From d4be68e361f4258cf0848fc70018dfe37a2acc24 Mon Sep 17 00:00:00 2001 From: shadchin Date: Mon, 18 Apr 2022 12:39:32 +0300 Subject: IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4 ref:9f96be6d02ee8044fdd6f124b799b270c20ce641 --- contrib/tools/python3/src/Include/Python-ast.h | 697 - contrib/tools/python3/src/Include/Python.h | 22 +- contrib/tools/python3/src/Include/abstract.h | 25 +- contrib/tools/python3/src/Include/asdl.h | 46 - contrib/tools/python3/src/Include/ast.h | 35 - contrib/tools/python3/src/Include/bitset.h | 23 - contrib/tools/python3/src/Include/boolobject.h | 15 +- contrib/tools/python3/src/Include/bytesobject.h | 35 +- contrib/tools/python3/src/Include/cellobject.h | 2 +- contrib/tools/python3/src/Include/ceval.h | 8 - contrib/tools/python3/src/Include/codecs.h | 8 + contrib/tools/python3/src/Include/compile.h | 109 +- .../tools/python3/src/Include/cpython/abstract.h | 23 +- .../python3/src/Include/cpython/bytesobject.h | 2 +- contrib/tools/python3/src/Include/cpython/ceval.h | 8 - contrib/tools/python3/src/Include/cpython/code.h | 33 +- .../tools/python3/src/Include/cpython/compile.h | 54 + .../tools/python3/src/Include/cpython/dictobject.h | 14 +- .../tools/python3/src/Include/cpython/fileobject.h | 8 +- .../tools/python3/src/Include/cpython/fileutils.h | 17 +- .../python3/src/Include/cpython/frameobject.h | 50 +- contrib/tools/python3/src/Include/cpython/import.h | 11 +- .../tools/python3/src/Include/cpython/initconfig.h | 287 +- .../src/Include/cpython/interpreteridobject.h | 8 - .../tools/python3/src/Include/cpython/listobject.h | 13 +- contrib/tools/python3/src/Include/cpython/object.h | 34 +- .../tools/python3/src/Include/cpython/objimpl.h | 51 +- .../python3/src/Include/cpython/odictobject.h | 43 + .../python3/src/Include/cpython/picklebufobject.h | 31 + .../tools/python3/src/Include/cpython/pyctype.h | 39 + .../tools/python3/src/Include/cpython/pydebug.h | 38 + .../tools/python3/src/Include/cpython/pyerrors.h | 38 +- contrib/tools/python3/src/Include/cpython/pyfpe.h | 15 + .../python3/src/Include/cpython/pylifecycle.h | 16 +- contrib/tools/python3/src/Include/cpython/pymem.h | 10 - .../tools/python3/src/Include/cpython/pystate.h | 72 +- .../tools/python3/src/Include/cpython/pythonrun.h | 121 + contrib/tools/python3/src/Include/cpython/pytime.h | 249 + .../tools/python3/src/Include/cpython/sysmodule.h | 8 - .../tools/python3/src/Include/cpython/traceback.h | 8 - .../python3/src/Include/cpython/tupleobject.h | 10 +- .../python3/src/Include/cpython/unicodeobject.h | 86 +- contrib/tools/python3/src/Include/datetime.h | 8 + contrib/tools/python3/src/Include/descrobject.h | 2 +- contrib/tools/python3/src/Include/dictobject.h | 3 + contrib/tools/python3/src/Include/errcode.h | 1 + contrib/tools/python3/src/Include/eval.h | 10 - contrib/tools/python3/src/Include/fileutils.h | 4 - contrib/tools/python3/src/Include/funcobject.h | 26 +- contrib/tools/python3/src/Include/genobject.h | 4 +- contrib/tools/python3/src/Include/graminit.h | 94 - contrib/tools/python3/src/Include/grammar.h | 77 - .../python3/src/Include/internal/pegen_interface.h | 46 - .../python3/src/Include/internal/pycore_asdl.h | 112 + .../python3/src/Include/internal/pycore_ast.h | 855 + .../src/Include/internal/pycore_ast_state.h | 255 + .../python3/src/Include/internal/pycore_atomic.h | 6 +- .../src/Include/internal/pycore_atomic_funcs.h | 94 + .../python3/src/Include/internal/pycore_bitutils.h | 176 + .../Include/internal/pycore_blocks_output_buffer.h | 317 + .../python3/src/Include/internal/pycore_byteswap.h | 88 - .../python3/src/Include/internal/pycore_ceval.h | 36 +- .../python3/src/Include/internal/pycore_code.h | 7 + .../python3/src/Include/internal/pycore_compile.h | 44 + .../python3/src/Include/internal/pycore_context.h | 2 +- .../src/Include/internal/pycore_fileutils.h | 5 + .../python3/src/Include/internal/pycore_format.h | 27 + .../tools/python3/src/Include/internal/pycore_gc.h | 18 +- .../python3/src/Include/internal/pycore_import.h | 9 +- .../src/Include/internal/pycore_initconfig.h | 11 +- .../python3/src/Include/internal/pycore_interp.h | 215 +- .../python3/src/Include/internal/pycore_list.h | 20 + .../python3/src/Include/internal/pycore_long.h | 40 + .../src/Include/internal/pycore_moduleobject.h | 42 + .../python3/src/Include/internal/pycore_object.h | 113 +- .../python3/src/Include/internal/pycore_parser.h | 31 + .../src/Include/internal/pycore_pathconfig.h | 1 + .../python3/src/Include/internal/pycore_pyarena.h | 64 + .../python3/src/Include/internal/pycore_pyerrors.h | 6 + .../src/Include/internal/pycore_pylifecycle.h | 83 +- .../python3/src/Include/internal/pycore_pymem.h | 3 - .../python3/src/Include/internal/pycore_pystate.h | 23 +- .../python3/src/Include/internal/pycore_runtime.h | 15 +- .../src/Include/internal/pycore_structseq.h | 21 + .../python3/src/Include/internal/pycore_symtable.h | 133 + .../src/Include/internal/pycore_traceback.h | 12 +- .../python3/src/Include/internal/pycore_tuple.h | 20 + .../src/Include/internal/pycore_tupleobject.h | 19 - .../python3/src/Include/internal/pycore_ucnhash.h | 34 + .../src/Include/internal/pycore_unionobject.h | 22 + .../python3/src/Include/internal/pycore_warnings.h | 2 +- contrib/tools/python3/src/Include/intrcheck.h | 3 - contrib/tools/python3/src/Include/iterobject.h | 3 + contrib/tools/python3/src/Include/longobject.h | 22 - contrib/tools/python3/src/Include/methodobject.h | 14 +- contrib/tools/python3/src/Include/modsupport.h | 10 +- contrib/tools/python3/src/Include/moduleobject.h | 6 + contrib/tools/python3/src/Include/node.h | 47 - contrib/tools/python3/src/Include/object.h | 161 +- contrib/tools/python3/src/Include/objimpl.h | 42 +- contrib/tools/python3/src/Include/odictobject.h | 43 - contrib/tools/python3/src/Include/opcode.h | 32 +- contrib/tools/python3/src/Include/parsetok.h | 110 - contrib/tools/python3/src/Include/patchlevel.h | 6 +- .../tools/python3/src/Include/picklebufobject.h | 31 - contrib/tools/python3/src/Include/pyarena.h | 64 - contrib/tools/python3/src/Include/pyconfig-linux.h | 83 +- .../tools/python3/src/Include/pyconfig-osx-arm64.h | 71 +- contrib/tools/python3/src/Include/pyconfig-osx.h | 75 +- contrib/tools/python3/src/Include/pyconfig.h | 6 +- contrib/tools/python3/src/Include/pyctype.h | 39 - contrib/tools/python3/src/Include/pydebug.h | 38 - contrib/tools/python3/src/Include/pyerrors.h | 10 +- contrib/tools/python3/src/Include/pyfpe.h | 15 - contrib/tools/python3/src/Include/pyhash.h | 5 +- contrib/tools/python3/src/Include/pylifecycle.h | 3 - contrib/tools/python3/src/Include/pymath.h | 8 - contrib/tools/python3/src/Include/pymem.h | 39 +- contrib/tools/python3/src/Include/pyport.h | 23 +- contrib/tools/python3/src/Include/pythonrun.h | 185 +- contrib/tools/python3/src/Include/pytime.h | 248 - contrib/tools/python3/src/Include/setobject.h | 9 +- contrib/tools/python3/src/Include/structmember.h | 1 + contrib/tools/python3/src/Include/symtable.h | 123 - contrib/tools/python3/src/Include/token.h | 5 +- contrib/tools/python3/src/Include/typeslots.h | 4 + contrib/tools/python3/src/Include/ucnhash.h | 36 - contrib/tools/python3/src/Include/unicodeobject.h | 22 +- contrib/tools/python3/src/LICENSE | 4 +- contrib/tools/python3/src/Lib/__future__.py | 4 +- contrib/tools/python3/src/Lib/_aix_support.py | 26 +- contrib/tools/python3/src/Lib/_bootlocale.py | 46 - contrib/tools/python3/src/Lib/_collections_abc.py | 150 +- contrib/tools/python3/src/Lib/_compression.py | 12 +- contrib/tools/python3/src/Lib/_markupbase.py | 35 +- contrib/tools/python3/src/Lib/_osx_support.py | 13 +- contrib/tools/python3/src/Lib/_pydecimal.py | 2 +- contrib/tools/python3/src/Lib/_pyio.py | 89 +- contrib/tools/python3/src/Lib/_sitebuiltins.py | 2 +- contrib/tools/python3/src/Lib/abc.py | 38 + contrib/tools/python3/src/Lib/argparse.py | 5 +- contrib/tools/python3/src/Lib/ast.py | 105 +- contrib/tools/python3/src/Lib/asynchat.py | 8 + contrib/tools/python3/src/Lib/asyncio/__init__.py | 4 - .../tools/python3/src/Lib/asyncio/base_events.py | 21 +- contrib/tools/python3/src/Lib/asyncio/events.py | 25 +- contrib/tools/python3/src/Lib/asyncio/futures.py | 6 +- contrib/tools/python3/src/Lib/asyncio/locks.py | 72 +- contrib/tools/python3/src/Lib/asyncio/mixins.py | 31 + .../python3/src/Lib/asyncio/proactor_events.py | 40 +- contrib/tools/python3/src/Lib/asyncio/queues.py | 21 +- contrib/tools/python3/src/Lib/asyncio/runners.py | 3 +- contrib/tools/python3/src/Lib/asyncio/streams.py | 51 +- .../tools/python3/src/Lib/asyncio/subprocess.py | 30 +- contrib/tools/python3/src/Lib/asyncio/tasks.py | 130 +- .../tools/python3/src/Lib/asyncio/unix_events.py | 34 +- contrib/tools/python3/src/Lib/asyncore.py | 23 +- contrib/tools/python3/src/Lib/base64.py | 86 +- contrib/tools/python3/src/Lib/bdb.py | 29 +- contrib/tools/python3/src/Lib/bisect.py | 70 +- contrib/tools/python3/src/Lib/bz2.py | 116 +- contrib/tools/python3/src/Lib/calendar.py | 25 +- contrib/tools/python3/src/Lib/cgi.py | 7 +- contrib/tools/python3/src/Lib/cgitb.py | 4 +- contrib/tools/python3/src/Lib/codecs.py | 2 +- contrib/tools/python3/src/Lib/codeop.py | 73 +- .../tools/python3/src/Lib/collections/__init__.py | 100 +- contrib/tools/python3/src/Lib/colorsys.py | 15 +- contrib/tools/python3/src/Lib/compileall.py | 13 +- .../python3/src/Lib/concurrent/futures/process.py | 8 + contrib/tools/python3/src/Lib/configparser.py | 11 +- contrib/tools/python3/src/Lib/contextlib.py | 64 +- contrib/tools/python3/src/Lib/copy.py | 1 + contrib/tools/python3/src/Lib/copyreg.py | 6 + contrib/tools/python3/src/Lib/csv.py | 12 +- contrib/tools/python3/src/Lib/dataclasses.py | 264 +- contrib/tools/python3/src/Lib/datetime.py | 51 +- contrib/tools/python3/src/Lib/dis.py | 45 +- .../tools/python3/src/Lib/distutils/__init__.py | 7 + .../python3/src/Lib/distutils/command/__init__.py | 1 - .../python3/src/Lib/distutils/command/bdist.py | 4 +- .../python3/src/Lib/distutils/command/bdist_msi.py | 2 - .../src/Lib/distutils/command/bdist_wininst.py | 377 - .../python3/src/Lib/distutils/command/install.py | 98 +- .../tools/python3/src/Lib/distutils/extension.py | 3 +- .../tools/python3/src/Lib/distutils/sysconfig.py | 636 +- contrib/tools/python3/src/Lib/distutils/util.py | 3 + contrib/tools/python3/src/Lib/doctest.py | 42 +- contrib/tools/python3/src/Lib/email/_parseaddr.py | 2 +- contrib/tools/python3/src/Lib/email/base64mime.py | 2 +- contrib/tools/python3/src/Lib/email/errors.py | 3 + .../tools/python3/src/Lib/email/headerregistry.py | 13 +- contrib/tools/python3/src/Lib/email/utils.py | 5 +- .../tools/python3/src/Lib/encodings/__init__.py | 3 +- .../tools/python3/src/Lib/ensurepip/__init__.py | 113 +- contrib/tools/python3/src/Lib/enum.py | 25 +- contrib/tools/python3/src/Lib/filecmp.py | 9 +- contrib/tools/python3/src/Lib/fileinput.py | 67 +- contrib/tools/python3/src/Lib/formatter.py | 452 - contrib/tools/python3/src/Lib/fractions.py | 125 +- contrib/tools/python3/src/Lib/functools.py | 30 +- contrib/tools/python3/src/Lib/glob.py | 151 +- contrib/tools/python3/src/Lib/gzip.py | 5 +- contrib/tools/python3/src/Lib/hashlib.py | 7 + contrib/tools/python3/src/Lib/hmac.py | 86 +- contrib/tools/python3/src/Lib/http/__init__.py | 1 + contrib/tools/python3/src/Lib/http/client.py | 84 +- contrib/tools/python3/src/Lib/http/cookiejar.py | 40 +- contrib/tools/python3/src/Lib/http/server.py | 5 +- contrib/tools/python3/src/Lib/imaplib.py | 13 +- contrib/tools/python3/src/Lib/imp.py | 3 +- .../tools/python3/src/Lib/importlib/__init__.py | 14 +- contrib/tools/python3/src/Lib/importlib/_abc.py | 54 + .../tools/python3/src/Lib/importlib/_adapters.py | 83 + .../tools/python3/src/Lib/importlib/_bootstrap.py | 80 +- .../src/Lib/importlib/_bootstrap_external.py | 184 +- contrib/tools/python3/src/Lib/importlib/_common.py | 85 +- contrib/tools/python3/src/Lib/importlib/abc.py | 136 +- .../tools/python3/src/Lib/importlib/machinery.py | 2 - .../tools/python3/src/Lib/importlib/metadata.py | 604 - .../python3/src/Lib/importlib/metadata/__init__.py | 1045 + .../src/Lib/importlib/metadata/_adapters.py | 68 + .../src/Lib/importlib/metadata/_collections.py | 30 + .../src/Lib/importlib/metadata/_functools.py | 85 + .../src/Lib/importlib/metadata/_itertools.py | 19 + .../python3/src/Lib/importlib/metadata/_meta.py | 47 + .../python3/src/Lib/importlib/metadata/_text.py | 99 + contrib/tools/python3/src/Lib/importlib/readers.py | 123 + .../tools/python3/src/Lib/importlib/resources.py | 220 +- contrib/tools/python3/src/Lib/importlib/util.py | 14 +- contrib/tools/python3/src/Lib/inspect.py | 161 +- contrib/tools/python3/src/Lib/io.py | 19 +- contrib/tools/python3/src/Lib/ipaddress.py | 11 +- contrib/tools/python3/src/Lib/keyword.py | 7 +- .../tools/python3/src/Lib/lib2to3/pgen2/pgen.py | 2 +- contrib/tools/python3/src/Lib/linecache.py | 11 +- contrib/tools/python3/src/Lib/locale.py | 98 +- contrib/tools/python3/src/Lib/logging/__init__.py | 75 +- contrib/tools/python3/src/Lib/logging/config.py | 5 +- contrib/tools/python3/src/Lib/logging/handlers.py | 11 +- contrib/tools/python3/src/Lib/lzma.py | 1 + contrib/tools/python3/src/Lib/mimetypes.py | 39 +- .../python3/src/Lib/multiprocessing/managers.py | 20 +- .../src/Lib/multiprocessing/resource_tracker.py | 10 +- .../tools/python3/src/Lib/multiprocessing/util.py | 2 +- contrib/tools/python3/src/Lib/netrc.py | 8 +- contrib/tools/python3/src/Lib/ntpath.py | 23 +- contrib/tools/python3/src/Lib/opcode.py | 25 +- contrib/tools/python3/src/Lib/os.py | 100 +- contrib/tools/python3/src/Lib/pathlib.py | 354 +- contrib/tools/python3/src/Lib/pickle.py | 1 + contrib/tools/python3/src/Lib/pipes.py | 4 +- contrib/tools/python3/src/Lib/pkgutil.py | 21 +- contrib/tools/python3/src/Lib/platform.py | 72 +- contrib/tools/python3/src/Lib/posixpath.py | 29 +- contrib/tools/python3/src/Lib/pprint.py | 224 +- contrib/tools/python3/src/Lib/pty.py | 47 +- contrib/tools/python3/src/Lib/py_compile.py | 71 +- contrib/tools/python3/src/Lib/pyclbr.py | 320 +- contrib/tools/python3/src/Lib/pydoc.py | 20 +- contrib/tools/python3/src/Lib/pydoc_data/topics.py | 1625 +- contrib/tools/python3/src/Lib/random.py | 85 +- contrib/tools/python3/src/Lib/re.py | 1 - contrib/tools/python3/src/Lib/rlcompleter.py | 9 +- contrib/tools/python3/src/Lib/runpy.py | 3 +- contrib/tools/python3/src/Lib/sched.py | 20 +- contrib/tools/python3/src/Lib/shelve.py | 4 +- contrib/tools/python3/src/Lib/shutil.py | 26 +- contrib/tools/python3/src/Lib/site.py | 53 +- contrib/tools/python3/src/Lib/smtpd.py | 18 +- contrib/tools/python3/src/Lib/smtplib.py | 8 +- contrib/tools/python3/src/Lib/socket.py | 7 +- contrib/tools/python3/src/Lib/sqlite3/__init__.py | 14 + contrib/tools/python3/src/Lib/sqlite3/dbapi2.py | 14 + contrib/tools/python3/src/Lib/ssl.py | 81 +- contrib/tools/python3/src/Lib/statistics.py | 267 +- contrib/tools/python3/src/Lib/subprocess.py | 53 +- contrib/tools/python3/src/Lib/symbol.py | 122 - contrib/tools/python3/src/Lib/symtable.py | 74 +- contrib/tools/python3/src/Lib/sysconfig.py | 274 +- contrib/tools/python3/src/Lib/tarfile.py | 74 +- contrib/tools/python3/src/Lib/tempfile.py | 60 +- contrib/tools/python3/src/Lib/textwrap.py | 12 +- contrib/tools/python3/src/Lib/threading.py | 112 +- contrib/tools/python3/src/Lib/timeit.py | 1 + contrib/tools/python3/src/Lib/token.py | 11 +- contrib/tools/python3/src/Lib/tokenize.py | 2 + contrib/tools/python3/src/Lib/trace.py | 2 +- contrib/tools/python3/src/Lib/traceback.py | 223 +- contrib/tools/python3/src/Lib/turtle.py | 18 +- contrib/tools/python3/src/Lib/types.py | 12 +- contrib/tools/python3/src/Lib/typing.py | 564 +- contrib/tools/python3/src/Lib/unittest/_log.py | 29 +- .../tools/python3/src/Lib/unittest/async_case.py | 2 +- contrib/tools/python3/src/Lib/unittest/case.py | 15 +- contrib/tools/python3/src/Lib/unittest/mock.py | 84 +- contrib/tools/python3/src/Lib/unittest/result.py | 3 +- contrib/tools/python3/src/Lib/urllib/parse.py | 3 +- contrib/tools/python3/src/Lib/urllib/request.py | 2 + .../src/Lib/venv/scripts/common/Activate.ps1 | 6 + .../python3/src/Lib/venv/scripts/common/activate | 3 + .../python3/src/Lib/venv/scripts/nt/activate.bat | 1 + .../python3/src/Lib/venv/scripts/nt/deactivate.bat | 1 + .../src/Lib/venv/scripts/posix/activate.csh | 3 +- .../src/Lib/venv/scripts/posix/activate.fish | 2 + contrib/tools/python3/src/Lib/webbrowser.py | 6 +- .../tools/python3/src/Lib/xml/etree/ElementPath.py | 31 +- .../tools/python3/src/Lib/xml/etree/ElementTree.py | 2 - contrib/tools/python3/src/Lib/xml/sax/handler.py | 45 + contrib/tools/python3/src/Lib/zipfile.py | 69 +- contrib/tools/python3/src/Lib/zipimport.py | 170 +- contrib/tools/python3/src/Lib/zoneinfo/_common.py | 3 +- contrib/tools/python3/src/Modules/_abc.c | 84 +- contrib/tools/python3/src/Modules/_asynciomodule.c | 215 +- contrib/tools/python3/src/Modules/_bisectmodule.c | 102 +- .../python3/src/Modules/_blake2/blake2b_impl.c | 59 +- .../python3/src/Modules/_blake2/blake2module.c | 121 +- .../python3/src/Modules/_blake2/blake2s_impl.c | 60 +- .../src/Modules/_blake2/clinic/blake2b_impl.c.h | 27 +- .../src/Modules/_blake2/clinic/blake2s_impl.c.h | 27 +- contrib/tools/python3/src/Modules/_bz2module.c | 461 +- contrib/tools/python3/src/Modules/_codecsmodule.c | 42 +- .../tools/python3/src/Modules/_collectionsmodule.c | 104 +- .../tools/python3/src/Modules/_contextvarsmodule.c | 21 +- contrib/tools/python3/src/Modules/_csv.c | 566 +- .../tools/python3/src/Modules/_ctypes/_ctypes.c | 387 +- .../tools/python3/src/Modules/_ctypes/callbacks.c | 5 +- .../tools/python3/src/Modules/_ctypes/callproc.c | 19 +- contrib/tools/python3/src/Modules/_ctypes/cfield.c | 58 +- contrib/tools/python3/src/Modules/_ctypes/ctypes.h | 4 - .../tools/python3/src/Modules/_ctypes/stgdict.c | 2 - .../tools/python3/src/Modules/_datetimemodule.c | 329 +- .../tools/python3/src/Modules/_decimal/_decimal.c | 58 +- .../python3/src/Modules/_decimal/libmpdec/bench.c | 137 + .../src/Modules/_decimal/libmpdec/bench_full.c | 193 + .../src/Modules/_decimal/libmpdec/constants.c | 5 +- .../src/Modules/_decimal/libmpdec/context.c | 6 +- .../python3/src/Modules/_decimal/libmpdec/crt.c | 18 +- .../python3/src/Modules/_decimal/libmpdec/crt.h | 2 +- .../Modules/_decimal/libmpdec/examples/compare.c | 77 + .../src/Modules/_decimal/libmpdec/examples/div.c | 77 + .../Modules/_decimal/libmpdec/examples/divmod.c | 82 + .../Modules/_decimal/libmpdec/examples/multiply.c | 77 + .../src/Modules/_decimal/libmpdec/examples/pow.c | 77 + .../Modules/_decimal/libmpdec/examples/powmod.c | 80 + .../src/Modules/_decimal/libmpdec/examples/shift.c | 77 + .../src/Modules/_decimal/libmpdec/examples/sqrt.c | 74 + .../python3/src/Modules/_decimal/libmpdec/io.c | 28 +- .../src/Modules/_decimal/libmpdec/mpalloc.c | 7 - .../src/Modules/_decimal/libmpdec/mpalloc.h | 10 +- .../src/Modules/_decimal/libmpdec/mpdecimal.c | 359 +- .../src/Modules/_decimal/libmpdec/mpdecimal.h | 84 +- .../src/Modules/_decimal/libmpdec/mpsignal.c | 967 + .../src/Modules/_decimal/libmpdec/typearith.h | 6 +- .../src/Modules/_decimal/libmpdec/vccompat.h | 56 - contrib/tools/python3/src/Modules/_elementtree.c | 2 +- .../tools/python3/src/Modules/_functoolsmodule.c | 558 +- contrib/tools/python3/src/Modules/_hashopenssl.c | 317 +- contrib/tools/python3/src/Modules/_heapqmodule.c | 67 +- contrib/tools/python3/src/Modules/_io/_iomodule.c | 74 +- contrib/tools/python3/src/Modules/_io/_iomodule.h | 1 - contrib/tools/python3/src/Modules/_io/bufferedio.c | 9 + .../python3/src/Modules/_io/clinic/_iomodule.c.h | 58 +- .../python3/src/Modules/_io/clinic/bufferedio.c.h | 49 +- .../python3/src/Modules/_io/clinic/bytesio.c.h | 14 +- .../python3/src/Modules/_io/clinic/fileio.c.h | 12 +- .../python3/src/Modules/_io/clinic/iobase.c.h | 9 +- .../python3/src/Modules/_io/clinic/stringio.c.h | 14 +- .../python3/src/Modules/_io/clinic/textio.c.h | 34 +- .../src/Modules/_io/clinic/winconsoleio.c.h | 18 +- contrib/tools/python3/src/Modules/_io/fileio.c | 19 +- contrib/tools/python3/src/Modules/_io/iobase.c | 6 +- contrib/tools/python3/src/Modules/_io/textio.c | 56 +- .../tools/python3/src/Modules/_io/winconsoleio.c | 139 +- contrib/tools/python3/src/Modules/_json.c | 77 +- contrib/tools/python3/src/Modules/_localemodule.c | 315 +- contrib/tools/python3/src/Modules/_lsprof.c | 290 +- contrib/tools/python3/src/Modules/_lzmamodule.c | 773 +- .../_multiprocessing/clinic/multiprocessing.c.h | 151 + .../Modules/_multiprocessing/clinic/posixshmem.c.h | 12 +- .../Modules/_multiprocessing/clinic/semaphore.c.h | 402 + .../src/Modules/_multiprocessing/multiprocessing.c | 193 +- .../src/Modules/_multiprocessing/multiprocessing.h | 2 +- .../src/Modules/_multiprocessing/posixshmem.c | 22 +- .../src/Modules/_multiprocessing/semaphore.c | 246 +- contrib/tools/python3/src/Modules/_opcode.c | 21 +- contrib/tools/python3/src/Modules/_operator.c | 342 +- contrib/tools/python3/src/Modules/_peg_parser.c | 153 - contrib/tools/python3/src/Modules/_pickle.c | 159 +- .../tools/python3/src/Modules/_posixsubprocess.c | 408 +- contrib/tools/python3/src/Modules/_queuemodule.c | 224 +- contrib/tools/python3/src/Modules/_randommodule.c | 111 +- contrib/tools/python3/src/Modules/_scproxy.c | 22 +- .../tools/python3/src/Modules/_sha3/sha3module.c | 335 +- contrib/tools/python3/src/Modules/_sqlite/cache.c | 231 +- contrib/tools/python3/src/Modules/_sqlite/cache.h | 14 +- .../src/Modules/_sqlite/clinic/connection.c.h | 709 + .../python3/src/Modules/_sqlite/clinic/cursor.c.h | 262 + .../python3/src/Modules/_sqlite/clinic/module.c.h | 225 + .../python3/src/Modules/_sqlite/clinic/row.c.h | 56 + .../tools/python3/src/Modules/_sqlite/connection.c | 959 +- .../tools/python3/src/Modules/_sqlite/connection.h | 14 +- contrib/tools/python3/src/Modules/_sqlite/cursor.c | 479 +- contrib/tools/python3/src/Modules/_sqlite/cursor.h | 14 +- .../python3/src/Modules/_sqlite/microprotocols.c | 25 +- .../python3/src/Modules/_sqlite/microprotocols.h | 7 +- contrib/tools/python3/src/Modules/_sqlite/module.c | 461 +- contrib/tools/python3/src/Modules/_sqlite/module.h | 1 + .../python3/src/Modules/_sqlite/prepare_protocol.c | 85 +- .../python3/src/Modules/_sqlite/prepare_protocol.h | 10 +- contrib/tools/python3/src/Modules/_sqlite/row.c | 196 +- contrib/tools/python3/src/Modules/_sqlite/row.h | 4 +- .../tools/python3/src/Modules/_sqlite/statement.c | 170 +- .../tools/python3/src/Modules/_sqlite/statement.h | 10 +- contrib/tools/python3/src/Modules/_sqlite/util.c | 12 +- contrib/tools/python3/src/Modules/_sqlite/util.h | 6 - contrib/tools/python3/src/Modules/_sre.c | 576 +- contrib/tools/python3/src/Modules/_ssl.c | 1853 +- contrib/tools/python3/src/Modules/_ssl.h | 74 + contrib/tools/python3/src/Modules/_ssl/cert.c | 245 + .../tools/python3/src/Modules/_ssl/clinic/cert.c.h | 60 + .../tools/python3/src/Modules/_ssl/debughelpers.c | 10 +- contrib/tools/python3/src/Modules/_ssl/misc.c | 34 + contrib/tools/python3/src/Modules/_struct.c | 512 +- contrib/tools/python3/src/Modules/_threadmodule.c | 782 +- contrib/tools/python3/src/Modules/_winapi.c | 322 +- .../python3/src/Modules/_xxsubinterpretersmodule.c | 37 +- .../tools/python3/src/Modules/_xxtestfuzz/fuzzer.c | 14 +- contrib/tools/python3/src/Modules/_zoneinfo.c | 29 +- contrib/tools/python3/src/Modules/arraymodule.c | 430 +- contrib/tools/python3/src/Modules/atexitmodule.c | 317 +- .../python3/src/Modules/cjkcodecs/cjkcodecs.h | 69 +- .../Modules/cjkcodecs/clinic/multibytecodec.c.h | 12 +- .../python3/src/Modules/cjkcodecs/multibytecodec.c | 498 +- .../python3/src/Modules/cjkcodecs/multibytecodec.h | 2 +- .../python3/src/Modules/clinic/_asynciomodule.c.h | 41 +- .../python3/src/Modules/clinic/_bisectmodule.c.h | 138 +- .../python3/src/Modules/clinic/_bz2module.c.h | 85 +- .../python3/src/Modules/clinic/_codecsmodule.c.h | 155 +- .../src/Modules/clinic/_collectionsmodule.c.h | 9 +- .../python3/src/Modules/clinic/_curses_panel.c.h | 168 +- .../python3/src/Modules/clinic/_cursesmodule.c.h | 531 +- .../python3/src/Modules/clinic/_datetimemodule.c.h | 17 +- .../python3/src/Modules/clinic/_dbmmodule.c.h | 50 +- .../python3/src/Modules/clinic/_elementtree.c.h | 9 +- .../python3/src/Modules/clinic/_gdbmmodule.c.h | 108 +- .../python3/src/Modules/clinic/_hashopenssl.c.h | 79 +- .../python3/src/Modules/clinic/_heapqmodule.c.h | 98 +- .../python3/src/Modules/clinic/_localemodule.c.h | 605 + .../tools/python3/src/Modules/clinic/_lsprof.c.h | 55 + .../python3/src/Modules/clinic/_lzmamodule.c.h | 52 +- .../tools/python3/src/Modules/clinic/_opcode.c.h | 7 +- .../tools/python3/src/Modules/clinic/_operator.c.h | 9 +- .../python3/src/Modules/clinic/_queuemodule.c.h | 58 +- .../python3/src/Modules/clinic/_randommodule.c.h | 7 +- contrib/tools/python3/src/Modules/clinic/_sre.c.h | 491 +- contrib/tools/python3/src/Modules/clinic/_ssl.c.h | 224 +- .../tools/python3/src/Modules/clinic/_struct.c.h | 24 +- .../tools/python3/src/Modules/clinic/_tkinter.c.h | 47 +- .../python3/src/Modules/clinic/_tracemalloc.c.h | 7 +- .../tools/python3/src/Modules/clinic/_winapi.c.h | 113 +- .../python3/src/Modules/clinic/arraymodule.c.h | 94 +- .../tools/python3/src/Modules/clinic/audioop.c.h | 166 +- .../tools/python3/src/Modules/clinic/binascii.c.h | 52 +- .../python3/src/Modules/clinic/fcntlmodule.c.h | 35 +- .../tools/python3/src/Modules/clinic/gcmodule.c.h | 12 +- .../python3/src/Modules/clinic/itertoolsmodule.c.h | 54 +- .../tools/python3/src/Modules/clinic/md5module.c.h | 21 +- .../python3/src/Modules/clinic/overlapped.c.h | 908 + .../python3/src/Modules/clinic/posixmodule.c.h | 908 +- .../tools/python3/src/Modules/clinic/pyexpat.c.h | 134 +- .../tools/python3/src/Modules/clinic/readline.c.h | 688 + .../tools/python3/src/Modules/clinic/resource.c.h | 17 +- .../python3/src/Modules/clinic/selectmodule.c.h | 64 +- .../python3/src/Modules/clinic/sha1module.c.h | 21 +- .../python3/src/Modules/clinic/sha256module.c.h | 21 +- .../python3/src/Modules/clinic/sha512module.c.h | 21 +- .../python3/src/Modules/clinic/signalmodule.c.h | 108 +- .../tools/python3/src/Modules/clinic/termios.c.h | 225 + .../python3/src/Modules/clinic/zlibmodule.c.h | 286 +- contrib/tools/python3/src/Modules/cmathmodule.c | 78 +- contrib/tools/python3/src/Modules/config.c | 16 +- contrib/tools/python3/src/Modules/faulthandler.c | 97 +- contrib/tools/python3/src/Modules/fcntlmodule.c | 77 +- contrib/tools/python3/src/Modules/gcmodule.c | 288 +- contrib/tools/python3/src/Modules/getpath.c | 5 - contrib/tools/python3/src/Modules/grpmodule.c | 91 +- .../tools/python3/src/Modules/itertoolsmodule.c | 150 +- contrib/tools/python3/src/Modules/main.c | 145 +- contrib/tools/python3/src/Modules/mathmodule.c | 280 +- contrib/tools/python3/src/Modules/md5module.c | 173 +- contrib/tools/python3/src/Modules/mmapmodule.c | 322 +- contrib/tools/python3/src/Modules/overlapped.c | 1106 +- contrib/tools/python3/src/Modules/parsermodule.c | 1222 - contrib/tools/python3/src/Modules/posixmodule.c | 474 +- contrib/tools/python3/src/Modules/pwdmodule.c | 65 +- contrib/tools/python3/src/Modules/pyexpat.c | 765 +- contrib/tools/python3/src/Modules/resource.c | 67 +- contrib/tools/python3/src/Modules/selectmodule.c | 270 +- contrib/tools/python3/src/Modules/sha1module.c | 169 +- contrib/tools/python3/src/Modules/sha256module.c | 268 +- contrib/tools/python3/src/Modules/sha512module.c | 254 +- contrib/tools/python3/src/Modules/signalmodule.c | 764 +- contrib/tools/python3/src/Modules/socketmodule.c | 207 +- contrib/tools/python3/src/Modules/socketmodule.h | 3 +- contrib/tools/python3/src/Modules/spwdmodule.c | 84 +- contrib/tools/python3/src/Modules/sre_lib.h | 33 +- contrib/tools/python3/src/Modules/symtablemodule.c | 102 +- contrib/tools/python3/src/Modules/termios.c | 344 +- contrib/tools/python3/src/Modules/timemodule.c | 79 +- contrib/tools/python3/src/Modules/unicodedata.c | 312 +- contrib/tools/python3/src/Modules/zlibmodule.c | 813 +- contrib/tools/python3/src/Objects/abstract.c | 735 +- contrib/tools/python3/src/Objects/boolobject.c | 25 + .../tools/python3/src/Objects/bytearrayobject.c | 95 +- contrib/tools/python3/src/Objects/bytes_methods.c | 21 +- contrib/tools/python3/src/Objects/bytesobject.c | 379 +- contrib/tools/python3/src/Objects/call.c | 144 +- contrib/tools/python3/src/Objects/capsule.c | 6 +- .../python3/src/Objects/clinic/bytearrayobject.c.h | 123 +- .../python3/src/Objects/clinic/bytesobject.c.h | 104 +- .../python3/src/Objects/clinic/codeobject.c.h | 187 +- .../python3/src/Objects/clinic/complexobject.c.h | 71 +- .../python3/src/Objects/clinic/dictobject.c.h | 5 +- .../python3/src/Objects/clinic/floatobject.c.h | 4 +- .../python3/src/Objects/clinic/listobject.c.h | 21 +- .../python3/src/Objects/clinic/longobject.c.h | 68 +- .../python3/src/Objects/clinic/memoryobject.c.h | 199 +- .../python3/src/Objects/clinic/odictobject.c.h | 45 +- .../python3/src/Objects/clinic/typeobject.c.h | 7 +- .../python3/src/Objects/clinic/unicodeobject.c.h | 130 +- contrib/tools/python3/src/Objects/codeobject.c | 485 +- contrib/tools/python3/src/Objects/complexobject.c | 135 +- contrib/tools/python3/src/Objects/descrobject.c | 82 +- contrib/tools/python3/src/Objects/dictobject.c | 587 +- contrib/tools/python3/src/Objects/enumobject.c | 22 +- contrib/tools/python3/src/Objects/exceptions.c | 463 +- contrib/tools/python3/src/Objects/fileobject.c | 42 +- contrib/tools/python3/src/Objects/floatobject.c | 153 +- contrib/tools/python3/src/Objects/frameobject.c | 435 +- contrib/tools/python3/src/Objects/funcobject.c | 249 +- .../tools/python3/src/Objects/genericaliasobject.c | 61 +- contrib/tools/python3/src/Objects/genobject.c | 393 +- .../python3/src/Objects/interpreteridobject.c | 12 +- contrib/tools/python3/src/Objects/iterobject.c | 215 +- contrib/tools/python3/src/Objects/listobject.c | 125 +- contrib/tools/python3/src/Objects/longobject.c | 365 +- contrib/tools/python3/src/Objects/memoryobject.c | 270 +- contrib/tools/python3/src/Objects/moduleobject.c | 153 +- contrib/tools/python3/src/Objects/object.c | 354 +- contrib/tools/python3/src/Objects/obmalloc.c | 365 +- contrib/tools/python3/src/Objects/odictobject.c | 49 +- contrib/tools/python3/src/Objects/rangeobject.c | 91 +- contrib/tools/python3/src/Objects/setobject.c | 68 +- contrib/tools/python3/src/Objects/sliceobject.c | 57 +- .../tools/python3/src/Objects/stringlib/asciilib.h | 1 - .../src/Objects/stringlib/clinic/transmogrify.h.h | 35 +- .../tools/python3/src/Objects/stringlib/codecs.h | 39 +- .../python3/src/Objects/stringlib/fastsearch.h | 490 +- .../python3/src/Objects/stringlib/find_max_char.h | 22 +- contrib/tools/python3/src/Objects/stringlib/join.h | 2 +- .../python3/src/Objects/stringlib/partition.h | 27 +- .../python3/src/Objects/stringlib/stringdefs.h | 1 - .../tools/python3/src/Objects/stringlib/ucs1lib.h | 1 - .../tools/python3/src/Objects/stringlib/ucs2lib.h | 1 - .../tools/python3/src/Objects/stringlib/ucs4lib.h | 1 - .../python3/src/Objects/stringlib/unicode_format.h | 4 +- .../python3/src/Objects/stringlib/unicodedefs.h | 1 - contrib/tools/python3/src/Objects/structseq.c | 163 +- contrib/tools/python3/src/Objects/tupleobject.c | 210 +- contrib/tools/python3/src/Objects/typeobject.c | 2514 +- contrib/tools/python3/src/Objects/typeslots.inc | 161 +- contrib/tools/python3/src/Objects/unicodeobject.c | 1127 +- contrib/tools/python3/src/Objects/unionobject.c | 496 + contrib/tools/python3/src/PC/clinic/_msi.c.h | 716 + .../tools/python3/src/PC/clinic/msvcrtmodule.c.h | 70 +- contrib/tools/python3/src/PC/clinic/winreg.c.h | 315 +- contrib/tools/python3/src/PC/clinic/winsound.c.h | 22 +- contrib/tools/python3/src/PC/msvcrtmodule.c | 40 +- contrib/tools/python3/src/PC/pyconfig.h | 13 +- contrib/tools/python3/src/PC/winreg.c | 79 +- contrib/tools/python3/src/Parser/acceler.c | 123 - contrib/tools/python3/src/Parser/grammar1.c | 47 - contrib/tools/python3/src/Parser/listnode.c | 71 - contrib/tools/python3/src/Parser/myreadline.c | 6 +- contrib/tools/python3/src/Parser/node.c | 189 - contrib/tools/python3/src/Parser/parser.c | 34801 ++++++++++++++++++- contrib/tools/python3/src/Parser/parser.h | 49 - contrib/tools/python3/src/Parser/parsetok.c | 486 - contrib/tools/python3/src/Parser/peg_api.c | 28 + contrib/tools/python3/src/Parser/pegen.c | 2630 ++ contrib/tools/python3/src/Parser/pegen.h | 336 + contrib/tools/python3/src/Parser/pegen/parse.c | 25594 -------------- .../tools/python3/src/Parser/pegen/parse_string.c | 1241 - .../tools/python3/src/Parser/pegen/parse_string.h | 46 - contrib/tools/python3/src/Parser/pegen/peg_api.c | 54 - contrib/tools/python3/src/Parser/pegen/pegen.c | 2280 -- contrib/tools/python3/src/Parser/pegen/pegen.h | 307 - contrib/tools/python3/src/Parser/string_parser.c | 1242 + contrib/tools/python3/src/Parser/string_parser.h | 46 + contrib/tools/python3/src/Parser/token.c | 1 + contrib/tools/python3/src/Parser/tokenizer.c | 1067 +- contrib/tools/python3/src/Parser/tokenizer.h | 21 +- contrib/tools/python3/src/Python/Python-ast.c | 3347 +- contrib/tools/python3/src/Python/_warnings.c | 125 +- contrib/tools/python3/src/Python/asdl.c | 66 +- contrib/tools/python3/src/Python/ast.c | 6019 +--- contrib/tools/python3/src/Python/ast_opt.c | 275 +- contrib/tools/python3/src/Python/ast_unparse.c | 27 +- contrib/tools/python3/src/Python/bltinmodule.c | 300 +- contrib/tools/python3/src/Python/bootstrap_hash.c | 5 + contrib/tools/python3/src/Python/ceval.c | 1876 +- contrib/tools/python3/src/Python/ceval_gil.h | 20 +- .../tools/python3/src/Python/clinic/_warnings.c.h | 9 +- .../python3/src/Python/clinic/bltinmodule.c.h | 75 +- contrib/tools/python3/src/Python/clinic/import.c.h | 7 +- .../tools/python3/src/Python/clinic/marshal.c.h | 12 +- .../tools/python3/src/Python/clinic/sysmodule.c.h | 65 +- .../tools/python3/src/Python/clinic/traceback.c.h | 12 +- contrib/tools/python3/src/Python/codecs.c | 65 +- contrib/tools/python3/src/Python/compile.c | 3734 +- contrib/tools/python3/src/Python/condvar.h | 2 +- contrib/tools/python3/src/Python/context.c | 63 +- contrib/tools/python3/src/Python/dynload_win.c | 13 +- contrib/tools/python3/src/Python/errors.c | 118 +- contrib/tools/python3/src/Python/fileutils.c | 284 +- .../tools/python3/src/Python/formatter_unicode.c | 2 +- contrib/tools/python3/src/Python/frozen.c | 29 +- contrib/tools/python3/src/Python/frozen_hello.h | 12 + contrib/tools/python3/src/Python/future.c | 28 +- contrib/tools/python3/src/Python/getargs.c | 190 +- contrib/tools/python3/src/Python/getcompiler.c | 4 +- contrib/tools/python3/src/Python/graminit.c | 2688 -- contrib/tools/python3/src/Python/hamt.c | 25 +- contrib/tools/python3/src/Python/import.c | 653 +- contrib/tools/python3/src/Python/importdl.c | 5 +- contrib/tools/python3/src/Python/importlib.h | 3405 +- .../tools/python3/src/Python/importlib_external.h | 5231 ++- .../tools/python3/src/Python/importlib_zipimport.h | 2048 +- contrib/tools/python3/src/Python/initconfig.c | 632 +- contrib/tools/python3/src/Python/marshal.c | 64 +- contrib/tools/python3/src/Python/modsupport.c | 103 +- contrib/tools/python3/src/Python/mysnprintf.c | 42 +- contrib/tools/python3/src/Python/opcode_targets.h | 18 +- contrib/tools/python3/src/Python/pathconfig.c | 163 +- contrib/tools/python3/src/Python/peephole.c | 538 - contrib/tools/python3/src/Python/preconfig.c | 49 +- contrib/tools/python3/src/Python/pyarena.c | 9 +- contrib/tools/python3/src/Python/pyhash.c | 26 +- contrib/tools/python3/src/Python/pylifecycle.c | 1054 +- contrib/tools/python3/src/Python/pymath.c | 15 - contrib/tools/python3/src/Python/pystate.c | 272 +- contrib/tools/python3/src/Python/pystrtod.c | 4 +- contrib/tools/python3/src/Python/pythonrun.c | 669 +- contrib/tools/python3/src/Python/pytime.c | 250 +- .../tools/python3/src/Python/stdlib_module_names.h | 308 + contrib/tools/python3/src/Python/structmember.c | 13 +- contrib/tools/python3/src/Python/suggestions.c | 289 + contrib/tools/python3/src/Python/symtable.c | 497 +- contrib/tools/python3/src/Python/sysmodule.c | 587 +- contrib/tools/python3/src/Python/thread.c | 19 + contrib/tools/python3/src/Python/thread_pthread.h | 17 +- contrib/tools/python3/src/Python/traceback.c | 34 +- contrib/tools/python3/src/README.rst | 39 +- 664 files changed, 100016 insertions(+), 79166 deletions(-) delete mode 100644 contrib/tools/python3/src/Include/Python-ast.h delete mode 100644 contrib/tools/python3/src/Include/asdl.h delete mode 100644 contrib/tools/python3/src/Include/ast.h delete mode 100644 contrib/tools/python3/src/Include/bitset.h create mode 100644 contrib/tools/python3/src/Include/cpython/compile.h create mode 100644 contrib/tools/python3/src/Include/cpython/odictobject.h create mode 100644 contrib/tools/python3/src/Include/cpython/picklebufobject.h create mode 100644 contrib/tools/python3/src/Include/cpython/pyctype.h create mode 100644 contrib/tools/python3/src/Include/cpython/pydebug.h create mode 100644 contrib/tools/python3/src/Include/cpython/pyfpe.h create mode 100644 contrib/tools/python3/src/Include/cpython/pythonrun.h create mode 100644 contrib/tools/python3/src/Include/cpython/pytime.h delete mode 100644 contrib/tools/python3/src/Include/graminit.h delete mode 100644 contrib/tools/python3/src/Include/grammar.h delete mode 100644 contrib/tools/python3/src/Include/internal/pegen_interface.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_asdl.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_ast.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_ast_state.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_atomic_funcs.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_bitutils.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_blocks_output_buffer.h delete mode 100644 contrib/tools/python3/src/Include/internal/pycore_byteswap.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_compile.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_format.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_list.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_long.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_moduleobject.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_parser.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_pyarena.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_structseq.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_symtable.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_tuple.h delete mode 100644 contrib/tools/python3/src/Include/internal/pycore_tupleobject.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_ucnhash.h create mode 100644 contrib/tools/python3/src/Include/internal/pycore_unionobject.h delete mode 100644 contrib/tools/python3/src/Include/node.h delete mode 100644 contrib/tools/python3/src/Include/odictobject.h delete mode 100644 contrib/tools/python3/src/Include/parsetok.h delete mode 100644 contrib/tools/python3/src/Include/picklebufobject.h delete mode 100644 contrib/tools/python3/src/Include/pyarena.h delete mode 100644 contrib/tools/python3/src/Include/pyctype.h delete mode 100644 contrib/tools/python3/src/Include/pydebug.h delete mode 100644 contrib/tools/python3/src/Include/pyfpe.h delete mode 100644 contrib/tools/python3/src/Include/pytime.h delete mode 100644 contrib/tools/python3/src/Include/symtable.h delete mode 100644 contrib/tools/python3/src/Include/ucnhash.h delete mode 100644 contrib/tools/python3/src/Lib/_bootlocale.py create mode 100644 contrib/tools/python3/src/Lib/asyncio/mixins.py delete mode 100644 contrib/tools/python3/src/Lib/distutils/command/bdist_wininst.py delete mode 100644 contrib/tools/python3/src/Lib/formatter.py create mode 100644 contrib/tools/python3/src/Lib/importlib/_abc.py create mode 100644 contrib/tools/python3/src/Lib/importlib/_adapters.py delete mode 100644 contrib/tools/python3/src/Lib/importlib/metadata.py create mode 100644 contrib/tools/python3/src/Lib/importlib/metadata/__init__.py create mode 100644 contrib/tools/python3/src/Lib/importlib/metadata/_adapters.py create mode 100644 contrib/tools/python3/src/Lib/importlib/metadata/_collections.py create mode 100644 contrib/tools/python3/src/Lib/importlib/metadata/_functools.py create mode 100644 contrib/tools/python3/src/Lib/importlib/metadata/_itertools.py create mode 100644 contrib/tools/python3/src/Lib/importlib/metadata/_meta.py create mode 100644 contrib/tools/python3/src/Lib/importlib/metadata/_text.py create mode 100644 contrib/tools/python3/src/Lib/importlib/readers.py delete mode 100644 contrib/tools/python3/src/Lib/symbol.py create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/bench.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/bench_full.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/compare.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/div.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/divmod.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/multiply.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/pow.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/powmod.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/shift.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/sqrt.c create mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/mpsignal.c delete mode 100644 contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h create mode 100644 contrib/tools/python3/src/Modules/_multiprocessing/clinic/multiprocessing.c.h create mode 100644 contrib/tools/python3/src/Modules/_multiprocessing/clinic/semaphore.c.h delete mode 100644 contrib/tools/python3/src/Modules/_peg_parser.c create mode 100644 contrib/tools/python3/src/Modules/_sqlite/clinic/connection.c.h create mode 100644 contrib/tools/python3/src/Modules/_sqlite/clinic/cursor.c.h create mode 100644 contrib/tools/python3/src/Modules/_sqlite/clinic/module.c.h create mode 100644 contrib/tools/python3/src/Modules/_sqlite/clinic/row.c.h create mode 100644 contrib/tools/python3/src/Modules/_ssl.h create mode 100644 contrib/tools/python3/src/Modules/_ssl/cert.c create mode 100644 contrib/tools/python3/src/Modules/_ssl/clinic/cert.c.h create mode 100644 contrib/tools/python3/src/Modules/_ssl/misc.c create mode 100644 contrib/tools/python3/src/Modules/clinic/_localemodule.c.h create mode 100644 contrib/tools/python3/src/Modules/clinic/_lsprof.c.h create mode 100644 contrib/tools/python3/src/Modules/clinic/overlapped.c.h create mode 100644 contrib/tools/python3/src/Modules/clinic/readline.c.h create mode 100644 contrib/tools/python3/src/Modules/clinic/termios.c.h delete mode 100644 contrib/tools/python3/src/Modules/parsermodule.c create mode 100644 contrib/tools/python3/src/Objects/unionobject.c create mode 100644 contrib/tools/python3/src/PC/clinic/_msi.c.h delete mode 100644 contrib/tools/python3/src/Parser/acceler.c delete mode 100644 contrib/tools/python3/src/Parser/grammar1.c delete mode 100644 contrib/tools/python3/src/Parser/listnode.c delete mode 100644 contrib/tools/python3/src/Parser/node.c delete mode 100644 contrib/tools/python3/src/Parser/parser.h delete mode 100644 contrib/tools/python3/src/Parser/parsetok.c create mode 100644 contrib/tools/python3/src/Parser/peg_api.c create mode 100644 contrib/tools/python3/src/Parser/pegen.c create mode 100644 contrib/tools/python3/src/Parser/pegen.h delete mode 100644 contrib/tools/python3/src/Parser/pegen/parse.c delete mode 100644 contrib/tools/python3/src/Parser/pegen/parse_string.c delete mode 100644 contrib/tools/python3/src/Parser/pegen/parse_string.h delete mode 100644 contrib/tools/python3/src/Parser/pegen/peg_api.c delete mode 100644 contrib/tools/python3/src/Parser/pegen/pegen.c delete mode 100644 contrib/tools/python3/src/Parser/pegen/pegen.h create mode 100644 contrib/tools/python3/src/Parser/string_parser.c create mode 100644 contrib/tools/python3/src/Parser/string_parser.h create mode 100644 contrib/tools/python3/src/Python/frozen_hello.h delete mode 100644 contrib/tools/python3/src/Python/graminit.c delete mode 100644 contrib/tools/python3/src/Python/peephole.c create mode 100644 contrib/tools/python3/src/Python/stdlib_module_names.h create mode 100644 contrib/tools/python3/src/Python/suggestions.c (limited to 'contrib/tools/python3/src') diff --git a/contrib/tools/python3/src/Include/Python-ast.h b/contrib/tools/python3/src/Include/Python-ast.h deleted file mode 100644 index e7afa1e6579..00000000000 --- a/contrib/tools/python3/src/Include/Python-ast.h +++ /dev/null @@ -1,697 +0,0 @@ -/* File automatically generated by Parser/asdl_c.py. */ - -#ifndef Py_PYTHON_AST_H -#define Py_PYTHON_AST_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_LIMITED_API -#include "asdl.h" - -#undef Yield /* undefine macro conflicting with */ - -typedef struct _mod *mod_ty; - -typedef struct _stmt *stmt_ty; - -typedef struct _expr *expr_ty; - -typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty; - -typedef enum _boolop { And=1, Or=2 } boolop_ty; - -typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, - LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, - FloorDiv=13 } operator_ty; - -typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; - -typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, - In=9, NotIn=10 } cmpop_ty; - -typedef struct _comprehension *comprehension_ty; - -typedef struct _excepthandler *excepthandler_ty; - -typedef struct _arguments *arguments_ty; - -typedef struct _arg *arg_ty; - -typedef struct _keyword *keyword_ty; - -typedef struct _alias *alias_ty; - -typedef struct _withitem *withitem_ty; - -typedef struct _type_ignore *type_ignore_ty; - - -enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, - FunctionType_kind=4}; -struct _mod { - enum _mod_kind kind; - union { - struct { - asdl_seq *body; - asdl_seq *type_ignores; - } Module; - - struct { - asdl_seq *body; - } Interactive; - - struct { - expr_ty body; - } Expression; - - struct { - asdl_seq *argtypes; - expr_ty returns; - } FunctionType; - - } v; -}; - -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, Raise_kind=15, Try_kind=16, - Assert_kind=17, Import_kind=18, ImportFrom_kind=19, - Global_kind=20, Nonlocal_kind=21, Expr_kind=22, Pass_kind=23, - Break_kind=24, Continue_kind=25}; -struct _stmt { - enum _stmt_kind kind; - union { - struct { - identifier name; - arguments_ty args; - asdl_seq *body; - asdl_seq *decorator_list; - expr_ty returns; - string type_comment; - } FunctionDef; - - struct { - identifier name; - arguments_ty args; - asdl_seq *body; - asdl_seq *decorator_list; - expr_ty returns; - string type_comment; - } AsyncFunctionDef; - - struct { - identifier name; - asdl_seq *bases; - asdl_seq *keywords; - asdl_seq *body; - asdl_seq *decorator_list; - } ClassDef; - - struct { - expr_ty value; - } Return; - - struct { - asdl_seq *targets; - } Delete; - - struct { - asdl_seq *targets; - expr_ty value; - string type_comment; - } Assign; - - struct { - expr_ty target; - operator_ty op; - expr_ty value; - } AugAssign; - - struct { - expr_ty target; - expr_ty annotation; - expr_ty value; - int simple; - } AnnAssign; - - struct { - expr_ty target; - expr_ty iter; - asdl_seq *body; - asdl_seq *orelse; - string type_comment; - } For; - - struct { - expr_ty target; - expr_ty iter; - asdl_seq *body; - asdl_seq *orelse; - string type_comment; - } AsyncFor; - - struct { - expr_ty test; - asdl_seq *body; - asdl_seq *orelse; - } While; - - struct { - expr_ty test; - asdl_seq *body; - asdl_seq *orelse; - } If; - - struct { - asdl_seq *items; - asdl_seq *body; - string type_comment; - } With; - - struct { - asdl_seq *items; - asdl_seq *body; - string type_comment; - } AsyncWith; - - struct { - expr_ty exc; - expr_ty cause; - } Raise; - - struct { - asdl_seq *body; - asdl_seq *handlers; - asdl_seq *orelse; - asdl_seq *finalbody; - } Try; - - struct { - expr_ty test; - expr_ty msg; - } Assert; - - struct { - asdl_seq *names; - } Import; - - struct { - identifier module; - asdl_seq *names; - int level; - } ImportFrom; - - struct { - asdl_seq *names; - } Global; - - struct { - asdl_seq *names; - } Nonlocal; - - struct { - expr_ty value; - } Expr; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4, - Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8, - ListComp_kind=9, SetComp_kind=10, DictComp_kind=11, - GeneratorExp_kind=12, Await_kind=13, Yield_kind=14, - YieldFrom_kind=15, Compare_kind=16, Call_kind=17, - FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20, - Attribute_kind=21, Subscript_kind=22, Starred_kind=23, - Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27}; -struct _expr { - enum _expr_kind kind; - union { - struct { - boolop_ty op; - asdl_seq *values; - } BoolOp; - - struct { - expr_ty target; - expr_ty value; - } NamedExpr; - - struct { - expr_ty left; - operator_ty op; - expr_ty right; - } BinOp; - - struct { - unaryop_ty op; - expr_ty operand; - } UnaryOp; - - struct { - arguments_ty args; - expr_ty body; - } Lambda; - - struct { - expr_ty test; - expr_ty body; - expr_ty orelse; - } IfExp; - - struct { - asdl_seq *keys; - asdl_seq *values; - } Dict; - - struct { - asdl_seq *elts; - } Set; - - struct { - expr_ty elt; - asdl_seq *generators; - } ListComp; - - struct { - expr_ty elt; - asdl_seq *generators; - } SetComp; - - struct { - expr_ty key; - expr_ty value; - asdl_seq *generators; - } DictComp; - - struct { - expr_ty elt; - asdl_seq *generators; - } GeneratorExp; - - struct { - expr_ty value; - } Await; - - struct { - expr_ty value; - } Yield; - - struct { - expr_ty value; - } YieldFrom; - - struct { - expr_ty left; - asdl_int_seq *ops; - asdl_seq *comparators; - } Compare; - - struct { - expr_ty func; - asdl_seq *args; - asdl_seq *keywords; - } Call; - - struct { - expr_ty value; - int conversion; - expr_ty format_spec; - } FormattedValue; - - struct { - asdl_seq *values; - } JoinedStr; - - struct { - constant value; - string kind; - } Constant; - - struct { - expr_ty value; - identifier attr; - expr_context_ty ctx; - } Attribute; - - struct { - expr_ty value; - expr_ty slice; - expr_context_ty ctx; - } Subscript; - - struct { - expr_ty value; - expr_context_ty ctx; - } Starred; - - struct { - identifier id; - expr_context_ty ctx; - } Name; - - struct { - asdl_seq *elts; - expr_context_ty ctx; - } List; - - struct { - asdl_seq *elts; - expr_context_ty ctx; - } Tuple; - - struct { - expr_ty lower; - expr_ty upper; - expr_ty step; - } Slice; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _comprehension { - expr_ty target; - expr_ty iter; - asdl_seq *ifs; - int is_async; -}; - -enum _excepthandler_kind {ExceptHandler_kind=1}; -struct _excepthandler { - enum _excepthandler_kind kind; - union { - struct { - expr_ty type; - identifier name; - asdl_seq *body; - } ExceptHandler; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _arguments { - asdl_seq *posonlyargs; - asdl_seq *args; - arg_ty vararg; - asdl_seq *kwonlyargs; - asdl_seq *kw_defaults; - arg_ty kwarg; - asdl_seq *defaults; -}; - -struct _arg { - identifier arg; - expr_ty annotation; - string type_comment; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _keyword { - identifier arg; - expr_ty value; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _alias { - identifier name; - identifier asname; -}; - -struct _withitem { - expr_ty context_expr; - expr_ty optional_vars; -}; - -enum _type_ignore_kind {TypeIgnore_kind=1}; -struct _type_ignore { - enum _type_ignore_kind kind; - union { - struct { - int lineno; - string tag; - } TypeIgnore; - - } v; -}; - - -// Note: these macros affect function definitions, not only call sites. -#define Module(a0, a1, a2) _Py_Module(a0, a1, a2) -mod_ty _Py_Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena); -#define Interactive(a0, a1) _Py_Interactive(a0, a1) -mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena); -#define Expression(a0, a1) _Py_Expression(a0, a1) -mod_ty _Py_Expression(expr_ty body, PyArena *arena); -#define FunctionType(a0, a1, a2) _Py_FunctionType(a0, a1, a2) -mod_ty _Py_FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena); -#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, - asdl_seq * decorator_list, expr_ty returns, string - type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * - body, asdl_seq * decorator_list, expr_ty returns, - string type_comment, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena - *arena); -#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, - asdl_seq * body, asdl_seq * decorator_list, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define Return(a0, a1, a2, a3, a4, a5) _Py_Return(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define Delete(a0, a1, a2, a3, a4, a5) _Py_Delete(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Assign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Assign(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) -stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int - simple, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * - orelse, string type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * - orelse, string type_comment, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define While(a0, a1, a2, a3, a4, a5, a6, a7) _Py_While(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define If(a0, a1, a2, a3, a4, a5, a6, a7) _Py_If(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define With(a0, a1, a2, a3, a4, a5, a6, a7) _Py_With(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Raise(a0, a1, a2, a3, a4, a5, a6) _Py_Raise(a0, a1, a2, a3, a4, a5, a6) -stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) -stmt_ty _Py_Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, - asdl_seq * finalbody, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Assert(a0, a1, a2, a3, a4, a5, a6) _Py_Assert(a0, a1, a2, a3, a4, a5, a6) -stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Import(a0, a1, a2, a3, a4, a5) _Py_Import(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Global(a0, a1, a2, a3, a4, a5) _Py_Global(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Nonlocal(a0, a1, a2, a3, a4, a5) _Py_Nonlocal(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Nonlocal(asdl_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Expr(a0, a1, a2, a3, a4, a5) _Py_Expr(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Pass(a0, a1, a2, a3, a4) _Py_Pass(a0, a1, a2, a3, a4) -stmt_ty _Py_Pass(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Break(a0, a1, a2, a3, a4) _Py_Break(a0, a1, a2, a3, a4) -stmt_ty _Py_Break(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Continue(a0, a1, a2, a3, a4) _Py_Continue(a0, a1, a2, a3, a4) -stmt_ty _Py_Continue(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define BoolOp(a0, a1, a2, a3, a4, a5, a6) _Py_BoolOp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define NamedExpr(a0, a1, a2, a3, a4, a5, a6) _Py_NamedExpr(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_NamedExpr(expr_ty target, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define BinOp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_BinOp(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define UnaryOp(a0, a1, a2, a3, a4, a5, a6) _Py_UnaryOp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define Lambda(a0, a1, a2, a3, a4, a5, a6) _Py_Lambda(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define IfExp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_IfExp(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Dict(a0, a1, a2, a3, a4, a5, a6) _Py_Dict(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Set(a0, a1, a2, a3, a4, a5) _Py_Set(a0, a1, a2, a3, a4, a5) -expr_ty _Py_Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define ListComp(a0, a1, a2, a3, a4, a5, a6) _Py_ListComp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define SetComp(a0, a1, a2, a3, a4, a5, a6) _Py_SetComp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_SetComp(expr_ty elt, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define DictComp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_DictComp(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define GeneratorExp(a0, a1, a2, a3, a4, a5, a6) _Py_GeneratorExp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define Await(a0, a1, a2, a3, a4, a5) _Py_Await(a0, a1, a2, a3, a4, a5) -expr_ty _Py_Await(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define Yield(a0, a1, a2, a3, a4, a5) _Py_Yield(a0, a1, a2, a3, a4, a5) -expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define YieldFrom(a0, a1, a2, a3, a4, a5) _Py_YieldFrom(a0, a1, a2, a3, a4, a5) -expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Compare(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Compare(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5) -expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Constant(a0, a1, a2, a3, a4, a5, a6) _Py_Constant(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Constant(constant value, string kind, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define Attribute(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Attribute(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Subscript(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Subscript(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Starred(a0, a1, a2, a3, a4, a5, a6) _Py_Starred(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Starred(expr_ty value, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Name(a0, a1, a2, a3, a4, a5, a6) _Py_Name(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define List(a0, a1, a2, a3, a4, a5, a6) _Py_List(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Tuple(a0, a1, a2, a3, a4, a5, a6) _Py_Tuple(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Slice(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Slice(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define comprehension(a0, a1, a2, a3, a4) _Py_comprehension(a0, a1, a2, a3, a4) -comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq * - ifs, int is_async, PyArena *arena); -#define ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) -excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq * - body, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena - *arena); -#define arguments(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7) -arguments_ty _Py_arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty - vararg, asdl_seq * kwonlyargs, asdl_seq * - kw_defaults, arg_ty kwarg, asdl_seq * defaults, - PyArena *arena); -#define arg(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arg(a0, a1, a2, a3, a4, a5, a6, a7) -arg_ty _Py_arg(identifier arg, expr_ty annotation, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define keyword(a0, a1, a2, a3, a4, a5, a6) _Py_keyword(a0, a1, a2, a3, a4, a5, a6) -keyword_ty _Py_keyword(identifier arg, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) -alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); -#define withitem(a0, a1, a2) _Py_withitem(a0, a1, a2) -withitem_ty _Py_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena - *arena); -#define TypeIgnore(a0, a1, a2) _Py_TypeIgnore(a0, a1, a2) -type_ignore_ty _Py_TypeIgnore(int lineno, string tag, PyArena *arena); - -PyObject* PyAST_mod2obj(mod_ty t); -mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); -int PyAST_Check(PyObject* obj); -#endif /* !Py_LIMITED_API */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYTHON_AST_H */ diff --git a/contrib/tools/python3/src/Include/Python.h b/contrib/tools/python3/src/Include/Python.h index 7f7ed5981c5..d3186c32e35 100644 --- a/contrib/tools/python3/src/Include/Python.h +++ b/contrib/tools/python3/src/Include/Python.h @@ -68,17 +68,7 @@ # endif #endif -/* Debug-mode build with pymalloc implies PYMALLOC_DEBUG. - * PYMALLOC_DEBUG is in error if pymalloc is not in use. - */ -#if defined(Py_DEBUG) && defined(WITH_PYMALLOC) && !defined(PYMALLOC_DEBUG) -#define PYMALLOC_DEBUG -#endif -#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC) -#error "PYMALLOC_DEBUG requires WITH_PYMALLOC" -#endif #include "pymath.h" -#include "pytime.h" #include "pymem.h" #include "object.h" @@ -86,7 +76,7 @@ #include "typeslots.h" #include "pyhash.h" -#include "pydebug.h" +#include "cpython/pydebug.h" #include "bytearrayobject.h" #include "bytesobject.h" @@ -101,7 +91,7 @@ #include "tupleobject.h" #include "listobject.h" #include "dictobject.h" -#include "odictobject.h" +#include "cpython/odictobject.h" #include "enumobject.h" #include "setobject.h" #include "methodobject.h" @@ -124,7 +114,8 @@ #include "weakrefobject.h" #include "structseq.h" #include "namespaceobject.h" -#include "picklebufobject.h" +#include "cpython/picklebufobject.h" +#include "cpython/pytime.h" #include "codecs.h" #include "pyerrors.h" @@ -132,7 +123,6 @@ #include "pystate.h" #include "context.h" -#include "pyarena.h" #include "modsupport.h" #include "compile.h" #include "pythonrun.h" @@ -148,11 +138,11 @@ #include "eval.h" -#include "pyctype.h" +#include "cpython/pyctype.h" #include "pystrtod.h" #include "pystrcmp.h" #include "fileutils.h" -#include "pyfpe.h" +#include "cpython/pyfpe.h" #include "tracemalloc.h" #endif /* !Py_PYTHON_H */ diff --git a/contrib/tools/python3/src/Include/abstract.h b/contrib/tools/python3/src/Include/abstract.h index d31d66e6b4a..9eaab6b2e05 100644 --- a/contrib/tools/python3/src/Include/abstract.h +++ b/contrib/tools/python3/src/Include/abstract.h @@ -371,11 +371,21 @@ PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj, returns itself. */ PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); -/* Returns 1 if the object 'obj' provides iterator protocols, and 0 otherwise. +/* Takes an AsyncIterable object and returns an AsyncIterator for it. + This is typically a new iterator but if the argument is an AsyncIterator, + this returns itself. */ +PyAPI_FUNC(PyObject *) PyObject_GetAIter(PyObject *); + +/* Returns non-zero if the object 'obj' provides iterator protocols, and 0 otherwise. This function always succeeds. */ PyAPI_FUNC(int) PyIter_Check(PyObject *); +/* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyAIter_Check(PyObject *); + /* Takes an iterator object and calls its tp_iternext slot, returning the next value. @@ -385,6 +395,19 @@ PyAPI_FUNC(int) PyIter_Check(PyObject *); NULL with an exception means an error occurred. */ PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 + +/* Takes generator, coroutine or iterator object and sends the value into it. + Returns: + - PYGEN_RETURN (0) if generator has returned. + 'result' parameter is filled with return value + - PYGEN_ERROR (-1) if exception was raised. + 'result' parameter is NULL + - PYGEN_NEXT (1) if generator has yielded. + 'result' parameter is filled with yielded value. */ +PyAPI_FUNC(PySendResult) PyIter_Send(PyObject *, PyObject *, PyObject **); +#endif + /* === Number Protocol ================================================== */ diff --git a/contrib/tools/python3/src/Include/asdl.h b/contrib/tools/python3/src/Include/asdl.h deleted file mode 100644 index e962560bcd4..00000000000 --- a/contrib/tools/python3/src/Include/asdl.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_ASDL_H -#define Py_ASDL_H - -typedef PyObject * identifier; -typedef PyObject * string; -typedef PyObject * object; -typedef PyObject * constant; - -/* It would be nice if the code generated by asdl_c.py was completely - independent of Python, but it is a goal the requires too much work - at this stage. So, for example, I'll represent identifiers as - interned Python strings. -*/ - -/* XXX A sequence should be typed so that its use can be typechecked. */ - -typedef struct { - Py_ssize_t size; - void *elements[1]; -} asdl_seq; - -typedef struct { - Py_ssize_t size; - int elements[1]; -} asdl_int_seq; - -asdl_seq *_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena); -asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena); - -#define asdl_seq_GET(S, I) (S)->elements[(I)] -#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) -#ifdef Py_DEBUG -#define asdl_seq_SET(S, I, V) \ - do { \ - Py_ssize_t _asdl_i = (I); \ - assert((S) != NULL); \ - assert(0 <= _asdl_i && _asdl_i < (S)->size); \ - (S)->elements[_asdl_i] = (V); \ - } while (0) -#else -#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V) -#endif - -#endif /* !Py_ASDL_H */ -#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/ast.h b/contrib/tools/python3/src/Include/ast.h deleted file mode 100644 index a8c52af786b..00000000000 --- a/contrib/tools/python3/src/Include/ast.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_AST_H -#define Py_AST_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python-ast.h" /* mod_ty */ -#include "node.h" /* node */ - -PyAPI_FUNC(int) PyAST_Validate(mod_ty); -PyAPI_FUNC(mod_ty) PyAST_FromNode( - const node *n, - PyCompilerFlags *flags, - const char *filename, /* decoded from the filesystem encoding */ - PyArena *arena); -PyAPI_FUNC(mod_ty) PyAST_FromNodeObject( - const node *n, - PyCompilerFlags *flags, - PyObject *filename, - PyArena *arena); - -/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */ -PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(expr_ty); - -/* Return the borrowed reference to the first literal string in the - sequence of statements or NULL if it doesn't start from a literal string. - Doesn't set exception. */ -PyAPI_FUNC(PyObject *) _PyAST_GetDocString(asdl_seq *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_AST_H */ -#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/bitset.h b/contrib/tools/python3/src/Include/bitset.h deleted file mode 100644 index 6a2ac9787ea..00000000000 --- a/contrib/tools/python3/src/Include/bitset.h +++ /dev/null @@ -1,23 +0,0 @@ - -#ifndef Py_BITSET_H -#define Py_BITSET_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Bitset interface */ - -#define BYTE char -typedef BYTE *bitset; - -#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0) - -#define BITSPERBYTE (8*sizeof(BYTE)) -#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE) -#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE) -#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit)) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BITSET_H */ diff --git a/contrib/tools/python3/src/Include/boolobject.h b/contrib/tools/python3/src/Include/boolobject.h index bb8044a2b02..cda6f89a99e 100644 --- a/contrib/tools/python3/src/Include/boolobject.h +++ b/contrib/tools/python3/src/Include/boolobject.h @@ -15,15 +15,24 @@ PyAPI_DATA(PyTypeObject) PyBool_Type; Don't forget to apply Py_INCREF() when returning either!!! */ /* Don't use these directly */ -PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct; +PyAPI_DATA(struct _longobject) _Py_FalseStruct; +PyAPI_DATA(struct _longobject) _Py_TrueStruct; /* Use these macros */ #define Py_False ((PyObject *) &_Py_FalseStruct) #define Py_True ((PyObject *) &_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); +#define Py_IsTrue(x) Py_Is((x), Py_True) + +// Test if an object is the False singleton, the same as "x is False" in Python. +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_INCREF(Py_True), Py_True -#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +#define Py_RETURN_TRUE return Py_NewRef(Py_True) +#define Py_RETURN_FALSE return Py_NewRef(Py_False) /* Function to return a bool from a C long */ PyAPI_FUNC(PyObject *) PyBool_FromLong(long); diff --git a/contrib/tools/python3/src/Include/bytesobject.h b/contrib/tools/python3/src/Include/bytesobject.h index 5062d8d123a..39c241a2dcf 100644 --- a/contrib/tools/python3/src/Include/bytesobject.h +++ b/contrib/tools/python3/src/Include/bytesobject.h @@ -1,5 +1,5 @@ -/* Bytes (String) object interface */ +/* Bytes object interface */ #ifndef Py_BYTESOBJECT_H #define Py_BYTESOBJECT_H @@ -10,23 +10,20 @@ extern "C" { #include /* -Type PyBytesObject represents a character string. An extra zero byte is +Type PyBytesObject represents a byte string. An extra zero byte is reserved at the end to ensure it is zero-terminated, but a size is present so strings with null bytes in them can be represented. This is an immutable object type. -There are functions to create new string objects, to test -an object for string-ness, and to get the -string value. The latter function returns a null pointer +There are functions to create new bytes objects, to test +an object for bytes-ness, and to get the +byte string value. The latter function returns a null pointer if the object is not of the proper type. There is a variant that takes an explicit size as well as a variant that assumes a zero-terminated string. Note that none of the -functions should be applied to nil objects. +functions should be applied to NULL pointer. */ -/* Caching the hash (ob_shash) saves recalculation of a string's hash value. - This significantly speeds up dict lookups. */ - PyAPI_DATA(PyTypeObject) PyBytes_Type; PyAPI_DATA(PyTypeObject) PyBytesIter_Type; @@ -50,26 +47,16 @@ PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, Py_ssize_t, const char *); -/* Provides access to the internal data buffer and size of a string - object or the default encoded version of a Unicode object. Passing - NULL as *len parameter will force the string buffer to be - 0-terminated (passing a string with embedded NULL characters will +/* Provides access to the internal data buffer and size of a bytes object. + Passing NULL as len parameter will force the string buffer to be + 0-terminated (passing a string with embedded NUL characters will cause an exception). */ PyAPI_FUNC(int) PyBytes_AsStringAndSize( - PyObject *obj, /* string or Unicode object */ + PyObject *obj, /* bytes object */ char **s, /* pointer to buffer variable */ - Py_ssize_t *len /* pointer to length variable or NULL - (only possible for 0-terminated - strings) */ + Py_ssize_t *len /* pointer to length variable or NULL */ ); -/* Flags used by string formatting */ -#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) - #ifndef Py_LIMITED_API # define Py_CPYTHON_BYTESOBJECT_H # include "cpython/bytesobject.h" diff --git a/contrib/tools/python3/src/Include/cellobject.h b/contrib/tools/python3/src/Include/cellobject.h index f12aa90a42a..81bc784d36f 100644 --- a/contrib/tools/python3/src/Include/cellobject.h +++ b/contrib/tools/python3/src/Include/cellobject.h @@ -20,7 +20,7 @@ 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) (((PyCellObject *)(op))->ob_ref = v) +#define PyCell_SET(op, v) ((void)(((PyCellObject *)(op))->ob_ref = v)) #ifdef __cplusplus } diff --git a/contrib/tools/python3/src/Include/ceval.h b/contrib/tools/python3/src/Include/ceval.h index 0f372e2044a..0f687666e2b 100644 --- a/contrib/tools/python3/src/Include/ceval.h +++ b/contrib/tools/python3/src/Include/ceval.h @@ -67,14 +67,6 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void); PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); -#define Py_ALLOW_RECURSION \ - do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ - PyThreadState_GET()->recursion_critical = 1; - -#define Py_END_ALLOW_RECURSION \ - PyThreadState_GET()->recursion_critical = _old; \ - } while(0); - PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); diff --git a/contrib/tools/python3/src/Include/codecs.h b/contrib/tools/python3/src/Include/codecs.h index 3ad0f2b5aae..37ecfb4ab75 100644 --- a/contrib/tools/python3/src/Include/codecs.h +++ b/contrib/tools/python3/src/Include/codecs.h @@ -27,6 +27,14 @@ PyAPI_FUNC(int) PyCodec_Register( PyObject *search_function ); +/* Unregister a codec search function and clear the registry's cache. + If the search function is not registered, do nothing. + Return 0 on success. Raise an exception and return -1 on error. */ + +PyAPI_FUNC(int) PyCodec_Unregister( + PyObject *search_function + ); + /* Codec registry lookup API. Looks up the given encoding and returns a CodecInfo object with diff --git a/contrib/tools/python3/src/Include/compile.h b/contrib/tools/python3/src/Include/compile.h index 98adee3d191..3c5acd7209f 100644 --- a/contrib/tools/python3/src/Include/compile.h +++ b/contrib/tools/python3/src/Include/compile.h @@ -1,109 +1,9 @@ #ifndef Py_COMPILE_H #define Py_COMPILE_H - -#ifndef Py_LIMITED_API - #ifdef __cplusplus extern "C" { #endif -/* Public interface */ -struct _node; /* Declare the existence of this type */ -#ifndef Py_BUILD_CORE -Py_DEPRECATED(3.9) -#endif -PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); -/* XXX (ncoghlan): Unprefixed type name in a public API! */ - -#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ - CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ - CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ - CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) -#define PyCF_MASK_OBSOLETE (CO_NESTED) - -/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. - PyCF_ constants can use bits from 0x0100 to 0x10000. - CO_FUTURE_ constants use bits starting at 0x20000. */ -#define PyCF_SOURCE_IS_UTF8 0x0100 -#define PyCF_DONT_IMPLY_DEDENT 0x0200 -#define PyCF_ONLY_AST 0x0400 -#define PyCF_IGNORE_COOKIE 0x0800 -#define PyCF_TYPE_COMMENTS 0x1000 -#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 -#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ - PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT) - -#ifndef Py_LIMITED_API -typedef struct { - int cf_flags; /* bitmask of CO_xxx flags relevant to future */ - int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ -} PyCompilerFlags; - -#define _PyCompilerFlags_INIT \ - (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} -#endif - -/* Future feature support */ - -typedef struct { - int ff_features; /* flags set by future statements */ - int ff_lineno; /* line number of last future statement */ -} PyFutureFeatures; - -#define FUTURE_NESTED_SCOPES "nested_scopes" -#define FUTURE_GENERATORS "generators" -#define FUTURE_DIVISION "division" -#define FUTURE_ABSOLUTE_IMPORT "absolute_import" -#define FUTURE_WITH_STATEMENT "with_statement" -#define FUTURE_PRINT_FUNCTION "print_function" -#define FUTURE_UNICODE_LITERALS "unicode_literals" -#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" -#define FUTURE_GENERATOR_STOP "generator_stop" -#define FUTURE_ANNOTATIONS "annotations" - -struct _mod; /* Declare the existence of this type */ -#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar) -PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx( - struct _mod *mod, - const char *filename, /* decoded from the filesystem encoding */ - PyCompilerFlags *flags, - int optimize, - PyArena *arena); -PyAPI_FUNC(PyCodeObject *) PyAST_CompileObject( - struct _mod *mod, - PyObject *filename, - PyCompilerFlags *flags, - int optimize, - PyArena *arena); -PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST( - struct _mod * mod, - const char *filename /* decoded from the filesystem encoding */ - ); -PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromASTObject( - struct _mod * mod, - PyObject *filename - ); - -/* _Py_Mangle is defined in compile.c */ -PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); - -#define PY_INVALID_STACK_EFFECT INT_MAX -PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); -PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); - -typedef struct { - int optimize; - int ff_features; -} _PyASTOptimizeState; - -PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, _PyASTOptimizeState *state); - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_LIMITED_API */ - /* These definitions must match corresponding definitions in graminit.h. */ #define Py_single_input 256 #define Py_file_input 257 @@ -113,4 +13,13 @@ PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, _PyASTOptimizeSta /* This doesn't need to match anything */ #define Py_fstring_input 800 +#ifndef Py_LIMITED_API +# define Py_CPYTHON_COMPILE_H +# include "cpython/compile.h" +# undef Py_CPYTHON_COMPILE_H +#endif + +#ifdef __cplusplus +} +#endif #endif /* !Py_COMPILE_H */ diff --git a/contrib/tools/python3/src/Include/cpython/abstract.h b/contrib/tools/python3/src/Include/cpython/abstract.h index 0f1304d26af..db850219645 100644 --- a/contrib/tools/python3/src/Include/cpython/abstract.h +++ b/contrib/tools/python3/src/Include/cpython/abstract.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* === Object Protocol ================================================== */ #ifdef PY_SSIZE_T_CLEAN @@ -123,7 +119,7 @@ static inline PyObject * PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = PyThreadState_Get(); return _PyObject_VectorcallTstate(tstate, callable, args, nargsf, kwnames); } @@ -159,7 +155,7 @@ _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const static inline PyObject * _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = PyThreadState_Get(); return _PyObject_FastCallTstate(tstate, func, args, nargs); } @@ -168,7 +164,7 @@ _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) PyObject_CallNoArgs(). */ static inline PyObject * _PyObject_CallNoArg(PyObject *func) { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = PyThreadState_Get(); return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } @@ -183,7 +179,7 @@ PyObject_CallOneArg(PyObject *func, PyObject *arg) assert(arg != NULL); args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET args[0] = arg; - tstate = PyThreadState_GET(); + tstate = PyThreadState_Get(); nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } @@ -329,12 +325,6 @@ PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, /* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); -/* ==== Iterators ================================================ */ - -#define PyIter_Check(obj) \ - (Py_TYPE(obj)->tp_iternext != NULL && \ - Py_TYPE(obj)->tp_iternext != &_PyObject_NextNotImplemented) - /* === Sequence protocol ================================================ */ /* Assume tp_as_sequence and sq_item exist and that 'i' does not @@ -379,6 +369,5 @@ PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, /* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); -#ifdef __cplusplus -} -#endif +/* Same as PyNumber_Index but can return an instance of a subclass of int. */ +PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o); diff --git a/contrib/tools/python3/src/Include/cpython/bytesobject.h b/contrib/tools/python3/src/Include/cpython/bytesobject.h index f284c5835df..6b3f55224fc 100644 --- a/contrib/tools/python3/src/Include/cpython/bytesobject.h +++ b/contrib/tools/python3/src/Include/cpython/bytesobject.h @@ -10,7 +10,7 @@ typedef struct { /* Invariants: * ob_sval contains space for 'ob_size+1' elements. * ob_sval[ob_size] == 0. - * ob_shash is the hash of the string or -1 if not computed yet. + * ob_shash is the hash of the byte string or -1 if not computed yet. */ } PyBytesObject; diff --git a/contrib/tools/python3/src/Include/cpython/ceval.h b/contrib/tools/python3/src/Include/cpython/ceval.h index e1922a677bd..06338928f67 100644 --- a/contrib/tools/python3/src/Include/cpython/ceval.h +++ b/contrib/tools/python3/src/Include/cpython/ceval.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); @@ -32,7 +28,3 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/code.h b/contrib/tools/python3/src/Include/cpython/code.h index cda28ac6ee9..fa6408521cf 100644 --- a/contrib/tools/python3/src/Include/cpython/code.h +++ b/contrib/tools/python3/src/Include/cpython/code.h @@ -38,7 +38,7 @@ struct PyCodeObject { Py_ssize_t *co_cell2arg; /* Maps cell vars which are arguments. */ PyObject *co_filename; /* unicode (where it was loaded from) */ PyObject *co_name; /* unicode (name, for reference) */ - PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See + PyObject *co_linetable; /* string (encoding addr<->lineno mapping) See Objects/lnotab_notes.txt for details. */ void *co_zombieframe; /* for optimization only (see frameobject.c) */ PyObject *co_weakreflist; /* to support weakrefs to code objects */ @@ -135,16 +135,23 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno); PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); /* for internal use only */ -typedef struct _addr_pair { - int ap_lower; - int ap_upper; -} PyAddrPair; +struct _opaque { + int computed_line; + const char *lo_next; + const char *limit; +}; + +typedef struct _line_offsets { + int ar_start; + int ar_end; + int ar_line; + struct _opaque opaque; +} PyCodeAddressRange; /* Update *bounds to describe the first and one-past-the-last instructions in the same line as lasti. Return the number of that line. */ -PyAPI_FUNC(int) _PyCode_CheckLineNumber(PyCodeObject* co, - int lasti, PyAddrPair *bounds); +PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds); /* Create a comparable key used to compare constants taking in account the * object type. It is used to make sure types are not coerced (e.g., float and @@ -163,3 +170,15 @@ 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); + +/** API for initializing the line number table. */ +int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds); + +/** Out of process API for initializing the line number table. */ +void PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range); + +/** API for traversing the line number table. */ +int PyLineTable_NextAddressRange(PyCodeAddressRange *range); +int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); + + diff --git a/contrib/tools/python3/src/Include/cpython/compile.h b/contrib/tools/python3/src/Include/cpython/compile.h new file mode 100644 index 00000000000..518a3764992 --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/compile.h @@ -0,0 +1,54 @@ +#ifndef Py_CPYTHON_COMPILE_H +# error "this header file must not be included directly" +#endif + +/* Public interface */ +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ + CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ + CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) +#define PyCF_MASK_OBSOLETE (CO_NESTED) + +/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. + PyCF_ constants can use bits from 0x0100 to 0x10000. + CO_FUTURE_ constants use bits starting at 0x20000. */ +#define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 +#define PyCF_IGNORE_COOKIE 0x0800 +#define PyCF_TYPE_COMMENTS 0x1000 +#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 +#define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000 +#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ + PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \ + PyCF_ALLOW_INCOMPLETE_INPUT) + +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ + int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ +} PyCompilerFlags; + +#define _PyCompilerFlags_INIT \ + (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} + +/* Future feature support */ + +typedef struct { + int ff_features; /* flags set by future statements */ + int ff_lineno; /* line number of last future statement */ +} PyFutureFeatures; + +#define FUTURE_NESTED_SCOPES "nested_scopes" +#define FUTURE_GENERATORS "generators" +#define FUTURE_DIVISION "division" +#define FUTURE_ABSOLUTE_IMPORT "absolute_import" +#define FUTURE_WITH_STATEMENT "with_statement" +#define FUTURE_PRINT_FUNCTION "print_function" +#define FUTURE_UNICODE_LITERALS "unicode_literals" +#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" +#define FUTURE_GENERATOR_STOP "generator_stop" +#define FUTURE_ANNOTATIONS "annotations" + +#define PY_INVALID_STACK_EFFECT INT_MAX +PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); +PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); diff --git a/contrib/tools/python3/src/Include/cpython/dictobject.h b/contrib/tools/python3/src/Include/cpython/dictobject.h index 50f4c4a9e55..641d7bdc48e 100644 --- a/contrib/tools/python3/src/Include/cpython/dictobject.h +++ b/contrib/tools/python3/src/Include/cpython/dictobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct _dictkeysobject PyDictKeysObject; /* The ma_values pointer is NULL for a combined table @@ -45,13 +41,13 @@ PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, int (*predicate)(PyObject *value)); PyDictKeysObject *_PyDict_NewKeysForClass(void); -PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *); 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) -PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash); +PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); +PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, struct _Py_Identifier *); PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); @@ -68,7 +64,6 @@ PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); argument is raised. */ PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); -PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key); PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item); PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key); @@ -76,6 +71,7 @@ PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); +Py_ssize_t _PyDict_GetItemHint(PyDictObject *, PyObject *, Py_ssize_t, PyObject **); /* _PyDictView */ @@ -86,7 +82,3 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/fileobject.h b/contrib/tools/python3/src/Include/cpython/fileobject.h index 3005ce1f00f..cff2243d625 100644 --- a/contrib/tools/python3/src/Include/cpython/fileobject.h +++ b/contrib/tools/python3/src/Include/cpython/fileobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); /* The std printer acts as a preliminary sys.stderr until the new io @@ -19,6 +15,4 @@ PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); -#ifdef __cplusplus -} -#endif +PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *); diff --git a/contrib/tools/python3/src/Include/cpython/fileutils.h b/contrib/tools/python3/src/Include/cpython/fileutils.h index e79d03e24f5..ccf37e9468d 100644 --- a/contrib/tools/python3/src/Include/cpython/fileutils.h +++ b/contrib/tools/python3/src/Include/cpython/fileutils.h @@ -32,6 +32,9 @@ PyAPI_FUNC(int) _Py_EncodeLocaleEx( int current_locale, _Py_error_handler errors); +PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( + const wchar_t *text, + size_t *error_pos); PyAPI_FUNC(PyObject *) _Py_device_encoding(int); @@ -95,10 +98,6 @@ PyAPI_FUNC(FILE *) _Py_wfopen( const wchar_t *path, const wchar_t *mode); -PyAPI_FUNC(FILE*) _Py_fopen( - const char *pathname, - const char *mode); - PyAPI_FUNC(FILE*) _Py_fopen_obj( PyObject *path, const char *mode); @@ -162,4 +161,12 @@ PyAPI_FUNC(int) _Py_dup(int fd); PyAPI_FUNC(int) _Py_get_blocking(int fd); PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); -#endif /* !MS_WINDOWS */ +#else /* MS_WINDOWS */ +PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd); + +PyAPI_FUNC(void*) _Py_get_osfhandle(int fd); + +PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags); + +PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags); +#endif /* MS_WINDOWS */ diff --git a/contrib/tools/python3/src/Include/cpython/frameobject.h b/contrib/tools/python3/src/Include/cpython/frameobject.h index 36a51baae87..5122ec41a3d 100644 --- a/contrib/tools/python3/src/Include/cpython/frameobject.h +++ b/contrib/tools/python3/src/Include/cpython/frameobject.h @@ -4,9 +4,20 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif +/* These values are chosen so that the inline functions below all + * compare f_state to zero. + */ +enum _framestate { + FRAME_CREATED = -2, + FRAME_SUSPENDED = -1, + FRAME_EXECUTING = 0, + FRAME_RETURNED = 1, + FRAME_UNWINDING = 2, + FRAME_RAISED = 3, + FRAME_CLEARED = 4 +}; + +typedef signed char PyFrameState; typedef struct { int b_type; /* what kind of block this is */ @@ -22,11 +33,8 @@ struct _frame { PyObject *f_globals; /* global symbol table (PyDictObject) */ PyObject *f_locals; /* local symbol table (any mapping) */ PyObject **f_valuestack; /* points after the last local */ - /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. - Frame evaluation usually NULLs it, but a frame that yields sets it - to the current stack top. */ - PyObject **f_stacktop; PyObject *f_trace; /* Trace function */ + int f_stackdepth; /* Depth of value stack */ char f_trace_lines; /* Emit per-line trace events? */ char f_trace_opcodes; /* Emit per-opcode trace events? */ @@ -34,18 +42,24 @@ struct _frame { PyObject *f_gen; int f_lasti; /* Last instruction if called */ - /* Call PyFrame_GetLineNumber() instead of reading this field - directly. As of 2.3 f_lineno is only valid when tracing is - active (i.e. when f_trace is set). At other times we use - PyCode_Addr2Line to calculate the line from the current - bytecode index. */ - int f_lineno; /* Current line number */ + int f_lineno; /* Current line number. Only valid if non-zero */ int f_iblock; /* index in f_blockstack */ - char f_executing; /* whether the frame is still executing */ + PyFrameState f_state; /* What state the frame is in */ PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ }; +static inline int _PyFrame_IsRunnable(struct _frame *f) { + return f->f_state < FRAME_EXECUTING; +} + +static inline int _PyFrame_IsExecuting(struct _frame *f) { + return f->f_state == FRAME_EXECUTING; +} + +static inline int _PyFrameHasCompleted(struct _frame *f) { + return f->f_state > FRAME_EXECUTING; +} /* Standard object interface */ @@ -57,8 +71,8 @@ PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, PyObject *, PyObject *); /* only internal use */ -PyFrameObject* _PyFrame_New_NoTrack(PyThreadState *, PyCodeObject *, - PyObject *, PyObject *); +PyFrameObject* +_PyFrame_New_NoTrack(PyThreadState *, PyFrameConstructor *, PyObject *); /* The rest of the interface is specific for frame objects */ @@ -78,7 +92,3 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/import.h b/contrib/tools/python3/src/Include/cpython/import.h index c1b47121f12..dd5bbdbad78 100644 --- a/contrib/tools/python3/src/Include/cpython/import.h +++ b/contrib/tools/python3/src/Include/cpython/import.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyMODINIT_FUNC PyInit__imp(void); PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); @@ -17,7 +13,8 @@ PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); PyAPI_FUNC(void) _PyImport_AcquireLock(void); PyAPI_FUNC(int) _PyImport_ReleaseLock(void); -PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *); +/* Obsolete since 3.5, will be removed in 3.11. */ +Py_DEPRECATED(3.10) PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *); PyAPI_FUNC(int) _PyImport_FixupBuiltin( PyObject *mod, @@ -44,7 +41,3 @@ struct _frozen { collection of frozen modules: */ PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/initconfig.h b/contrib/tools/python3/src/Include/cpython/initconfig.h index 0a256d4b5b0..583165bee48 100644 --- a/contrib/tools/python3/src/Include/cpython/initconfig.h +++ b/contrib/tools/python3/src/Include/cpython/initconfig.h @@ -44,7 +44,7 @@ PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list, /* --- PyPreConfig ----------------------------------------------- */ -typedef struct { +typedef struct PyPreConfig { int _config_init; /* _PyConfigInitEnum value */ /* Parse Py_PreInitializeFromBytesArgs() arguments? @@ -130,298 +130,85 @@ PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config); /* --- PyConfig ---------------------------------------------- */ -typedef struct { +/* This structure is best documented in the Doc/c-api/init_config.rst file. */ +typedef struct PyConfig { int _config_init; /* _PyConfigInitEnum value */ - int isolated; /* Isolated mode? see PyPreConfig.isolated */ - int use_environment; /* Use environment variables? see PyPreConfig.use_environment */ - int dev_mode; /* Python Development Mode? See PyPreConfig.dev_mode */ - - /* Install signal handlers? Yes by default. */ + int isolated; + int use_environment; + int dev_mode; int install_signal_handlers; - - int use_hash_seed; /* PYTHONHASHSEED=x */ + int use_hash_seed; unsigned long hash_seed; - - /* Enable faulthandler? - Set to 1 by -X faulthandler and PYTHONFAULTHANDLER. -1 means unset. */ int faulthandler; - - /* Enable PEG parser? - 1 by default, set to 0 by -X oldparser and PYTHONOLDPARSER */ - int _use_peg_parser; - - /* Enable tracemalloc? - Set by -X tracemalloc=N and PYTHONTRACEMALLOC. -1 means unset */ int tracemalloc; - - int import_time; /* PYTHONPROFILEIMPORTTIME, -X importtime */ - int show_ref_count; /* -X showrefcount */ - int dump_refs; /* PYTHONDUMPREFS */ - int malloc_stats; /* PYTHONMALLOCSTATS */ - - /* Python filesystem encoding and error handler: - sys.getfilesystemencoding() and sys.getfilesystemencodeerrors(). - - Default encoding and error handler: - - * if Py_SetStandardStreamEncoding() has been called: they have the - highest priority; - * PYTHONIOENCODING environment variable; - * The UTF-8 Mode uses UTF-8/surrogateescape; - * If Python forces the usage of the ASCII encoding (ex: C locale - or POSIX locale on FreeBSD or HP-UX), use ASCII/surrogateescape; - * locale encoding: ANSI code page on Windows, UTF-8 on Android and - VxWorks, LC_CTYPE locale encoding on other platforms; - * On Windows, "surrogateescape" error handler; - * "surrogateescape" error handler if the LC_CTYPE locale is "C" or "POSIX"; - * "surrogateescape" error handler if the LC_CTYPE locale has been coerced - (PEP 538); - * "strict" error handler. - - Supported error handlers: "strict", "surrogateescape" and - "surrogatepass". The surrogatepass error handler is only supported - if Py_DecodeLocale() and Py_EncodeLocale() use directly the UTF-8 codec; - it's only used on Windows. - - initfsencoding() updates the encoding to the Python codec name. - For example, "ANSI_X3.4-1968" is replaced with "ascii". - - On Windows, sys._enablelegacywindowsfsencoding() sets the - encoding/errors to mbcs/replace at runtime. - - - See Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors. - */ + int import_time; + int show_ref_count; + int dump_refs; + int malloc_stats; wchar_t *filesystem_encoding; wchar_t *filesystem_errors; - - wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ - int parse_argv; /* Parse argv command line arguments? */ - - /* Command line arguments (sys.argv). - - Set parse_argv to 1 to parse argv as Python command line arguments - and then strip Python arguments from argv. - - If argv is empty, an empty string is added to ensure that sys.argv - always exists and is never empty. */ + wchar_t *pycache_prefix; + int parse_argv; + PyWideStringList orig_argv; PyWideStringList argv; - - /* Program name: - - - If Py_SetProgramName() was called, use its value. - - On macOS, use PYTHONEXECUTABLE environment variable if set. - - If WITH_NEXT_FRAMEWORK macro is defined, use __PYVENV_LAUNCHER__ - environment variable is set. - - Use argv[0] if available and non-empty. - - Use "python" on Windows, or "python3 on other platforms. */ - wchar_t *program_name; - - PyWideStringList xoptions; /* Command line -X options */ - - /* Warnings options: lowest to highest priority. warnings.filters - is built in the reverse order (highest to lowest priority). */ + PyWideStringList xoptions; PyWideStringList warnoptions; - - /* If equal to zero, disable the import of the module site and the - site-dependent manipulations of sys.path that it entails. Also disable - these manipulations if site is explicitly imported later (call - site.main() if you want them to be triggered). - - Set to 0 by the -S command line option. If set to -1 (default), it is - set to !Py_NoSiteFlag. */ int site_import; - - /* Bytes warnings: - - * If equal to 1, issue a warning when comparing bytes or bytearray with - str or bytes with int. - * If equal or greater to 2, issue an error. - - Incremented by the -b command line option. If set to -1 (default), inherit - Py_BytesWarningFlag value. */ int bytes_warning; - - /* If greater than 0, enable inspect: when a script is passed as first - argument or the -c option is used, enter interactive mode after - executing the script or the command, even when sys.stdin does not appear - to be a terminal. - - Incremented by the -i command line option. Set to 1 if the PYTHONINSPECT - environment variable is non-empty. If set to -1 (default), inherit - Py_InspectFlag value. */ + int warn_default_encoding; int inspect; - - /* If greater than 0: enable the interactive mode (REPL). - - Incremented by the -i command line option. If set to -1 (default), - inherit Py_InteractiveFlag value. */ int interactive; - - /* Optimization level. - - Incremented by the -O command line option. Set by the PYTHONOPTIMIZE - environment variable. If set to -1 (default), inherit Py_OptimizeFlag - value. */ int optimization_level; - - /* If greater than 0, enable the debug mode: turn on parser debugging - output (for expert only, depending on compilation options). - - Incremented by the -d command line option. Set by the PYTHONDEBUG - environment variable. If set to -1 (default), inherit Py_DebugFlag - value. */ int parser_debug; - - /* If equal to 0, Python won't try to write ``.pyc`` files on the - import of source modules. - - Set to 0 by the -B command line option and the PYTHONDONTWRITEBYTECODE - environment variable. If set to -1 (default), it is set to - !Py_DontWriteBytecodeFlag. */ int write_bytecode; - - /* If greater than 0, enable the verbose mode: 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 searching for a module. Also provides information on module - cleanup at exit. - - Incremented by the -v option. Set by the PYTHONVERBOSE environment - variable. If set to -1 (default), inherit Py_VerboseFlag value. */ int verbose; - - /* If greater than 0, enable the quiet mode: Don't display the copyright - and version messages even in interactive mode. - - Incremented by the -q option. If set to -1 (default), inherit - Py_QuietFlag value. */ int quiet; - - /* If greater than 0, don't add the user site-packages directory to - sys.path. - - Set to 0 by the -s and -I command line options , and the PYTHONNOUSERSITE - environment variable. If set to -1 (default), it is set to - !Py_NoUserSiteDirectory. */ int user_site_directory; - - /* If non-zero, configure C standard steams (stdio, stdout, - stderr): - - - Set O_BINARY mode on Windows. - - If buffered_stdio is equal to zero, make streams unbuffered. - Otherwise, enable streams buffering if interactive is non-zero. */ int configure_c_stdio; - - /* If equal to 0, enable unbuffered mode: force the stdout and stderr - streams to be unbuffered. - - Set to 0 by the -u option. Set by the PYTHONUNBUFFERED environment - variable. - If set to -1 (default), it is set to !Py_UnbufferedStdioFlag. */ int buffered_stdio; - - /* Encoding of sys.stdin, sys.stdout and sys.stderr. - Value set from PYTHONIOENCODING environment variable and - Py_SetStandardStreamEncoding() function. - See also 'stdio_errors' attribute. */ wchar_t *stdio_encoding; - - /* Error handler of sys.stdin and sys.stdout. - Value set from PYTHONIOENCODING environment variable and - Py_SetStandardStreamEncoding() function. - See also 'stdio_encoding' attribute. */ wchar_t *stdio_errors; - #ifdef MS_WINDOWS - /* If greater than zero, use io.FileIO instead of WindowsConsoleIO for sys - standard streams. - - Set to 1 if the PYTHONLEGACYWINDOWSSTDIO environment variable is set to - a non-empty string. If set to -1 (default), inherit - Py_LegacyWindowsStdioFlag value. - - See PEP 528 for more details. */ int legacy_windows_stdio; #endif - - /* Value of the --check-hash-based-pycs command line option: - - - "default" means the 'check_source' flag in hash-based pycs - determines invalidation - - "always" causes the interpreter to hash the source file for - invalidation regardless of value of 'check_source' bit - - "never" causes the interpreter to always assume hash-based pycs are - valid - - The default value is "default". - - See PEP 552 "Deterministic pycs" for more details. */ wchar_t *check_hash_pycs_mode; /* --- Path configuration inputs ------------ */ - - /* If greater than 0, suppress _PyPathConfig_Calculate() warnings on Unix. - The parameter has no effect on Windows. - - If set to -1 (default), inherit !Py_FrozenFlag value. */ int pathconfig_warnings; - - wchar_t *pythonpath_env; /* PYTHONPATH environment variable */ - wchar_t *home; /* PYTHONHOME environment variable, - see also Py_SetPythonHome(). */ + wchar_t *program_name; + wchar_t *pythonpath_env; + wchar_t *home; + wchar_t *platlibdir; /* --- Path configuration outputs ----------- */ - - int module_search_paths_set; /* If non-zero, use module_search_paths */ - PyWideStringList module_search_paths; /* sys.path paths. Computed if - module_search_paths_set is equal - to zero. */ - - wchar_t *executable; /* sys.executable */ - wchar_t *base_executable; /* sys._base_executable */ - wchar_t *prefix; /* sys.prefix */ - wchar_t *base_prefix; /* sys.base_prefix */ - wchar_t *exec_prefix; /* sys.exec_prefix */ - wchar_t *base_exec_prefix; /* sys.base_exec_prefix */ - wchar_t *platlibdir; /* sys.platlibdir */ + int module_search_paths_set; + PyWideStringList module_search_paths; + wchar_t *executable; + wchar_t *base_executable; + wchar_t *prefix; + wchar_t *base_prefix; + wchar_t *exec_prefix; + wchar_t *base_exec_prefix; /* --- Parameter only used by Py_Main() ---------- */ - - /* Skip the first line of the source ('run_filename' parameter), allowing use of non-Unix forms of - "#!cmd". This is intended for a DOS specific hack only. - - Set by the -x command line option. */ int skip_source_first_line; - - wchar_t *run_command; /* -c command line argument */ - wchar_t *run_module; /* -m command line argument */ - wchar_t *run_filename; /* Trailing command line argument without -c or -m */ + wchar_t *run_command; + wchar_t *run_module; + wchar_t *run_filename; /* --- Private fields ---------------------------- */ - /* Install importlib? If set to 0, importlib is not initialized at all. - Needed by freeze_importlib. */ + // Install importlib? If equals to 0, importlib is not initialized at all. + // Needed by freeze_importlib. int _install_importlib; - /* If equal to 0, stop Python initialization before the "main" phase */ + // If equal to 0, stop Python initialization before the "main" phase. int _init_main; - /* If non-zero, disallow threads, subprocesses, and fork. - Default: 0. */ + // If non-zero, disallow threads, subprocesses, and fork. + // Default: 0. int _isolated_interpreter; - - /* Original command line arguments. If _orig_argv is empty and _argv is - not equal to [''], PyConfig_Read() copies the configuration 'argv' list - into '_orig_argv' list before modifying 'argv' list (if parse_argv - is non-zero). - - _PyConfig_Write() initializes Py_GetArgcArgv() to this list. */ - PyWideStringList _orig_argv; } PyConfig; PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); @@ -452,7 +239,7 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, /* Get the original command line arguments, before Python modified them. - See also PyConfig._orig_argv. */ + See also PyConfig.orig_argv. */ PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv); #ifdef __cplusplus diff --git a/contrib/tools/python3/src/Include/cpython/interpreteridobject.h b/contrib/tools/python3/src/Include/cpython/interpreteridobject.h index 67ec5873542..5076584209b 100644 --- a/contrib/tools/python3/src/Include/cpython/interpreteridobject.h +++ b/contrib/tools/python3/src/Include/cpython/interpreteridobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Interpreter ID Object */ PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; @@ -13,7 +9,3 @@ 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 diff --git a/contrib/tools/python3/src/Include/cpython/listobject.h b/contrib/tools/python3/src/Include/cpython/listobject.h index 74fe3301a7a..e3239152c49 100644 --- a/contrib/tools/python3/src/Include/cpython/listobject.h +++ b/contrib/tools/python3/src/Include/cpython/listobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { PyObject_VAR_HEAD /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ @@ -30,14 +26,9 @@ PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); /* Macro, trading safety for speed */ -/* Cast argument to PyTupleObject* type. */ +/* Cast argument to PyListObject* type. */ #define _PyList_CAST(op) (assert(PyList_Check(op)), (PyListObject *)(op)) #define PyList_GET_ITEM(op, i) (_PyList_CAST(op)->ob_item[i]) -#define PyList_SET_ITEM(op, i, v) (_PyList_CAST(op)->ob_item[i] = (v)) +#define PyList_SET_ITEM(op, i, v) ((void)(_PyList_CAST(op)->ob_item[i] = (v))) #define PyList_GET_SIZE(op) Py_SIZE(_PyList_CAST(op)) -#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item) - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/object.h b/contrib/tools/python3/src/Include/cpython/object.h index 444f832f5bd..84c60e55d5c 100644 --- a/contrib/tools/python3/src/Include/cpython/object.h +++ b/contrib/tools/python3/src/Include/cpython/object.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(void) _Py_NewReference(PyObject *op); #ifdef Py_TRACE_REFS @@ -13,10 +9,6 @@ PyAPI_FUNC(void) _Py_NewReference(PyObject *op); PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); #endif -/* Update the Python traceback of an object. This function must be called - when a memory block is reused from a free list. */ -PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); - #ifdef Py_REF_DEBUG PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); #endif @@ -43,12 +35,13 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. */ typedef struct _Py_Identifier { - struct _Py_Identifier *next; const char* string; - PyObject *object; + // Index in PyInterpreterState.unicode.ids.array. It is process-wide + // unique and must be initialized to -1. + Py_ssize_t index; } _Py_Identifier; -#define _Py_static_string_init(value) { .next = NULL, .string = value, .object = NULL } +#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) @@ -175,10 +168,13 @@ typedef struct { objobjargproc mp_ass_subscript; } PyMappingMethods; +typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result); + typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; + sendfunc am_send; } PyAsyncMethods; typedef struct { @@ -190,6 +186,8 @@ typedef struct { * backwards-compatibility */ typedef Py_ssize_t printfunc; +// If this structure is modified, Doc/includes/typestruct.h should be updated +// as well. struct _typeobject { PyObject_VAR_HEAD const char *tp_name; /* For printing, in format "." */ @@ -249,6 +247,7 @@ struct _typeobject { struct PyMethodDef *tp_methods; struct PyMemberDef *tp_members; struct PyGetSetDef *tp_getset; + // Strong reference on a heap type, borrowed reference on a static type struct _typeobject *tp_base; PyObject *tp_dict; descrgetfunc tp_descr_get; @@ -304,6 +303,8 @@ PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *); 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 *); +struct PyModuleDef; +PyAPI_FUNC(PyObject *) _PyType_GetModuleByDef(PyTypeObject *, struct PyModuleDef *); struct _Py_Identifier; PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); @@ -314,7 +315,6 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *); -PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *); /* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which don't raise AttributeError. @@ -519,6 +519,8 @@ struct _ts; /* Python 3.9 private API, invoked by the macros below. */ PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op); PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); +/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */ +PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); #define PyTrash_UNWIND_LEVEL 50 @@ -528,7 +530,7 @@ PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); /* 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_Get(); \ if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \ break; \ } \ @@ -542,13 +544,9 @@ PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); #define Py_TRASHCAN_BEGIN(op, dealloc) \ Py_TRASHCAN_BEGIN_CONDITION(op, \ - Py_TYPE(op)->tp_dealloc == (destructor)(dealloc)) + _PyTrash_cond(_PyObject_CAST(op), (destructor)dealloc)) /* For backwards compatibility, these macros enable the trashcan * unconditionally */ #define Py_TRASHCAN_SAFE_BEGIN(op) Py_TRASHCAN_BEGIN_CONDITION(op, 1) #define Py_TRASHCAN_SAFE_END(op) Py_TRASHCAN_END - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/objimpl.h b/contrib/tools/python3/src/Include/cpython/objimpl.h index b835936db70..d83700e2a46 100644 --- a/contrib/tools/python3/src/Include/cpython/objimpl.h +++ b/contrib/tools/python3/src/Include/cpython/objimpl.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a @@ -41,8 +37,9 @@ extern "C" { PyObject *op; op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); - if (op == NULL) - return PyErr_NoMemory(); + if (op == NULL) { + return PyErr_NoMemory(); + } PyObject_Init(op, &YourTypeStruct); @@ -55,40 +52,6 @@ extern "C" { the 1st step is performed automatically for you, so in a C++ class constructor you would start directly with PyObject_Init/InitVar. */ - -/* Inline functions trading binary compatibility for speed: - PyObject_INIT() is the fast version of PyObject_Init(), and - PyObject_INIT_VAR() is the fast version of PyObject_InitVar(). - - These inline functions must not be called with op=NULL. */ -static inline PyObject* -_PyObject_INIT(PyObject *op, PyTypeObject *typeobj) -{ - assert(op != NULL); - Py_SET_TYPE(op, typeobj); - if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { - Py_INCREF(typeobj); - } - _Py_NewReference(op); - return op; -} - -#define PyObject_INIT(op, typeobj) \ - _PyObject_INIT(_PyObject_CAST(op), (typeobj)) - -static inline PyVarObject* -_PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) -{ - assert(op != NULL); - Py_SET_SIZE(op, size); - PyObject_INIT((PyObject *)op, typeobj); - return op; -} - -#define PyObject_INIT_VAR(op, typeobj, size) \ - _PyObject_INIT_VAR(_PyVarObject_CAST(op), (typeobj), (size)) - - /* This function returns the number of allocated memory blocks, regardless of size */ PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); @@ -116,10 +79,6 @@ PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator); PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator); -PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(void); -PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void); - - /* Test if an object implements the garbage collector protocol */ PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); @@ -139,7 +98,3 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/odictobject.h b/contrib/tools/python3/src/Include/cpython/odictobject.h new file mode 100644 index 00000000000..e070413017d --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/odictobject.h @@ -0,0 +1,43 @@ +#ifndef Py_ODICTOBJECT_H +#define Py_ODICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* OrderedDict */ +/* This API is optional and mostly redundant. */ + +#ifndef Py_LIMITED_API + +typedef struct _odictobject PyODictObject; + +PyAPI_DATA(PyTypeObject) PyODict_Type; +PyAPI_DATA(PyTypeObject) PyODictIter_Type; +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_SIZE(op) PyDict_GET_SIZE((op)) + +PyAPI_FUNC(PyObject *) PyODict_New(void); +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_GetItemWithError(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) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ODICTOBJECT_H */ diff --git a/contrib/tools/python3/src/Include/cpython/picklebufobject.h b/contrib/tools/python3/src/Include/cpython/picklebufobject.h new file mode 100644 index 00000000000..0df2561dcea --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/picklebufobject.h @@ -0,0 +1,31 @@ +/* PickleBuffer object. This is built-in for ease of use from third-party + * C extensions. + */ + +#ifndef Py_PICKLEBUFOBJECT_H +#define Py_PICKLEBUFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + +PyAPI_DATA(PyTypeObject) 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 *); +/* Get the PickleBuffer's underlying view to the original object + * (NULL if released) + */ +PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *); +/* Release the PickleBuffer. Returns 0 on success, -1 on error. */ +PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *); + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PICKLEBUFOBJECT_H */ diff --git a/contrib/tools/python3/src/Include/cpython/pyctype.h b/contrib/tools/python3/src/Include/cpython/pyctype.h new file mode 100644 index 00000000000..729d93275e6 --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/pyctype.h @@ -0,0 +1,39 @@ +#ifndef Py_LIMITED_API +#ifndef PYCTYPE_H +#define PYCTYPE_H +#ifdef __cplusplus +extern "C" { +#endif + +#define PY_CTF_LOWER 0x01 +#define PY_CTF_UPPER 0x02 +#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) +#define PY_CTF_DIGIT 0x04 +#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) +#define PY_CTF_SPACE 0x08 +#define PY_CTF_XDIGIT 0x10 + +PyAPI_DATA(const unsigned int) _Py_ctype_table[256]; + +/* Unlike their C counterparts, the following macros are not meant to + * handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument + * must be a signed/unsigned char. */ +#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) +#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) +#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) +#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) +#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) +#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) +#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) + +PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256]; +PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256]; + +#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) +#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) + +#ifdef __cplusplus +} +#endif +#endif /* !PYCTYPE_H */ +#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/cpython/pydebug.h b/contrib/tools/python3/src/Include/cpython/pydebug.h new file mode 100644 index 00000000000..78bcb118be4 --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/pydebug.h @@ -0,0 +1,38 @@ +#ifndef Py_LIMITED_API +#ifndef Py_PYDEBUG_H +#define Py_PYDEBUG_H +#ifdef __cplusplus +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; + +#ifdef MS_WINDOWS +PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; +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 */ +#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYDEBUG_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/cpython/pyerrors.h b/contrib/tools/python3/src/Include/cpython/pyerrors.h index 9c87b539790..3f952456679 100644 --- a/contrib/tools/python3/src/Include/cpython/pyerrors.h +++ b/contrib/tools/python3/src/Include/cpython/pyerrors.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Error objects */ /* PyException_HEAD defines the initial segment of every exception class. */ @@ -24,6 +20,8 @@ typedef struct { PyObject *filename; PyObject *lineno; PyObject *offset; + PyObject *end_lineno; + PyObject *end_offset; PyObject *text; PyObject *print_file_and_line; } PySyntaxErrorObject; @@ -66,6 +64,17 @@ typedef struct { PyObject *value; } PyStopIterationObject; +typedef struct { + PyException_HEAD + PyObject *name; +} PyNameErrorObject; + +typedef struct { + PyException_HEAD + PyObject *obj; + PyObject *name; +} PyAttributeErrorObject; + /* Compatibility typedefs */ typedef PyOSErrorObject PyEnvironmentErrorObject; #ifdef MS_WINDOWS @@ -82,10 +91,6 @@ PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, Py PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); -/* */ - -#define PyExceptionClass_Name(x) (((PyTypeObject*)(x))->tp_name) - /* Convenience functions */ #ifdef MS_WINDOWS @@ -145,6 +150,13 @@ PyAPI_FUNC(void) PyErr_SyntaxLocationObject( int lineno, int col_offset); +PyAPI_FUNC(void) PyErr_RangedSyntaxLocationObject( + PyObject *filename, + int lineno, + int col_offset, + int end_lineno, + int end_col_offset); + PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( PyObject *filename, int lineno); @@ -173,6 +185,12 @@ Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( Py_ssize_t end, const char *reason /* UTF-8 encoded string */ ); + +PyAPI_FUNC(PyObject *) _PyErr_ProgramDecodedTextObject( + PyObject *filename, + int lineno, + const char* encoding); + PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( PyObject *object, Py_ssize_t start, @@ -194,7 +212,3 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat( ...); #define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message) - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/pyfpe.h b/contrib/tools/python3/src/Include/cpython/pyfpe.h new file mode 100644 index 00000000000..cc2def63aa5 --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/pyfpe.h @@ -0,0 +1,15 @@ +#ifndef Py_PYFPE_H +#define Py_PYFPE_H +/* Header excluded from the stable API */ +#ifndef Py_LIMITED_API + +/* These macros used to do something when Python was built with --with-fpectl, + * but support for that was dropped in 3.7. We continue to define them though, + * to avoid breaking API users. + */ + +#define PyFPE_START_PROTECT(err_string, leave_stmt) +#define PyFPE_END_PROTECT(v) + +#endif /* !defined(Py_LIMITED_API) */ +#endif /* !Py_PYFPE_H */ diff --git a/contrib/tools/python3/src/Include/cpython/pylifecycle.h b/contrib/tools/python3/src/Include/cpython/pylifecycle.h index eb523b82e18..5faeb3533b6 100644 --- a/contrib/tools/python3/src/Include/cpython/pylifecycle.h +++ b/contrib/tools/python3/src/Include/cpython/pylifecycle.h @@ -2,9 +2,9 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif +/* Py_FrozenMain is kept out of the Limited API until documented and present + in all builds of Python */ +PyAPI_FUNC(int) Py_FrozenMain(int argc, char **argv); /* Only used by applications that embed the interpreter and need to * override the standard encoding determination mechanism @@ -39,15 +39,11 @@ PyAPI_FUNC(int) Py_RunMain(void); PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err); -/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level - * exit functions. - */ -PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(PyObject *), PyObject *); - /* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ PyAPI_FUNC(void) _Py_RestoreSignals(void); PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); +PyAPI_FUNC(int) _Py_FdIsInteractive(FILE *fp, PyObject *filename); PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *); @@ -66,7 +62,3 @@ PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/pymem.h b/contrib/tools/python3/src/Include/cpython/pymem.h index 79f063b1217..d1054d76520 100644 --- a/contrib/tools/python3/src/Include/cpython/pymem.h +++ b/contrib/tools/python3/src/Include/cpython/pymem.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); @@ -14,8 +10,6 @@ PyAPI_FUNC(void) PyMem_RawFree(void *ptr); /* Try to get the allocators name set by _PyMem_SetupAllocators(). */ PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void); -PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); - /* strdup() using PyMem_RawMalloc() */ PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); @@ -102,7 +96,3 @@ PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, The function does nothing if Python is not compiled is debug mode. */ PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/pystate.h b/contrib/tools/python3/src/Include/cpython/pystate.h index 0eb601fd7c5..7c995b93074 100644 --- a/contrib/tools/python3/src/Include/cpython/pystate.h +++ b/contrib/tools/python3/src/Include/cpython/pystate.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); @@ -31,6 +27,21 @@ typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *); #define PyTrace_OPCODE 7 +typedef struct _cframe { + /* This struct will be threaded through the C stack + * allowing fast access to per-thread state that needs + * to be accessed quickly by the interpreter, but can + * be modified outside of the interpreter. + * + * WARNING: This makes data on the C stack accessible from + * heap objects. Care must be taken to maintain stack + * discipline and make sure that instances of this struct cannot + * accessed outside of their lifetime. + */ + int use_tracing; + struct _cframe *previous; +} CFrame; + typedef struct _err_stackitem { /* This struct represents an entry on the exception stack, which is a * per-coroutine state. (Coroutine in the computer science sense, @@ -56,17 +67,17 @@ struct _ts { /* Borrowed reference to the current frame (it can be NULL) */ PyFrameObject *frame; int recursion_depth; - char overflowed; /* The stack has overflowed. Allow 50 more calls - to handle the runtime error. */ - char recursion_critical; /* The current calls must not cause - a stack overflow. */ + int recursion_headroom; /* Allow 50 more calls to handle any errors. */ int stackcheck_counter; /* '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 use_tracing; + + /* Pointer to current CFrame in the C stack frame of the currently, + * or most recently, executing _PyEval_EvalFrameDefault. */ + CFrame *cframe; Py_tracefunc c_profilefunc; Py_tracefunc c_tracefunc; @@ -134,6 +145,8 @@ struct _ts { /* Unique thread state id. */ uint64_t id; + CFrame root_cframe; + /* XXX signal handlers should also be here */ }; @@ -171,6 +184,11 @@ PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); */ PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); +/* The implementation of sys._current_exceptions() Returns a dict mapping + thread id to that thread's current exception. +*/ +PyAPI_FUNC(PyObject *) _PyThread_CurrentExceptions(void); + /* Routines for advanced debuggers, requested by David Beazley. Don't use unless you know what you are doing! */ PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); @@ -192,7 +210,37 @@ PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc( PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *interp); -// Get the configuration of the currrent interpreter. +/* Get a copy of the current interpreter configuration. + + Return 0 on success. Raise an exception and return -1 on error. + + The caller must initialize 'config', using PyConfig_InitPythonConfig() + for example. + + Python must be preinitialized to call this method. + The caller must hold the GIL. */ +PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( + struct PyConfig *config); + +/* Set the configuration of the current interpreter. + + This function should be called during or just after the Python + initialization. + + Update the sys module with the new configuration. If the sys module was + modified directly after the Python initialization, these changes are lost. + + Some configuration like faulthandler or warnoptions can be updated in the + configuration, but don't reconfigure Python (don't enable/disable + faulthandler and don't reconfigure warnings filters). + + Return 0 on success. Raise an exception and return -1 on error. + + The configuration should come from _PyInterpreterState_GetConfigCopy(). */ +PyAPI_FUNC(int) _PyInterpreterState_SetConfig( + const struct PyConfig *config); + +// Get the configuration of the current interpreter. // The caller must hold the GIL. PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); @@ -255,7 +303,3 @@ typedef int (*crossinterpdatafunc)(PyObject *, struct _xid *); PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/pythonrun.h b/contrib/tools/python3/src/Include/cpython/pythonrun.h new file mode 100644 index 00000000000..2e72d0820d3 --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/pythonrun.h @@ -0,0 +1,121 @@ +#ifndef Py_CPYTHON_PYTHONRUN_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); +PyAPI_FUNC(int) _PyRun_SimpleFileObject( + FILE *fp, + PyObject *filename, + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_AnyFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) _PyRun_AnyFileObject( + FILE *fp, + PyObject *filename, + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_SimpleFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); +PyAPI_FUNC(int) _PyRun_InteractiveLoopObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); + + +PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, + PyObject *, PyCompilerFlags *); + +PyAPI_FUNC(PyObject *) PyRun_FileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyObject *globals, + PyObject *locals, + int closeit, + PyCompilerFlags *flags); + + +PyAPI_FUNC(PyObject *) Py_CompileStringExFlags( + const char *str, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyCompilerFlags *flags, + int optimize); +PyAPI_FUNC(PyObject *) Py_CompileStringObject( + const char *str, + PyObject *filename, int start, + 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) + + +PyAPI_FUNC(const char *) _Py_SourceAsString( + PyObject *cmd, + const char *funcname, + const char *what, + PyCompilerFlags *cf, + PyObject **cmd_copy); + + +/* A function flavor is also exported by libpython. It is required when + libpython is accessed directly rather than using header files which defines + macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to + export functions in pythonXX.dll. */ +PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l); +PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name); +PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit); +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_SimpleString(const char *s); +PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p); +PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c); +PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p); +PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p); +PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l); +PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c); +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_AnyFileEx(fp, name, closeit) \ + 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) +#define PyRun_File(fp, p, s, g, l) \ + 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) +#define PyRun_FileFlags(fp, p, s, g, l, flags) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, flags) + + +/* Stuff with no proper home (yet) */ +PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); +PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; +PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *); diff --git a/contrib/tools/python3/src/Include/cpython/pytime.h b/contrib/tools/python3/src/Include/cpython/pytime.h new file mode 100644 index 00000000000..9589972fa21 --- /dev/null +++ b/contrib/tools/python3/src/Include/cpython/pytime.h @@ -0,0 +1,249 @@ +#ifndef Py_LIMITED_API +#ifndef Py_PYTIME_H +#define Py_PYTIME_H + +struct timeval; + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to time related +functions and constants +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#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). */ +typedef int64_t _PyTime_t; +#define _PyTime_MIN INT64_MIN +#define _PyTime_MAX INT64_MAX + +typedef enum { + /* Round towards minus infinity (-inf). + For example, used to read a clock. */ + _PyTime_ROUND_FLOOR=0, + /* Round towards infinity (+inf). + For example, used for timeout to wait "at least" N seconds. */ + _PyTime_ROUND_CEILING=1, + /* Round to nearest with ties going to nearest even integer. + For example, used to round from a Python float. */ + _PyTime_ROUND_HALF_EVEN=2, + /* Round away from zero + For example, used for timeout. _PyTime_ROUND_CEILING rounds + -1e-9 to 0 milliseconds which causes bpo-31786 issue. + _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps + the timeout sign as expected. select.poll(timeout) must block + for negative values." */ + _PyTime_ROUND_UP=3, + /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be + used for timeouts. */ + _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP +} _PyTime_round_t; + + +/* Convert a time_t to a PyLong. */ +PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( + time_t sec); + +/* Convert a PyLong to a time_t. */ +PyAPI_FUNC(time_t) _PyLong_AsTime_t( + PyObject *obj); + +/* Convert a number of seconds, int or float, to time_t. */ +PyAPI_FUNC(int) _PyTime_ObjectToTime_t( + PyObject *obj, + time_t *sec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timeval structure. + usec is in the range [0; 999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimeval( + PyObject *obj, + time_t *sec, + long *usec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timespec structure. + nsec is in the range [0; 999999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimespec( + PyObject *obj, + time_t *sec, + long *nsec, + _PyTime_round_t); + + +/* Create a timestamp from a number of seconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); + +/* Macro to create a timestamp from a number of seconds, no integer overflow. + Only use the macro for small values, prefer _PyTime_FromSeconds(). */ +#define _PYTIME_FROMSECONDS(seconds) \ + ((_PyTime_t)(seconds) * (1000 * 1000 * 1000)) + +/* Create a timestamp from a number of nanoseconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); + +/* Create a timestamp from nanoseconds (Python int). */ +PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, + PyObject *obj); + +/* Convert a number of seconds (Python float or int) to a timestamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds as a C double. */ +PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); + +/* Convert timestamp to a number of milliseconds (10^-3 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of microseconds (10^-6 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int + object. */ +PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t); + +/* Create a timestamp from a timeval structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); + +/* Convert a timestamp to a timeval structure (microsecond resolution). + tv_usec is always positive. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Similar to _PyTime_AsTimeval(), but don't raise an exception on error. */ +PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds (secs) and microseconds (us). + us is always positive. This function is similar to _PyTime_AsTimeval() + except that secs is always a time_t type, whereas the timeval structure + uses a C long for tv_sec on Windows. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( + _PyTime_t t, + time_t *secs, + int *us, + _PyTime_round_t round); + +#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) +/* Create a timestamp from a timespec structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts); + +/* Convert a timestamp to a timespec structure (nanosecond resolution). + tv_nsec is always positive. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts); +#endif + +/* Compute ticks * mul / div. + The caller must ensure that ((div - 1) * mul) cannot overflow. */ +PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks, + _PyTime_t mul, + _PyTime_t div); + +/* Structure used by time.get_clock_info() */ +typedef struct { + const char *implementation; + int monotonic; + int adjustable; + double resolution; +} _Py_clock_info_t; + +/* Get the current time from the system clock. + + If the internal clock fails, silently ignore the error and return 0. + On integer overflow, silently ignore the overflow and truncated the clock to + _PyTime_MIN or _PyTime_MAX. + + Use _PyTime_GetSystemClockWithInfo() to check for failure. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); + +/* Get the current time from the system clock. + * On success, set *t and *info (if not NULL), and return 0. + * On error, raise an exception and return -1. + */ +PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + If the internal clock fails, silently ignore the error and return 0. + On integer overflow, silently ignore the overflow and truncated the clock to + _PyTime_MIN or _PyTime_MAX. + + Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + + +/* Converts a timestamp to the Gregorian time, using the local time zone. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); + +/* Converts a timestamp to the Gregorian time, assuming UTC. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + If the internal clock fails, silently ignore the error and return 0. + On integer overflow, silently ignore the overflow and truncated the clock to + _PyTime_MIN or _PyTime_MAX. + + Use _PyTime_GetPerfCounterWithInfo() to check for failure. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + +#ifdef __cplusplus +} +#endif + +#endif /* Py_PYTIME_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/cpython/sysmodule.h b/contrib/tools/python3/src/Include/cpython/sysmodule.h index 1802b5b3000..fc4c899b3fe 100644 --- a/contrib/tools/python3/src/Include/cpython/sysmodule.h +++ b/contrib/tools/python3/src/Include/cpython/sysmodule.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); @@ -18,7 +14,3 @@ PyAPI_FUNC(int) PySys_Audit( const char *argFormat, ...); PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/traceback.h b/contrib/tools/python3/src/Include/cpython/traceback.h index 837470c3ba2..aac5b42c344 100644 --- a/contrib/tools/python3/src/Include/cpython/traceback.h +++ b/contrib/tools/python3/src/Include/cpython/traceback.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct _traceback { PyObject_HEAD struct _traceback *tb_next; @@ -16,7 +12,3 @@ typedef struct _traceback { PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/tupleobject.h b/contrib/tools/python3/src/Include/cpython/tupleobject.h index 1565f2a5c3d..7cada8848c4 100644 --- a/contrib/tools/python3/src/Include/cpython/tupleobject.h +++ b/contrib/tools/python3/src/Include/cpython/tupleobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { PyObject_VAR_HEAD /* ob_item contains space for 'ob_size' elements. @@ -27,10 +23,6 @@ PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); #define PyTuple_GET_ITEM(op, i) (_PyTuple_CAST(op)->ob_item[i]) /* Macro, *only* to be used to fill in brand new tuples */ -#define PyTuple_SET_ITEM(op, i, v) (_PyTuple_CAST(op)->ob_item[i] = v) +#define PyTuple_SET_ITEM(op, i, v) ((void)(_PyTuple_CAST(op)->ob_item[i] = v)) PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Include/cpython/unicodeobject.h b/contrib/tools/python3/src/Include/cpython/unicodeobject.h index 1b460c9f189..0761f01efb4 100644 --- a/contrib/tools/python3/src/Include/cpython/unicodeobject.h +++ b/contrib/tools/python3/src/Include/cpython/unicodeobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Py_UNICODE was the native Unicode storage format (code unit) used by Python and represents a single Unicode element in the Unicode type. With PEP 393, Py_UNICODE is deprecated and replaced with a @@ -15,6 +11,10 @@ extern "C" { /* --- 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 @@ -583,7 +583,7 @@ Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( /* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string contains null characters. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( +PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( PyObject *unicode /* Unicode object */ ); @@ -597,9 +597,6 @@ Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( Py_ssize_t *size /* location where to save the length */ ); -/* Get the maximum ordinal for a Unicode character. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); - /* --- _PyUnicodeWriter API ----------------------------------------------- */ @@ -729,26 +726,6 @@ PyAPI_FUNC(int) _PyUnicode_FormatAdvancedWriter( /* --- Manage the default encoding ---------------------------------------- */ -/* Returns a pointer to the default encoding (UTF-8) of the - Unicode object unicode and the size of the encoded representation - in bytes stored in *size. - - In case of an error, no *size is set. - - This function caches the UTF-8 encoded string in the unicodeobject - and subsequent calls will return the same string. The memory is released - when the unicodeobject is deallocated. - - _PyUnicode_AsStringAndSize is a #define for PyUnicode_AsUTF8AndSize to - support the previous internal function with the same behaviour. -*/ - -PyAPI_FUNC(const char *) PyUnicode_AsUTF8AndSize( - PyObject *unicode, - Py_ssize_t *size); - -#define _PyUnicode_AsStringAndSize PyUnicode_AsUTF8AndSize - /* Returns a pointer to the default encoding (UTF-8) of the Unicode object unicode. @@ -864,6 +841,7 @@ PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeStateful( const char *errors, /* error handling */ Py_ssize_t *consumed /* bytes consumed */ ); + /* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape chars. */ PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal( @@ -1176,53 +1154,8 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha( Py_UCS4 ch /* Unicode character */ ); -Py_DEPRECATED(3.3) PyAPI_FUNC(size_t) Py_UNICODE_strlen( - const Py_UNICODE *u - ); - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcpy( - Py_UNICODE *s1, - const Py_UNICODE *s2); - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcat( - Py_UNICODE *s1, const Py_UNICODE *s2); - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy( - Py_UNICODE *s1, - const Py_UNICODE *s2, - size_t n); - -Py_DEPRECATED(3.3) PyAPI_FUNC(int) Py_UNICODE_strcmp( - const Py_UNICODE *s1, - const Py_UNICODE *s2 - ); - -Py_DEPRECATED(3.3) PyAPI_FUNC(int) Py_UNICODE_strncmp( - const Py_UNICODE *s1, - const Py_UNICODE *s2, - size_t n - ); - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( - const Py_UNICODE *s, - Py_UNICODE c - ); - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( - const Py_UNICODE *s, - Py_UNICODE c - ); - PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); -/* Create a copy of a unicode string ending with a nul character. Return NULL - and raise a MemoryError exception on memory allocation failure, otherwise - return a new allocated buffer (use PyMem_Free() to free the buffer). */ - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( - PyObject *unicode - ); - /* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); @@ -1230,8 +1163,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 *); -PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *); +PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *); -#ifdef __cplusplus -} -#endif +PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *); diff --git a/contrib/tools/python3/src/Include/datetime.h b/contrib/tools/python3/src/Include/datetime.h index 5d9f2558f92..bb565201a16 100644 --- a/contrib/tools/python3/src/Include/datetime.h +++ b/contrib/tools/python3/src/Include/datetime.h @@ -115,6 +115,10 @@ typedef struct /* Apply for date and datetime instances. */ + +// 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]) @@ -128,6 +132,8 @@ typedef struct (((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]) @@ -138,6 +144,8 @@ typedef struct (((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) diff --git a/contrib/tools/python3/src/Include/descrobject.h b/contrib/tools/python3/src/Include/descrobject.h index ead269d1d2f..703bc8fd6df 100644 --- a/contrib/tools/python3/src/Include/descrobject.h +++ b/contrib/tools/python3/src/Include/descrobject.h @@ -93,7 +93,7 @@ PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); -#define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL) +PyAPI_FUNC(int) PyDescr_IsData(PyObject *); #endif PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); diff --git a/contrib/tools/python3/src/Include/dictobject.h b/contrib/tools/python3/src/Include/dictobject.h index c88b0aa0a5d..da5a36ba07f 100644 --- a/contrib/tools/python3/src/Include/dictobject.h +++ b/contrib/tools/python3/src/Include/dictobject.h @@ -57,6 +57,9 @@ PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 +PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *); +#endif /* Dictionary (keys, values, items) views */ diff --git a/contrib/tools/python3/src/Include/errcode.h b/contrib/tools/python3/src/Include/errcode.h index 790518b8b77..54ae929bf25 100644 --- a/contrib/tools/python3/src/Include/errcode.h +++ b/contrib/tools/python3/src/Include/errcode.h @@ -30,6 +30,7 @@ extern "C" { #define E_EOLS 24 /* EOL in single-quoted string */ #define E_LINECONT 25 /* Unexpected characters after a line continuation */ #define E_BADSINGLE 27 /* Ill-formed single statement input */ +#define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */ #ifdef __cplusplus } diff --git a/contrib/tools/python3/src/Include/eval.h b/contrib/tools/python3/src/Include/eval.h index 2c1c2d0549a..eda28df8f65 100644 --- a/contrib/tools/python3/src/Include/eval.h +++ b/contrib/tools/python3/src/Include/eval.h @@ -18,16 +18,6 @@ PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co, PyObject *kwdefs, PyObject *closure); #ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyEval_EvalCodeWithName( - PyObject *co, - PyObject *globals, PyObject *locals, - PyObject *const *args, Py_ssize_t argcount, - PyObject *const *kwnames, PyObject *const *kwargs, - Py_ssize_t kwcount, int kwstep, - PyObject *const *defs, Py_ssize_t defcount, - PyObject *kwdefs, PyObject *closure, - PyObject *name, PyObject *qualname); - PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); #endif diff --git a/contrib/tools/python3/src/Include/fileutils.h b/contrib/tools/python3/src/Include/fileutils.h index 12bd071c49c..16f3b635dee 100644 --- a/contrib/tools/python3/src/Include/fileutils.h +++ b/contrib/tools/python3/src/Include/fileutils.h @@ -12,10 +12,6 @@ PyAPI_FUNC(wchar_t *) Py_DecodeLocale( PyAPI_FUNC(char*) Py_EncodeLocale( const wchar_t *text, size_t *error_pos); - -PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( - const wchar_t *text, - size_t *error_pos); #endif #ifndef Py_LIMITED_API diff --git a/contrib/tools/python3/src/Include/funcobject.h b/contrib/tools/python3/src/Include/funcobject.h index c5cc9d261a3..d7acd18c651 100644 --- a/contrib/tools/python3/src/Include/funcobject.h +++ b/contrib/tools/python3/src/Include/funcobject.h @@ -7,6 +7,21 @@ extern "C" { #endif + +#define COMMON_FIELDS(PREFIX) \ + PyObject *PREFIX ## globals; \ + PyObject *PREFIX ## builtins; \ + PyObject *PREFIX ## name; \ + PyObject *PREFIX ## qualname; \ + PyObject *PREFIX ## code; /* A code object, the __code__ attribute */ \ + PyObject *PREFIX ## defaults; /* NULL or a tuple */ \ + PyObject *PREFIX ## kwdefaults; /* NULL or a dict */ \ + PyObject *PREFIX ## closure; /* NULL or a tuple of cell objects */ + +typedef struct { + COMMON_FIELDS(fc_) +} PyFrameConstructor; + /* Function objects and code objects should not be confused with each other: * * Function objects are created by the execution of the 'def' statement. @@ -20,18 +35,12 @@ extern "C" { typedef struct { PyObject_HEAD - PyObject *func_code; /* A code object, the __code__ attribute */ - PyObject *func_globals; /* A dictionary (other mappings won't do) */ - PyObject *func_defaults; /* NULL or a tuple */ - PyObject *func_kwdefaults; /* NULL or a dict */ - PyObject *func_closure; /* NULL or a tuple of cell objects */ + COMMON_FIELDS(func_) PyObject *func_doc; /* The __doc__ attribute, can be anything */ - PyObject *func_name; /* The __name__ attribute, a string object */ PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */ 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_qualname; /* The qualified name */ vectorcallfunc vectorcall; /* Invariant: @@ -84,6 +93,9 @@ PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( #define PyFunction_GET_ANNOTATIONS(func) \ (((PyFunctionObject *)func) -> func_annotations) +#define PyFunction_AS_FRAME_CONSTRUCTOR(func) \ + ((PyFrameConstructor *)&((PyFunctionObject *)(func))->func_globals) + /* The classmethod and staticmethod types lives here, too */ PyAPI_DATA(PyTypeObject) PyClassMethod_Type; PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; diff --git a/contrib/tools/python3/src/Include/genobject.h b/contrib/tools/python3/src/Include/genobject.h index 8ffd15646f0..e965334a014 100644 --- a/contrib/tools/python3/src/Include/genobject.h +++ b/contrib/tools/python3/src/Include/genobject.h @@ -9,6 +9,7 @@ extern "C" { #endif #include "pystate.h" /* _PyErr_StackItem */ +#include "abstract.h" /* PySendResult */ /* _PyGenObject_HEAD defines the initial segment of generator and coroutine objects. */ @@ -16,8 +17,6 @@ extern "C" { PyObject_HEAD \ /* Note: gi_frame can be NULL if the generator is "finished" */ \ PyFrameObject *prefix##_frame; \ - /* True if generator is being executed. */ \ - char prefix##_running; \ /* The code object backing the generator */ \ PyObject *prefix##_code; \ /* List of weak reference. */ \ @@ -43,7 +42,6 @@ PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, PyObject *name, PyObject *qualname); PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); -PyAPI_FUNC(PyObject *) _PyGen_Send(PyGenObject *, PyObject *); PyObject *_PyGen_yf(PyGenObject *); PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); diff --git a/contrib/tools/python3/src/Include/graminit.h b/contrib/tools/python3/src/Include/graminit.h deleted file mode 100644 index d1027b7a743..00000000000 --- a/contrib/tools/python3/src/Include/graminit.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Generated by Parser/pgen */ - -#define single_input 256 -#define file_input 257 -#define eval_input 258 -#define decorator 259 -#define decorators 260 -#define decorated 261 -#define async_funcdef 262 -#define funcdef 263 -#define parameters 264 -#define typedargslist 265 -#define tfpdef 266 -#define varargslist 267 -#define vfpdef 268 -#define stmt 269 -#define simple_stmt 270 -#define small_stmt 271 -#define expr_stmt 272 -#define annassign 273 -#define testlist_star_expr 274 -#define augassign 275 -#define del_stmt 276 -#define pass_stmt 277 -#define flow_stmt 278 -#define break_stmt 279 -#define continue_stmt 280 -#define return_stmt 281 -#define yield_stmt 282 -#define raise_stmt 283 -#define import_stmt 284 -#define import_name 285 -#define import_from 286 -#define import_as_name 287 -#define dotted_as_name 288 -#define import_as_names 289 -#define dotted_as_names 290 -#define dotted_name 291 -#define global_stmt 292 -#define nonlocal_stmt 293 -#define assert_stmt 294 -#define compound_stmt 295 -#define async_stmt 296 -#define if_stmt 297 -#define while_stmt 298 -#define for_stmt 299 -#define try_stmt 300 -#define with_stmt 301 -#define with_item 302 -#define except_clause 303 -#define suite 304 -#define namedexpr_test 305 -#define test 306 -#define test_nocond 307 -#define lambdef 308 -#define lambdef_nocond 309 -#define or_test 310 -#define and_test 311 -#define not_test 312 -#define comparison 313 -#define comp_op 314 -#define star_expr 315 -#define expr 316 -#define xor_expr 317 -#define and_expr 318 -#define shift_expr 319 -#define arith_expr 320 -#define term 321 -#define factor 322 -#define power 323 -#define atom_expr 324 -#define atom 325 -#define testlist_comp 326 -#define trailer 327 -#define subscriptlist 328 -#define subscript 329 -#define sliceop 330 -#define exprlist 331 -#define testlist 332 -#define dictorsetmaker 333 -#define classdef 334 -#define arglist 335 -#define argument 336 -#define comp_iter 337 -#define sync_comp_for 338 -#define comp_for 339 -#define comp_if 340 -#define encoding_decl 341 -#define yield_expr 342 -#define yield_arg 343 -#define func_body_suite 344 -#define func_type_input 345 -#define func_type 346 -#define typelist 347 diff --git a/contrib/tools/python3/src/Include/grammar.h b/contrib/tools/python3/src/Include/grammar.h deleted file mode 100644 index 4b66b1e9b97..00000000000 --- a/contrib/tools/python3/src/Include/grammar.h +++ /dev/null @@ -1,77 +0,0 @@ - -/* Grammar interface */ - -#ifndef Py_GRAMMAR_H -#define Py_GRAMMAR_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "bitset.h" /* Sigh... */ - -/* A label of an arc */ - -typedef struct { - int lb_type; - const char *lb_str; -} label; - -#define EMPTY 0 /* Label number 0 is by definition the empty label */ - -/* A list of labels */ - -typedef struct { - int ll_nlabels; - const label *ll_label; -} labellist; - -/* An arc from one state to another */ - -typedef struct { - short a_lbl; /* Label of this arc */ - short a_arrow; /* State where this arc goes to */ -} arc; - -/* A state in a DFA */ - -typedef struct { - int s_narcs; - const arc *s_arc; /* Array of arcs */ - - /* Optional accelerators */ - int s_lower; /* Lowest label index */ - int s_upper; /* Highest label index */ - int *s_accel; /* Accelerator */ - int s_accept; /* Nonzero for accepting state */ -} state; - -/* A DFA */ - -typedef struct { - int d_type; /* Non-terminal this represents */ - char *d_name; /* For printing */ - int d_nstates; - state *d_state; /* Array of states */ - bitset d_first; -} dfa; - -/* A grammar */ - -typedef struct { - int g_ndfas; - const dfa *g_dfa; /* Array of DFAs */ - const labellist g_ll; - int g_start; /* Start symbol of the grammar */ - int g_accel; /* Set if accelerators present */ -} grammar; - -/* FUNCTIONS */ -const dfa *PyGrammar_FindDFA(grammar *g, int type); -const char *PyGrammar_LabelRepr(label *lb); -void PyGrammar_AddAccelerators(grammar *g); -void PyGrammar_RemoveAccelerators(grammar *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_GRAMMAR_H */ diff --git a/contrib/tools/python3/src/Include/internal/pegen_interface.h b/contrib/tools/python3/src/Include/internal/pegen_interface.h deleted file mode 100644 index ee4c77ec006..00000000000 --- a/contrib/tools/python3/src/Include/internal/pegen_interface.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef Py_PEGENINTERFACE -#define Py_PEGENINTERFACE -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "Python.h" -#include "Python-ast.h" - -PyAPI_FUNC(mod_ty) PyPegen_ASTFromString( - const char *str, - const char *filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(mod_ty) PyPegen_ASTFromStringObject( - const char *str, - PyObject* filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(mod_ty) PyPegen_ASTFromFileObject( - FILE *fp, - PyObject *filename_ob, - int mode, - const char *enc, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); -PyAPI_FUNC(mod_ty) PyPegen_ASTFromFilename( - const char *filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PEGENINTERFACE*/ diff --git a/contrib/tools/python3/src/Include/internal/pycore_asdl.h b/contrib/tools/python3/src/Include/internal/pycore_asdl.h new file mode 100644 index 00000000000..c0b07c31810 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_asdl.h @@ -0,0 +1,112 @@ +#ifndef Py_INTERNAL_ASDL_H +#define Py_INTERNAL_ASDL_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pyarena.h" // _PyArena_Malloc() + +typedef PyObject * identifier; +typedef PyObject * string; +typedef PyObject * object; +typedef PyObject * constant; + +/* It would be nice if the code generated by asdl_c.py was completely + independent of Python, but it is a goal the requires too much work + at this stage. So, for example, I'll represent identifiers as + interned Python strings. +*/ + +#define _ASDL_SEQ_HEAD \ + Py_ssize_t size; \ + void **elements; + +typedef struct { + _ASDL_SEQ_HEAD +} asdl_seq; + +typedef struct { + _ASDL_SEQ_HEAD + void *typed_elements[1]; +} asdl_generic_seq; + +typedef struct { + _ASDL_SEQ_HEAD + PyObject *typed_elements[1]; +} asdl_identifier_seq; + +typedef struct { + _ASDL_SEQ_HEAD + int typed_elements[1]; +} asdl_int_seq; + +asdl_generic_seq *_Py_asdl_generic_seq_new(Py_ssize_t size, PyArena *arena); +asdl_identifier_seq *_Py_asdl_identifier_seq_new(Py_ssize_t size, PyArena *arena); +asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena); + + +#define GENERATE_ASDL_SEQ_CONSTRUCTOR(NAME, TYPE) \ +asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *arena) \ +{ \ + asdl_ ## NAME ## _seq *seq = NULL; \ + size_t n; \ + /* check size is sane */ \ + if (size < 0 || \ + (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { \ + PyErr_NoMemory(); \ + return NULL; \ + } \ + n = (size ? (sizeof(TYPE *) * (size - 1)) : 0); \ + /* check if size can be added safely */ \ + if (n > SIZE_MAX - sizeof(asdl_ ## NAME ## _seq)) { \ + PyErr_NoMemory(); \ + return NULL; \ + } \ + n += sizeof(asdl_ ## NAME ## _seq); \ + seq = (asdl_ ## NAME ## _seq *)_PyArena_Malloc(arena, n); \ + if (!seq) { \ + PyErr_NoMemory(); \ + return NULL; \ + } \ + memset(seq, 0, n); \ + seq->size = size; \ + seq->elements = (void**)seq->typed_elements; \ + return seq; \ +} + +#define asdl_seq_GET_UNTYPED(S, I) (S)->elements[(I)] +#define asdl_seq_GET(S, I) (S)->typed_elements[(I)] +#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) + +#ifdef Py_DEBUG +# define asdl_seq_SET(S, I, V) \ + do { \ + Py_ssize_t _asdl_i = (I); \ + assert((S) != NULL); \ + assert(0 <= _asdl_i && _asdl_i < (S)->size); \ + (S)->typed_elements[_asdl_i] = (V); \ + } while (0) +#else +# define asdl_seq_SET(S, I, V) (S)->typed_elements[I] = (V) +#endif + +#ifdef Py_DEBUG +# define asdl_seq_SET_UNTYPED(S, I, V) \ + do { \ + Py_ssize_t _asdl_i = (I); \ + assert((S) != NULL); \ + assert(0 <= _asdl_i && _asdl_i < (S)->size); \ + (S)->elements[_asdl_i] = (V); \ + } while (0) +#else +# define asdl_seq_SET_UNTYPED(S, I, V) (S)->elements[I] = (V) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_ASDL_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_ast.h b/contrib/tools/python3/src/Include/internal/pycore_ast.h new file mode 100644 index 00000000000..ebb6a90087b --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_ast.h @@ -0,0 +1,855 @@ +// File automatically generated by Parser/asdl_c.py. + +#ifndef Py_INTERNAL_AST_H +#define Py_INTERNAL_AST_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_asdl.h" + +typedef struct _mod *mod_ty; + +typedef struct _stmt *stmt_ty; + +typedef struct _expr *expr_ty; + +typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty; + +typedef enum _boolop { And=1, Or=2 } boolop_ty; + +typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, + LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, + FloorDiv=13 } operator_ty; + +typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; + +typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, + In=9, NotIn=10 } cmpop_ty; + +typedef struct _comprehension *comprehension_ty; + +typedef struct _excepthandler *excepthandler_ty; + +typedef struct _arguments *arguments_ty; + +typedef struct _arg *arg_ty; + +typedef struct _keyword *keyword_ty; + +typedef struct _alias *alias_ty; + +typedef struct _withitem *withitem_ty; + +typedef struct _match_case *match_case_ty; + +typedef struct _pattern *pattern_ty; + +typedef struct _type_ignore *type_ignore_ty; + + +typedef struct { + _ASDL_SEQ_HEAD + mod_ty typed_elements[1]; +} asdl_mod_seq; + +asdl_mod_seq *_Py_asdl_mod_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + stmt_ty typed_elements[1]; +} asdl_stmt_seq; + +asdl_stmt_seq *_Py_asdl_stmt_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + expr_ty typed_elements[1]; +} asdl_expr_seq; + +asdl_expr_seq *_Py_asdl_expr_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + comprehension_ty typed_elements[1]; +} asdl_comprehension_seq; + +asdl_comprehension_seq *_Py_asdl_comprehension_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + excepthandler_ty typed_elements[1]; +} asdl_excepthandler_seq; + +asdl_excepthandler_seq *_Py_asdl_excepthandler_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + arguments_ty typed_elements[1]; +} asdl_arguments_seq; + +asdl_arguments_seq *_Py_asdl_arguments_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + arg_ty typed_elements[1]; +} asdl_arg_seq; + +asdl_arg_seq *_Py_asdl_arg_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + keyword_ty typed_elements[1]; +} asdl_keyword_seq; + +asdl_keyword_seq *_Py_asdl_keyword_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + alias_ty typed_elements[1]; +} asdl_alias_seq; + +asdl_alias_seq *_Py_asdl_alias_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + withitem_ty typed_elements[1]; +} asdl_withitem_seq; + +asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + match_case_ty typed_elements[1]; +} asdl_match_case_seq; + +asdl_match_case_seq *_Py_asdl_match_case_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + pattern_ty typed_elements[1]; +} asdl_pattern_seq; + +asdl_pattern_seq *_Py_asdl_pattern_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + type_ignore_ty typed_elements[1]; +} asdl_type_ignore_seq; + +asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena + *arena); + + +enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, + FunctionType_kind=4}; +struct _mod { + enum _mod_kind kind; + union { + struct { + asdl_stmt_seq *body; + asdl_type_ignore_seq *type_ignores; + } Module; + + struct { + asdl_stmt_seq *body; + } Interactive; + + struct { + expr_ty body; + } Expression; + + struct { + asdl_expr_seq *argtypes; + expr_ty returns; + } FunctionType; + + } v; +}; + +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, + Assert_kind=18, Import_kind=19, ImportFrom_kind=20, + Global_kind=21, Nonlocal_kind=22, Expr_kind=23, Pass_kind=24, + Break_kind=25, Continue_kind=26}; +struct _stmt { + enum _stmt_kind kind; + union { + struct { + identifier name; + arguments_ty args; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; + expr_ty returns; + string type_comment; + } FunctionDef; + + struct { + identifier name; + arguments_ty args; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; + expr_ty returns; + string type_comment; + } AsyncFunctionDef; + + struct { + identifier name; + asdl_expr_seq *bases; + asdl_keyword_seq *keywords; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; + } ClassDef; + + struct { + expr_ty value; + } Return; + + struct { + asdl_expr_seq *targets; + } Delete; + + struct { + asdl_expr_seq *targets; + expr_ty value; + string type_comment; + } Assign; + + struct { + expr_ty target; + operator_ty op; + expr_ty value; + } AugAssign; + + struct { + expr_ty target; + expr_ty annotation; + expr_ty value; + int simple; + } AnnAssign; + + struct { + expr_ty target; + expr_ty iter; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + string type_comment; + } For; + + struct { + expr_ty target; + expr_ty iter; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + string type_comment; + } AsyncFor; + + struct { + expr_ty test; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + } While; + + struct { + expr_ty test; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + } If; + + struct { + asdl_withitem_seq *items; + asdl_stmt_seq *body; + string type_comment; + } With; + + struct { + asdl_withitem_seq *items; + asdl_stmt_seq *body; + string type_comment; + } AsyncWith; + + struct { + expr_ty subject; + asdl_match_case_seq *cases; + } Match; + + struct { + expr_ty exc; + expr_ty cause; + } Raise; + + struct { + asdl_stmt_seq *body; + asdl_excepthandler_seq *handlers; + asdl_stmt_seq *orelse; + asdl_stmt_seq *finalbody; + } Try; + + struct { + expr_ty test; + expr_ty msg; + } Assert; + + struct { + asdl_alias_seq *names; + } Import; + + struct { + identifier module; + asdl_alias_seq *names; + int level; + } ImportFrom; + + struct { + asdl_identifier_seq *names; + } Global; + + struct { + asdl_identifier_seq *names; + } Nonlocal; + + struct { + expr_ty value; + } Expr; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4, + Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8, + ListComp_kind=9, SetComp_kind=10, DictComp_kind=11, + GeneratorExp_kind=12, Await_kind=13, Yield_kind=14, + YieldFrom_kind=15, Compare_kind=16, Call_kind=17, + FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20, + Attribute_kind=21, Subscript_kind=22, Starred_kind=23, + Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27}; +struct _expr { + enum _expr_kind kind; + union { + struct { + boolop_ty op; + asdl_expr_seq *values; + } BoolOp; + + struct { + expr_ty target; + expr_ty value; + } NamedExpr; + + struct { + expr_ty left; + operator_ty op; + expr_ty right; + } BinOp; + + struct { + unaryop_ty op; + expr_ty operand; + } UnaryOp; + + struct { + arguments_ty args; + expr_ty body; + } Lambda; + + struct { + expr_ty test; + expr_ty body; + expr_ty orelse; + } IfExp; + + struct { + asdl_expr_seq *keys; + asdl_expr_seq *values; + } Dict; + + struct { + asdl_expr_seq *elts; + } Set; + + struct { + expr_ty elt; + asdl_comprehension_seq *generators; + } ListComp; + + struct { + expr_ty elt; + asdl_comprehension_seq *generators; + } SetComp; + + struct { + expr_ty key; + expr_ty value; + asdl_comprehension_seq *generators; + } DictComp; + + struct { + expr_ty elt; + asdl_comprehension_seq *generators; + } GeneratorExp; + + struct { + expr_ty value; + } Await; + + struct { + expr_ty value; + } Yield; + + struct { + expr_ty value; + } YieldFrom; + + struct { + expr_ty left; + asdl_int_seq *ops; + asdl_expr_seq *comparators; + } Compare; + + struct { + expr_ty func; + asdl_expr_seq *args; + asdl_keyword_seq *keywords; + } Call; + + struct { + expr_ty value; + int conversion; + expr_ty format_spec; + } FormattedValue; + + struct { + asdl_expr_seq *values; + } JoinedStr; + + struct { + constant value; + string kind; + } Constant; + + struct { + expr_ty value; + identifier attr; + expr_context_ty ctx; + } Attribute; + + struct { + expr_ty value; + expr_ty slice; + expr_context_ty ctx; + } Subscript; + + struct { + expr_ty value; + expr_context_ty ctx; + } Starred; + + struct { + identifier id; + expr_context_ty ctx; + } Name; + + struct { + asdl_expr_seq *elts; + expr_context_ty ctx; + } List; + + struct { + asdl_expr_seq *elts; + expr_context_ty ctx; + } Tuple; + + struct { + expr_ty lower; + expr_ty upper; + expr_ty step; + } Slice; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _comprehension { + expr_ty target; + expr_ty iter; + asdl_expr_seq *ifs; + int is_async; +}; + +enum _excepthandler_kind {ExceptHandler_kind=1}; +struct _excepthandler { + enum _excepthandler_kind kind; + union { + struct { + expr_ty type; + identifier name; + asdl_stmt_seq *body; + } ExceptHandler; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _arguments { + asdl_arg_seq *posonlyargs; + asdl_arg_seq *args; + arg_ty vararg; + asdl_arg_seq *kwonlyargs; + asdl_expr_seq *kw_defaults; + arg_ty kwarg; + asdl_expr_seq *defaults; +}; + +struct _arg { + identifier arg; + expr_ty annotation; + string type_comment; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _keyword { + identifier arg; + expr_ty value; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _alias { + identifier name; + identifier asname; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _withitem { + expr_ty context_expr; + expr_ty optional_vars; +}; + +struct _match_case { + pattern_ty pattern; + expr_ty guard; + asdl_stmt_seq *body; +}; + +enum _pattern_kind {MatchValue_kind=1, MatchSingleton_kind=2, + MatchSequence_kind=3, MatchMapping_kind=4, + MatchClass_kind=5, MatchStar_kind=6, MatchAs_kind=7, + MatchOr_kind=8}; +struct _pattern { + enum _pattern_kind kind; + union { + struct { + expr_ty value; + } MatchValue; + + struct { + constant value; + } MatchSingleton; + + struct { + asdl_pattern_seq *patterns; + } MatchSequence; + + struct { + asdl_expr_seq *keys; + asdl_pattern_seq *patterns; + identifier rest; + } MatchMapping; + + struct { + expr_ty cls; + asdl_pattern_seq *patterns; + asdl_identifier_seq *kwd_attrs; + asdl_pattern_seq *kwd_patterns; + } MatchClass; + + struct { + identifier name; + } MatchStar; + + struct { + pattern_ty pattern; + identifier name; + } MatchAs; + + struct { + asdl_pattern_seq *patterns; + } MatchOr; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +enum _type_ignore_kind {TypeIgnore_kind=1}; +struct _type_ignore { + enum _type_ignore_kind kind; + union { + struct { + int lineno; + string tag; + } TypeIgnore; + + } v; +}; + + +// Note: these macros affect function definitions, not only call sites. +mod_ty _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, + PyArena *arena); +mod_ty _PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena); +mod_ty _PyAST_Expression(expr_ty body, PyArena *arena); +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); +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); +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); +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 + end_lineno, int end_col_offset, PyArena *arena); +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_AugAssign(expr_ty target, operator_ty op, expr_ty value, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +stmt_ty _PyAST_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int + simple, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +stmt_ty _PyAST_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, + asdl_stmt_seq * orelse, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +stmt_ty _PyAST_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, + asdl_stmt_seq * orelse, string type_comment, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +stmt_ty _PyAST_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * + orelse, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +stmt_ty _PyAST_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +stmt_ty _PyAST_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string + type_comment, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +stmt_ty _PyAST_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, + string type_comment, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +stmt_ty _PyAST_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, + asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +stmt_ty _PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +stmt_ty _PyAST_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +stmt_ty _PyAST_Pass(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +stmt_ty _PyAST_Break(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +stmt_ty _PyAST_Continue(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +expr_ty _PyAST_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_NamedExpr(expr_ty target, expr_ty value, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +expr_ty _PyAST_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +expr_ty _PyAST_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_Lambda(arguments_ty args, expr_ty body, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +expr_ty _PyAST_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_Set(asdl_expr_seq * elts, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +expr_ty _PyAST_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +expr_ty _PyAST_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +expr_ty _PyAST_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * + generators, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +expr_ty _PyAST_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +expr_ty _PyAST_Await(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +expr_ty _PyAST_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +expr_ty _PyAST_YieldFrom(expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +expr_ty _PyAST_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * + comparators, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +expr_ty _PyAST_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * + keywords, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +expr_ty _PyAST_FormattedValue(expr_ty value, int conversion, expr_ty + format_spec, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +expr_ty _PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +expr_ty _PyAST_Constant(constant value, string kind, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +expr_ty _PyAST_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +expr_ty _PyAST_Starred(expr_ty value, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_Name(identifier id, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +expr_ty _PyAST_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +comprehension_ty _PyAST_comprehension(expr_ty target, expr_ty iter, + asdl_expr_seq * ifs, int is_async, + PyArena *arena); +excepthandler_ty _PyAST_ExceptHandler(expr_ty type, identifier name, + asdl_stmt_seq * body, int lineno, int + col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +arguments_ty _PyAST_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, + arg_ty vararg, asdl_arg_seq * kwonlyargs, + asdl_expr_seq * kw_defaults, arg_ty kwarg, + asdl_expr_seq * defaults, PyArena *arena); +arg_ty _PyAST_arg(identifier arg, expr_ty annotation, string type_comment, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +keyword_ty _PyAST_keyword(identifier arg, expr_ty value, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +alias_ty _PyAST_alias(identifier name, identifier asname, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +withitem_ty _PyAST_withitem(expr_ty context_expr, expr_ty optional_vars, + PyArena *arena); +match_case_ty _PyAST_match_case(pattern_ty pattern, expr_ty guard, + asdl_stmt_seq * body, PyArena *arena); +pattern_ty _PyAST_MatchValue(expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +pattern_ty _PyAST_MatchSingleton(constant value, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena + *arena); +pattern_ty _PyAST_MatchSequence(asdl_pattern_seq * patterns, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +pattern_ty _PyAST_MatchMapping(asdl_expr_seq * keys, asdl_pattern_seq * + patterns, identifier rest, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +pattern_ty _PyAST_MatchClass(expr_ty cls, asdl_pattern_seq * patterns, + asdl_identifier_seq * kwd_attrs, asdl_pattern_seq + * kwd_patterns, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +pattern_ty _PyAST_MatchStar(identifier name, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +pattern_ty _PyAST_MatchAs(pattern_ty pattern, identifier name, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +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); + + +PyObject* PyAST_mod2obj(mod_ty t); +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); +int PyAST_Check(PyObject* obj); + +extern int _PyAST_Validate(mod_ty); + +/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */ +extern PyObject* _PyAST_ExprAsUnicode(expr_ty); + +/* Return the borrowed reference to the first literal string in the + sequence of statements or NULL if it doesn't start from a literal string. + Doesn't set exception. */ +extern PyObject* _PyAST_GetDocString(asdl_stmt_seq *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_AST_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_ast_state.h b/contrib/tools/python3/src/Include/internal/pycore_ast_state.h new file mode 100644 index 00000000000..882cd09c006 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_ast_state.h @@ -0,0 +1,255 @@ +// File automatically generated by Parser/asdl_c.py. + +#ifndef Py_INTERNAL_AST_STATE_H +#define Py_INTERNAL_AST_STATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +struct ast_state { + int initialized; + PyObject *AST_type; + PyObject *Add_singleton; + PyObject *Add_type; + PyObject *And_singleton; + PyObject *And_type; + PyObject *AnnAssign_type; + PyObject *Assert_type; + PyObject *Assign_type; + PyObject *AsyncFor_type; + PyObject *AsyncFunctionDef_type; + PyObject *AsyncWith_type; + PyObject *Attribute_type; + PyObject *AugAssign_type; + PyObject *Await_type; + PyObject *BinOp_type; + PyObject *BitAnd_singleton; + PyObject *BitAnd_type; + PyObject *BitOr_singleton; + PyObject *BitOr_type; + PyObject *BitXor_singleton; + PyObject *BitXor_type; + PyObject *BoolOp_type; + PyObject *Break_type; + PyObject *Call_type; + PyObject *ClassDef_type; + PyObject *Compare_type; + PyObject *Constant_type; + PyObject *Continue_type; + PyObject *Del_singleton; + PyObject *Del_type; + PyObject *Delete_type; + PyObject *DictComp_type; + PyObject *Dict_type; + PyObject *Div_singleton; + PyObject *Div_type; + PyObject *Eq_singleton; + PyObject *Eq_type; + PyObject *ExceptHandler_type; + PyObject *Expr_type; + PyObject *Expression_type; + PyObject *FloorDiv_singleton; + PyObject *FloorDiv_type; + PyObject *For_type; + PyObject *FormattedValue_type; + PyObject *FunctionDef_type; + PyObject *FunctionType_type; + PyObject *GeneratorExp_type; + PyObject *Global_type; + PyObject *GtE_singleton; + PyObject *GtE_type; + PyObject *Gt_singleton; + PyObject *Gt_type; + PyObject *IfExp_type; + PyObject *If_type; + PyObject *ImportFrom_type; + PyObject *Import_type; + PyObject *In_singleton; + PyObject *In_type; + PyObject *Interactive_type; + PyObject *Invert_singleton; + PyObject *Invert_type; + PyObject *IsNot_singleton; + PyObject *IsNot_type; + PyObject *Is_singleton; + PyObject *Is_type; + PyObject *JoinedStr_type; + PyObject *LShift_singleton; + PyObject *LShift_type; + PyObject *Lambda_type; + PyObject *ListComp_type; + PyObject *List_type; + PyObject *Load_singleton; + PyObject *Load_type; + PyObject *LtE_singleton; + PyObject *LtE_type; + PyObject *Lt_singleton; + PyObject *Lt_type; + PyObject *MatMult_singleton; + PyObject *MatMult_type; + PyObject *MatchAs_type; + PyObject *MatchClass_type; + PyObject *MatchMapping_type; + PyObject *MatchOr_type; + PyObject *MatchSequence_type; + PyObject *MatchSingleton_type; + PyObject *MatchStar_type; + PyObject *MatchValue_type; + PyObject *Match_type; + PyObject *Mod_singleton; + PyObject *Mod_type; + PyObject *Module_type; + PyObject *Mult_singleton; + PyObject *Mult_type; + PyObject *Name_type; + PyObject *NamedExpr_type; + PyObject *Nonlocal_type; + PyObject *NotEq_singleton; + PyObject *NotEq_type; + PyObject *NotIn_singleton; + PyObject *NotIn_type; + PyObject *Not_singleton; + PyObject *Not_type; + PyObject *Or_singleton; + PyObject *Or_type; + PyObject *Pass_type; + PyObject *Pow_singleton; + PyObject *Pow_type; + PyObject *RShift_singleton; + PyObject *RShift_type; + PyObject *Raise_type; + PyObject *Return_type; + PyObject *SetComp_type; + PyObject *Set_type; + PyObject *Slice_type; + PyObject *Starred_type; + PyObject *Store_singleton; + PyObject *Store_type; + PyObject *Sub_singleton; + PyObject *Sub_type; + PyObject *Subscript_type; + PyObject *Try_type; + PyObject *Tuple_type; + PyObject *TypeIgnore_type; + PyObject *UAdd_singleton; + PyObject *UAdd_type; + PyObject *USub_singleton; + PyObject *USub_type; + PyObject *UnaryOp_type; + PyObject *While_type; + PyObject *With_type; + PyObject *YieldFrom_type; + PyObject *Yield_type; + PyObject *__dict__; + PyObject *__doc__; + PyObject *__match_args__; + PyObject *__module__; + PyObject *_attributes; + PyObject *_fields; + PyObject *alias_type; + PyObject *annotation; + PyObject *arg; + PyObject *arg_type; + PyObject *args; + PyObject *argtypes; + PyObject *arguments_type; + PyObject *asname; + PyObject *ast; + PyObject *attr; + PyObject *bases; + PyObject *body; + PyObject *boolop_type; + PyObject *cases; + PyObject *cause; + PyObject *cls; + PyObject *cmpop_type; + PyObject *col_offset; + PyObject *comparators; + PyObject *comprehension_type; + PyObject *context_expr; + PyObject *conversion; + PyObject *ctx; + PyObject *decorator_list; + PyObject *defaults; + PyObject *elt; + PyObject *elts; + PyObject *end_col_offset; + PyObject *end_lineno; + PyObject *exc; + PyObject *excepthandler_type; + PyObject *expr_context_type; + PyObject *expr_type; + PyObject *finalbody; + PyObject *format_spec; + PyObject *func; + PyObject *generators; + PyObject *guard; + PyObject *handlers; + PyObject *id; + PyObject *ifs; + PyObject *is_async; + PyObject *items; + PyObject *iter; + PyObject *key; + PyObject *keys; + PyObject *keyword_type; + PyObject *keywords; + PyObject *kind; + PyObject *kw_defaults; + PyObject *kwarg; + PyObject *kwd_attrs; + PyObject *kwd_patterns; + PyObject *kwonlyargs; + PyObject *left; + PyObject *level; + PyObject *lineno; + PyObject *lower; + PyObject *match_case_type; + PyObject *mod_type; + PyObject *module; + PyObject *msg; + PyObject *name; + PyObject *names; + PyObject *op; + PyObject *operand; + PyObject *operator_type; + PyObject *ops; + PyObject *optional_vars; + PyObject *orelse; + PyObject *pattern; + PyObject *pattern_type; + PyObject *patterns; + PyObject *posonlyargs; + PyObject *rest; + PyObject *returns; + PyObject *right; + PyObject *simple; + PyObject *slice; + PyObject *step; + PyObject *stmt_type; + PyObject *subject; + PyObject *tag; + PyObject *target; + PyObject *targets; + PyObject *test; + PyObject *type; + PyObject *type_comment; + PyObject *type_ignore_type; + PyObject *type_ignores; + PyObject *unaryop_type; + PyObject *upper; + PyObject *value; + PyObject *values; + PyObject *vararg; + PyObject *withitem_type; +}; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_AST_STATE_H */ + diff --git a/contrib/tools/python3/src/Include/internal/pycore_atomic.h b/contrib/tools/python3/src/Include/internal/pycore_atomic.h index 1d5c5621677..3d42e54464c 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_atomic.h +++ b/contrib/tools/python3/src/Include/internal/pycore_atomic.h @@ -11,8 +11,8 @@ extern "C" { #include "dynamic_annotations.h" /* _Py_ANNOTATE_MEMORY_ORDER */ #include "pyconfig.h" -#if defined(HAVE_STD_ATOMIC) -#include +#ifdef HAVE_STD_ATOMIC +# include #endif @@ -62,7 +62,7 @@ typedef struct _Py_atomic_int { #define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER) -/* Use builtin atomic operations in GCC >= 4.7 */ +// Use builtin atomic operations in GCC >= 4.7 and clang #elif defined(HAVE_BUILTIN_ATOMIC) typedef enum _Py_memory_order { diff --git a/contrib/tools/python3/src/Include/internal/pycore_atomic_funcs.h b/contrib/tools/python3/src/Include/internal/pycore_atomic_funcs.h new file mode 100644 index 00000000000..a708789cea7 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_atomic_funcs.h @@ -0,0 +1,94 @@ +/* Atomic functions: similar to pycore_atomic.h, but don't need + to declare variables as atomic. + + Py_ssize_t type: + + * value = _Py_atomic_size_get(&var) + * _Py_atomic_size_set(&var, value) + + Use sequentially-consistent ordering (__ATOMIC_SEQ_CST memory order): + enforce total ordering with all other atomic functions. +*/ +#ifndef Py_ATOMIC_FUNC_H +#define Py_ATOMIC_FUNC_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#if defined(_MSC_VER) +# include // _InterlockedExchange() +#endif + + +// Use builtin atomic operations in GCC >= 4.7 and clang +#ifdef HAVE_BUILTIN_ATOMIC + +static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) +{ + return __atomic_load_n(var, __ATOMIC_SEQ_CST); +} + +static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) +{ + __atomic_store_n(var, value, __ATOMIC_SEQ_CST); +} + +#elif defined(_MSC_VER) + +static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) +{ +#if SIZEOF_VOID_P == 8 + Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var)); + volatile __int64 *volatile_var = (volatile __int64 *)var; + __int64 old; + do { + old = *volatile_var; + } while(_InterlockedCompareExchange64(volatile_var, old, old) != old); +#else + Py_BUILD_ASSERT(sizeof(long) == sizeof(*var)); + volatile long *volatile_var = (volatile long *)var; + long old; + do { + old = *volatile_var; + } while(_InterlockedCompareExchange(volatile_var, old, old) != old); +#endif + return old; +} + +static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) +{ +#if SIZEOF_VOID_P == 8 + Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var)); + volatile __int64 *volatile_var = (volatile __int64 *)var; + _InterlockedExchange64(volatile_var, value); +#else + Py_BUILD_ASSERT(sizeof(long) == sizeof(*var)); + volatile long *volatile_var = (volatile long *)var; + _InterlockedExchange(volatile_var, value); +#endif +} + +#else +// Fallback implementation using volatile + +static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) +{ + volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var; + return *volatile_var; +} + +static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) +{ + volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var; + *volatile_var = value; +} +#endif + +#ifdef __cplusplus +} +#endif +#endif /* Py_ATOMIC_FUNC_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_bitutils.h b/contrib/tools/python3/src/Include/internal/pycore_bitutils.h new file mode 100644 index 00000000000..e4aa7a3d0d0 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_bitutils.h @@ -0,0 +1,176 @@ +/* Bit and bytes utilities. + + Bytes swap functions, reverse order of bytes: + + - _Py_bswap16(uint16_t) + - _Py_bswap32(uint32_t) + - _Py_bswap64(uint64_t) +*/ + +#ifndef Py_INTERNAL_BITUTILS_H +#define Py_INTERNAL_BITUTILS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) + /* __builtin_bswap16() is available since GCC 4.8, + __builtin_bswap32() is available since GCC 4.3, + __builtin_bswap64() is available since GCC 4.3. */ +# define _PY_HAVE_BUILTIN_BSWAP +#endif + +#ifdef _MSC_VER + /* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */ +# include +#endif + +static inline uint16_t +_Py_bswap16(uint16_t word) +{ +#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap16) + return __builtin_bswap16(word); +#elif defined(_MSC_VER) + Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short)); + return _byteswap_ushort(word); +#else + // Portable implementation which doesn't rely on circular bit shift + return ( ((word & UINT16_C(0x00FF)) << 8) + | ((word & UINT16_C(0xFF00)) >> 8)); +#endif +} + +static inline uint32_t +_Py_bswap32(uint32_t word) +{ +#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap32) + return __builtin_bswap32(word); +#elif defined(_MSC_VER) + Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long)); + return _byteswap_ulong(word); +#else + // Portable implementation which doesn't rely on circular bit shift + return ( ((word & UINT32_C(0x000000FF)) << 24) + | ((word & UINT32_C(0x0000FF00)) << 8) + | ((word & UINT32_C(0x00FF0000)) >> 8) + | ((word & UINT32_C(0xFF000000)) >> 24)); +#endif +} + +static inline uint64_t +_Py_bswap64(uint64_t word) +{ +#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap64) + return __builtin_bswap64(word); +#elif defined(_MSC_VER) + return _byteswap_uint64(word); +#else + // Portable implementation which doesn't rely on circular bit shift + return ( ((word & UINT64_C(0x00000000000000FF)) << 56) + | ((word & UINT64_C(0x000000000000FF00)) << 40) + | ((word & UINT64_C(0x0000000000FF0000)) << 24) + | ((word & UINT64_C(0x00000000FF000000)) << 8) + | ((word & UINT64_C(0x000000FF00000000)) >> 8) + | ((word & UINT64_C(0x0000FF0000000000)) >> 24) + | ((word & UINT64_C(0x00FF000000000000)) >> 40) + | ((word & UINT64_C(0xFF00000000000000)) >> 56)); +#endif +} + + +// Population count: count the number of 1's in 'x' +// (number of bits set to 1), also known as the hamming weight. +// +// Implementation note. CPUID is not used, to test if x86 POPCNT instruction +// can be used, to keep the implementation simple. For example, Visual Studio +// __popcnt() is not used this reason. The clang and GCC builtin function can +// use the x86 POPCNT instruction if the target architecture has SSE4a or +// newer. +static inline int +_Py_popcount32(uint32_t x) +{ +#if (defined(__clang__) || defined(__GNUC__)) + +#if SIZEOF_INT >= 4 + Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned int)); + return __builtin_popcount(x); +#else + // The C standard guarantees that unsigned long will always be big enough + // to hold a uint32_t value without losing information. + Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned long)); + return __builtin_popcountl(x); +#endif + +#else + // 32-bit SWAR (SIMD Within A Register) popcount + + // Binary: 0 1 0 1 ... + const uint32_t M1 = 0x55555555; + // Binary: 00 11 00 11. .. + const uint32_t M2 = 0x33333333; + // Binary: 0000 1111 0000 1111 ... + const uint32_t M4 = 0x0F0F0F0F; + // 256**4 + 256**3 + 256**2 + 256**1 + const uint32_t SUM = 0x01010101; + + // Put count of each 2 bits into those 2 bits + x = x - ((x >> 1) & M1); + // Put count of each 4 bits into those 4 bits + x = (x & M2) + ((x >> 2) & M2); + // Put count of each 8 bits into those 8 bits + x = (x + (x >> 4)) & M4; + // Sum of the 4 byte counts + return (uint32_t)((uint64_t)x * (uint64_t)SUM) >> 24; +#endif +} + + +// Return the index of the most significant 1 bit in 'x'. This is the smallest +// integer k such that x < 2**k. Equivalent to floor(log2(x)) + 1 for x != 0. +static inline int +_Py_bit_length(unsigned long x) +{ +#if (defined(__clang__) || defined(__GNUC__)) + if (x != 0) { + // __builtin_clzl() is available since GCC 3.4. + // Undefined behavior for x == 0. + return (int)sizeof(unsigned long) * 8 - __builtin_clzl(x); + } + else { + return 0; + } +#elif defined(_MSC_VER) + // _BitScanReverse() is documented to search 32 bits. + Py_BUILD_ASSERT(sizeof(unsigned long) <= 4); + unsigned long msb; + if (_BitScanReverse(&msb, x)) { + return (int)msb + 1; + } + else { + return 0; + } +#else + const int BIT_LENGTH_TABLE[32] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 + }; + int msb = 0; + while (x >= 32) { + msb += 6; + x >>= 6; + } + msb += BIT_LENGTH_TABLE[x]; + return msb; +#endif +} + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_BITUTILS_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_blocks_output_buffer.h b/contrib/tools/python3/src/Include/internal/pycore_blocks_output_buffer.h new file mode 100644 index 00000000000..28cf6fba4ee --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_blocks_output_buffer.h @@ -0,0 +1,317 @@ +/* + _BlocksOutputBuffer is used to maintain an output buffer + that has unpredictable size. Suitable for compression/decompression + API (bz2/lzma/zlib) that has stream->next_out and stream->avail_out: + + stream->next_out: point to the next output position. + stream->avail_out: the number of available bytes left in the buffer. + + It maintains a list of bytes object, so there is no overhead of resizing + the buffer. + + Usage: + + 1, Initialize the struct instance like this: + _BlocksOutputBuffer buffer = {.list = NULL}; + Set .list to NULL for _BlocksOutputBuffer_OnError() + + 2, Initialize the buffer use one of these functions: + _BlocksOutputBuffer_InitAndGrow() + _BlocksOutputBuffer_InitWithSize() + + 3, If (avail_out == 0), grow the buffer: + _BlocksOutputBuffer_Grow() + + 4, Get the current outputted data size: + _BlocksOutputBuffer_GetDataSize() + + 5, Finish the buffer, and return a bytes object: + _BlocksOutputBuffer_Finish() + + 6, Clean up the buffer when an error occurred: + _BlocksOutputBuffer_OnError() +*/ + +#ifndef Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H +#define Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "Python.h" + +typedef struct { + // List of bytes objects + PyObject *list; + // Number of whole allocated size + Py_ssize_t allocated; + // Max length of the buffer, negative number means unlimited length. + Py_ssize_t max_length; +} _BlocksOutputBuffer; + +static const char unable_allocate_msg[] = "Unable to allocate output buffer."; + +/* In 32-bit build, the max block size should <= INT32_MAX. */ +#define OUTPUT_BUFFER_MAX_BLOCK_SIZE (256*1024*1024) + +/* Block size sequence */ +#define KB (1024) +#define MB (1024*1024) +static const Py_ssize_t BUFFER_BLOCK_SIZE[] = + { 32*KB, 64*KB, 256*KB, 1*MB, 4*MB, 8*MB, 16*MB, 16*MB, + 32*MB, 32*MB, 32*MB, 32*MB, 64*MB, 64*MB, 128*MB, 128*MB, + OUTPUT_BUFFER_MAX_BLOCK_SIZE }; +#undef KB +#undef MB + +/* According to the block sizes defined by BUFFER_BLOCK_SIZE, the whole + allocated size growth step is: + 1 32 KB +32 KB + 2 96 KB +64 KB + 3 352 KB +256 KB + 4 1.34 MB +1 MB + 5 5.34 MB +4 MB + 6 13.34 MB +8 MB + 7 29.34 MB +16 MB + 8 45.34 MB +16 MB + 9 77.34 MB +32 MB + 10 109.34 MB +32 MB + 11 141.34 MB +32 MB + 12 173.34 MB +32 MB + 13 237.34 MB +64 MB + 14 301.34 MB +64 MB + 15 429.34 MB +128 MB + 16 557.34 MB +128 MB + 17 813.34 MB +256 MB + 18 1069.34 MB +256 MB + 19 1325.34 MB +256 MB + 20 1581.34 MB +256 MB + 21 1837.34 MB +256 MB + 22 2093.34 MB +256 MB + ... +*/ + +/* Initialize the buffer, and grow the buffer. + + max_length: Max length of the buffer, -1 for unlimited length. + + On success, return allocated size (>=0) + On failure, return -1 +*/ +static inline Py_ssize_t +_BlocksOutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer, + const Py_ssize_t max_length, + void **next_out) +{ + PyObject *b; + Py_ssize_t block_size; + + // ensure .list was set to NULL + assert(buffer->list == NULL); + + // get block size + if (0 <= max_length && max_length < BUFFER_BLOCK_SIZE[0]) { + block_size = max_length; + } else { + block_size = BUFFER_BLOCK_SIZE[0]; + } + + // the first block + b = PyBytes_FromStringAndSize(NULL, block_size); + if (b == NULL) { + return -1; + } + + // create the list + buffer->list = PyList_New(1); + if (buffer->list == NULL) { + Py_DECREF(b); + return -1; + } + PyList_SET_ITEM(buffer->list, 0, b); + + // set variables + buffer->allocated = block_size; + buffer->max_length = max_length; + + *next_out = PyBytes_AS_STRING(b); + return block_size; +} + +/* Initialize the buffer, with an initial size. + + Check block size limit in the outer wrapper function. For example, some libs + accept UINT32_MAX as the maximum block size, then init_size should <= it. + + On success, return allocated size (>=0) + On failure, return -1 +*/ +static inline Py_ssize_t +_BlocksOutputBuffer_InitWithSize(_BlocksOutputBuffer *buffer, + const Py_ssize_t init_size, + void **next_out) +{ + PyObject *b; + + // ensure .list was set to NULL + assert(buffer->list == NULL); + + // the first block + b = PyBytes_FromStringAndSize(NULL, init_size); + if (b == NULL) { + PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); + return -1; + } + + // create the list + buffer->list = PyList_New(1); + if (buffer->list == NULL) { + Py_DECREF(b); + return -1; + } + PyList_SET_ITEM(buffer->list, 0, b); + + // set variables + buffer->allocated = init_size; + buffer->max_length = -1; + + *next_out = PyBytes_AS_STRING(b); + return init_size; +} + +/* Grow the buffer. The avail_out must be 0, please check it before calling. + + On success, return allocated size (>=0) + On failure, return -1 +*/ +static inline Py_ssize_t +_BlocksOutputBuffer_Grow(_BlocksOutputBuffer *buffer, + void **next_out, + const Py_ssize_t avail_out) +{ + PyObject *b; + const Py_ssize_t list_len = Py_SIZE(buffer->list); + Py_ssize_t block_size; + + // ensure no gaps in the data + if (avail_out != 0) { + PyErr_SetString(PyExc_SystemError, + "avail_out is non-zero in _BlocksOutputBuffer_Grow()."); + return -1; + } + + // get block size + if (list_len < (Py_ssize_t) Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE)) { + block_size = BUFFER_BLOCK_SIZE[list_len]; + } else { + block_size = BUFFER_BLOCK_SIZE[Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE) - 1]; + } + + // check max_length + if (buffer->max_length >= 0) { + // if (rest == 0), should not grow the buffer. + Py_ssize_t rest = buffer->max_length - buffer->allocated; + assert(rest > 0); + + // block_size of the last block + if (block_size > rest) { + block_size = rest; + } + } + + // check buffer->allocated overflow + if (block_size > PY_SSIZE_T_MAX - buffer->allocated) { + PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); + return -1; + } + + // create the block + b = PyBytes_FromStringAndSize(NULL, block_size); + if (b == NULL) { + PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); + return -1; + } + if (PyList_Append(buffer->list, b) < 0) { + Py_DECREF(b); + return -1; + } + Py_DECREF(b); + + // set variables + buffer->allocated += block_size; + + *next_out = PyBytes_AS_STRING(b); + return block_size; +} + +/* Return the current outputted data size. */ +static inline Py_ssize_t +_BlocksOutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer, + const Py_ssize_t avail_out) +{ + return buffer->allocated - avail_out; +} + +/* Finish the buffer. + + Return a bytes object on success + Return NULL on failure +*/ +static inline PyObject * +_BlocksOutputBuffer_Finish(_BlocksOutputBuffer *buffer, + const Py_ssize_t avail_out) +{ + PyObject *result, *block; + const Py_ssize_t list_len = Py_SIZE(buffer->list); + + // fast path for single block + if ((list_len == 1 && avail_out == 0) || + (list_len == 2 && Py_SIZE(PyList_GET_ITEM(buffer->list, 1)) == avail_out)) + { + block = PyList_GET_ITEM(buffer->list, 0); + Py_INCREF(block); + + Py_CLEAR(buffer->list); + return block; + } + + // final bytes object + result = PyBytes_FromStringAndSize(NULL, buffer->allocated - avail_out); + if (result == NULL) { + PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); + return NULL; + } + + // memory copy + if (list_len > 0) { + char *posi = PyBytes_AS_STRING(result); + + // blocks except the last one + Py_ssize_t i = 0; + for (; i < list_len-1; i++) { + block = PyList_GET_ITEM(buffer->list, i); + memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block)); + posi += Py_SIZE(block); + } + // the last block + block = PyList_GET_ITEM(buffer->list, i); + memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block) - avail_out); + } else { + assert(Py_SIZE(result) == 0); + } + + Py_CLEAR(buffer->list); + return result; +} + +/* Clean up the buffer when an error occurred. */ +static inline void +_BlocksOutputBuffer_OnError(_BlocksOutputBuffer *buffer) +{ + Py_CLEAR(buffer->list); +} + +#ifdef __cplusplus +} +#endif +#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */ \ No newline at end of file diff --git a/contrib/tools/python3/src/Include/internal/pycore_byteswap.h b/contrib/tools/python3/src/Include/internal/pycore_byteswap.h deleted file mode 100644 index 2b20fc6c7d3..00000000000 --- a/contrib/tools/python3/src/Include/internal/pycore_byteswap.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Bytes swap functions, reverse order of bytes: - - - _Py_bswap16(uint16_t) - - _Py_bswap32(uint32_t) - - _Py_bswap64(uint64_t) -*/ - -#ifndef Py_INTERNAL_BSWAP_H -#define Py_INTERNAL_BSWAP_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#if defined(__GNUC__) \ - && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) - /* __builtin_bswap16() is available since GCC 4.8, - __builtin_bswap32() is available since GCC 4.3, - __builtin_bswap64() is available since GCC 4.3. */ -# define _PY_HAVE_BUILTIN_BSWAP -#endif - -#ifdef _MSC_VER - /* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */ -# include -#endif - -static inline uint16_t -_Py_bswap16(uint16_t word) -{ -#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap16) - return __builtin_bswap16(word); -#elif defined(_MSC_VER) - Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short)); - return _byteswap_ushort(word); -#else - // Portable implementation which doesn't rely on circular bit shift - return ( ((word & UINT16_C(0x00FF)) << 8) - | ((word & UINT16_C(0xFF00)) >> 8)); -#endif -} - -static inline uint32_t -_Py_bswap32(uint32_t word) -{ -#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap32) - return __builtin_bswap32(word); -#elif defined(_MSC_VER) - Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long)); - return _byteswap_ulong(word); -#else - // Portable implementation which doesn't rely on circular bit shift - return ( ((word & UINT32_C(0x000000FF)) << 24) - | ((word & UINT32_C(0x0000FF00)) << 8) - | ((word & UINT32_C(0x00FF0000)) >> 8) - | ((word & UINT32_C(0xFF000000)) >> 24)); -#endif -} - -static inline uint64_t -_Py_bswap64(uint64_t word) -{ -#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap64) - return __builtin_bswap64(word); -#elif defined(_MSC_VER) - return _byteswap_uint64(word); -#else - // Portable implementation which doesn't rely on circular bit shift - return ( ((word & UINT64_C(0x00000000000000FF)) << 56) - | ((word & UINT64_C(0x000000000000FF00)) << 40) - | ((word & UINT64_C(0x0000000000FF0000)) << 24) - | ((word & UINT64_C(0x00000000FF000000)) << 8) - | ((word & UINT64_C(0x000000FF00000000)) >> 8) - | ((word & UINT64_C(0x0000FF0000000000)) >> 24) - | ((word & UINT64_C(0x00FF000000000000)) >> 40) - | ((word & UINT64_C(0xFF00000000000000)) >> 56)); -#endif -} - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_BSWAP_H */ - diff --git a/contrib/tools/python3/src/Include/internal/pycore_ceval.h b/contrib/tools/python3/src/Include/internal/pycore_ceval.h index e7ace9bd01c..f573c3e5086 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_ceval.h +++ b/contrib/tools/python3/src/Include/internal/pycore_ceval.h @@ -23,43 +23,49 @@ PyAPI_FUNC(int) _PyEval_AddPendingCall( PyInterpreterState *interp, int (*func)(void *), void *arg); -PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyThreadState *tstate); +PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp); #ifdef HAVE_FORK -extern void _PyEval_ReInitThreads(struct pyruntimestate *runtime); +extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); #endif PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( PyThreadState *tstate, int new_depth); -/* Private function */ void _PyEval_Fini(void); + +extern PyObject* _PyEval_GetBuiltins(PyThreadState *tstate); +extern PyObject *_PyEval_BuiltinsFromGlobals( + PyThreadState *tstate, + PyObject *globals); + + static inline PyObject* _PyEval_EvalFrame(PyThreadState *tstate, PyFrameObject *f, int throwflag) { return tstate->interp->eval_frame(tstate, f, throwflag); } -extern PyObject *_PyEval_EvalCode( - PyThreadState *tstate, - PyObject *_co, PyObject *globals, PyObject *locals, - PyObject *const *args, Py_ssize_t argcount, - PyObject *const *kwnames, PyObject *const *kwargs, - Py_ssize_t kwcount, int kwstep, - PyObject *const *defs, Py_ssize_t defcount, - PyObject *kwdefs, PyObject *closure, - PyObject *name, PyObject *qualname); +extern PyObject * +_PyEval_Vector(PyThreadState *tstate, + PyFrameConstructor *desc, PyObject *locals, + PyObject* const* args, size_t argcount, + PyObject *kwnames); +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS +extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp); +#else extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime); +#endif extern PyStatus _PyEval_InitGIL(PyThreadState *tstate); -extern void _PyEval_FiniGIL(PyThreadState *tstate); +extern void _PyEval_FiniGIL(PyInterpreterState *interp); extern void _PyEval_ReleaseLock(PyThreadState *tstate); +extern void _PyEval_DeactivateOpCache(void); -/* --- _Py_EnterRecursiveCall() ----------------------------------------- */ -PyAPI_DATA(int) _Py_CheckRecursionLimit; +/* --- _Py_EnterRecursiveCall() ----------------------------------------- */ #ifdef USE_STACKCHECK /* With USE_STACKCHECK macro defined, trigger stack checks in diff --git a/contrib/tools/python3/src/Include/internal/pycore_code.h b/contrib/tools/python3/src/Include/internal/pycore_code.h index a1bd6a0bc0f..8ff1863dc00 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_code.h +++ b/contrib/tools/python3/src/Include/internal/pycore_code.h @@ -10,9 +10,16 @@ typedef struct { uint64_t builtins_ver; /* ma_version of builtin dict */ } _PyOpcache_LoadGlobal; +typedef struct { + PyTypeObject *type; + Py_ssize_t hint; + unsigned int tp_version_tag; +} _PyOpCodeOpt_LoadAttr; + struct _PyOpcache { union { _PyOpcache_LoadGlobal lg; + _PyOpCodeOpt_LoadAttr la; } u; char optimized; }; diff --git a/contrib/tools/python3/src/Include/internal/pycore_compile.h b/contrib/tools/python3/src/Include/internal/pycore_compile.h new file mode 100644 index 00000000000..06a6082cdda --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_compile.h @@ -0,0 +1,44 @@ +#ifndef Py_INTERNAL_COMPILE_H +#define Py_INTERNAL_COMPILE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +struct _arena; // Type defined in pycore_pyarena.h +struct _mod; // Type defined in pycore_ast.h + +// Export the symbol for test_peg_generator (built as a library) +PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( + struct _mod *mod, + PyObject *filename, + PyCompilerFlags *flags, + int optimize, + struct _arena *arena); +extern PyFutureFeatures* _PyFuture_FromAST( + struct _mod * mod, + PyObject *filename + ); + +extern PyObject* _Py_Mangle(PyObject *p, PyObject *name); + +typedef struct { + int optimize; + int ff_features; + + int recursion_depth; /* current recursion depth */ + int recursion_limit; /* recursion limit */ +} _PyASTOptimizeState; + +extern int _PyAST_Optimize( + struct _mod *, + struct _arena *arena, + _PyASTOptimizeState *state); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_COMPILE_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_context.h b/contrib/tools/python3/src/Include/internal/pycore_context.h index f665ad5c115..a482dd42122 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_context.h +++ b/contrib/tools/python3/src/Include/internal/pycore_context.h @@ -37,6 +37,6 @@ struct _pycontexttokenobject { int _PyContext_Init(void); -void _PyContext_Fini(void); +void _PyContext_Fini(PyInterpreterState *interp); #endif /* !Py_INTERNAL_CONTEXT_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_fileutils.h b/contrib/tools/python3/src/Include/internal/pycore_fileutils.h index 8cf137bb4bd..c1c9244a1bc 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_fileutils.h +++ b/contrib/tools/python3/src/Include/internal/pycore_fileutils.h @@ -48,6 +48,11 @@ PyAPI_FUNC(int) _Py_GetLocaleconvNumeric( PyObject **decimal_point, PyObject **thousands_sep); +PyAPI_FUNC(void) _Py_closerange(int first, int last); + +PyAPI_FUNC(wchar_t*) _Py_GetLocaleEncoding(void); +PyAPI_FUNC(PyObject*) _Py_GetLocaleEncodingObject(void); + #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION extern int _Py_LocaleUsesNonUnicodeWchar(void); diff --git a/contrib/tools/python3/src/Include/internal/pycore_format.h b/contrib/tools/python3/src/Include/internal/pycore_format.h new file mode 100644 index 00000000000..1b8d57539ca --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_format.h @@ -0,0 +1,27 @@ +#ifndef Py_INTERNAL_FORMAT_H +#define Py_INTERNAL_FORMAT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* Format codes + * F_LJUST '-' + * F_SIGN '+' + * F_BLANK ' ' + * F_ALT '#' + * F_ZERO '0' + */ +#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) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_FORMAT_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_gc.h b/contrib/tools/python3/src/Include/internal/pycore_gc.h index 0511eea779a..9db4a4716fa 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_gc.h +++ b/contrib/tools/python3/src/Include/internal/pycore_gc.h @@ -161,17 +161,19 @@ struct _gc_runtime_state { Py_ssize_t long_lived_pending; }; -PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); +extern void _PyGC_InitState(struct _gc_runtime_state *); + +extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate); // Functions to clear types free lists -extern void _PyFrame_ClearFreeList(void); -extern void _PyTuple_ClearFreeList(void); -extern void _PyFloat_ClearFreeList(void); -extern void _PyList_ClearFreeList(void); -extern void _PyDict_ClearFreeList(void); -extern void _PyAsyncGen_ClearFreeLists(void); -extern void _PyContext_ClearFreeList(void); +extern void _PyFrame_ClearFreeList(PyInterpreterState *interp); +extern void _PyTuple_ClearFreeList(PyInterpreterState *interp); +extern void _PyFloat_ClearFreeList(PyInterpreterState *interp); +extern void _PyList_ClearFreeList(PyInterpreterState *interp); +extern void _PyDict_ClearFreeList(PyInterpreterState *interp); +extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp); +extern void _PyContext_ClearFreeList(PyInterpreterState *interp); #ifdef __cplusplus } diff --git a/contrib/tools/python3/src/Include/internal/pycore_import.h b/contrib/tools/python3/src/Include/internal/pycore_import.h index b011ea44251..e21ed0a7a06 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_import.h +++ b/contrib/tools/python3/src/Include/internal/pycore_import.h @@ -5,15 +5,10 @@ extern "C" { #endif -PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( - PyThreadState *tstate, - const char *name /* UTF-8 encoded string */ - ); - #ifdef HAVE_FORK -extern void _PyImport_ReInitLock(void); +extern PyStatus _PyImport_ReInitLock(void); #endif -extern void _PyImport_Cleanup(PyThreadState *tstate); +extern PyObject* _PyImport_BootstrapImp(PyThreadState *tstate); #ifdef __cplusplus } diff --git a/contrib/tools/python3/src/Include/internal/pycore_initconfig.h b/contrib/tools/python3/src/Include/internal/pycore_initconfig.h index 457a005860b..4b009e816b4 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_initconfig.h +++ b/contrib/tools/python3/src/Include/internal/pycore_initconfig.h @@ -44,6 +44,8 @@ struct pyruntimestate; #define _PyStatus_UPDATE_FUNC(err) \ do { err.func = _PyStatus_GET_FUNC(); } while (0) +PyObject* _PyErr_SetFromPyStatus(PyStatus status); + /* --- PyWideStringList ------------------------------------------------ */ #define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL} @@ -100,6 +102,7 @@ typedef struct { int isolated; /* -I option */ int use_environment; /* -E option */ int dev_mode; /* -X dev and PYTHONDEVMODE */ + int warn_default_encoding; /* -X warn_default_encoding and PYTHONWARNDEFAULTENCODING */ } _PyPreCmdline; #define _PyPreCmdline_INIT \ @@ -149,13 +152,19 @@ PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config); extern PyStatus _PyConfig_Copy( PyConfig *config, const PyConfig *config2); -extern PyStatus _PyConfig_InitPathConfig(PyConfig *config); +extern PyStatus _PyConfig_InitPathConfig( + PyConfig *config, + int compute_path_config); +extern PyStatus _PyConfig_Read(PyConfig *config, int compute_path_config); extern PyStatus _PyConfig_Write(const PyConfig *config, struct pyruntimestate *runtime); extern PyStatus _PyConfig_SetPyArgv( PyConfig *config, const _PyArgv *args); +PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config); +PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict); + /* --- Function used for testing ---------------------------------- */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_interp.h b/contrib/tools/python3/src/Include/internal/pycore_interp.h index 551ad833bb6..4307b61ca36 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_interp.h +++ b/contrib/tools/python3/src/Include/internal/pycore_interp.h @@ -8,12 +8,11 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_atomic.h" /* _Py_atomic_address */ -#include "pycore_gil.h" /* struct _gil_runtime_state */ -#include "pycore_gc.h" /* struct _gc_runtime_state */ -#include "pycore_warnings.h" /* struct _warnings_runtime_state */ - -/* ceval state */ +#include "pycore_atomic.h" // _Py_atomic_address +#include "pycore_ast_state.h" // struct ast_state +#include "pycore_gil.h" // struct _gil_runtime_state +#include "pycore_gc.h" // struct _gc_runtime_state +#include "pycore_warnings.h" // struct _warnings_runtime_state struct _pending_calls { PyThread_type_lock lock; @@ -34,18 +33,15 @@ struct _pending_calls { struct _ceval_state { int recursion_limit; - /* Records whether tracing is on for any thread. Counts the number - of threads for which tstate->c_tracefunc is non-NULL, so if the - value is 0, we know we don't have to check this thread's - c_tracefunc. This speeds up the if statement in - _PyEval_EvalFrameDefault() after fast_next_opcode. */ - int tracing_possible; /* 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; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + struct _gil_runtime_state gil; +#endif }; /* fs_codec.encoding is initialized to NULL. @@ -57,8 +53,150 @@ struct _Py_unicode_fs_codec { _Py_error_handler error_handler; }; +struct _Py_bytes_state { + PyObject *empty_string; + PyBytesObject *characters[256]; +}; + +struct _Py_unicode_ids { + Py_ssize_t size; + PyObject **array; +}; + struct _Py_unicode_state { + // The empty Unicode object is a singleton to improve performance. + PyObject *empty_string; + /* Single character Unicode strings in the Latin-1 range are being + shared as well. */ + PyObject *latin1[256]; struct _Py_unicode_fs_codec fs_codec; + + // Unused member kept for ABI backward compatibility with Python 3.10.0: + // see bpo-46006. + PyObject *unused_interned; + + // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId() + struct _Py_unicode_ids ids; +}; + +struct _Py_float_state { + /* Special free list + free_list is a singly-linked list of available PyFloatObjects, + linked via abuse of their ob_type members. */ + int numfree; + PyFloatObject *free_list; +}; + +/* Speed optimization to avoid frequent malloc/free of small tuples */ +#ifndef PyTuple_MAXSAVESIZE + // Largest tuple to save on free list +# define PyTuple_MAXSAVESIZE 20 +#endif +#ifndef PyTuple_MAXFREELIST + // Maximum number of tuples of each size to save +# define PyTuple_MAXFREELIST 2000 +#endif + +struct _Py_tuple_state { +#if PyTuple_MAXSAVESIZE > 0 + /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, + entry 0 is the empty tuple () of which at most one instance + will be allocated. */ + PyTupleObject *free_list[PyTuple_MAXSAVESIZE]; + int numfree[PyTuple_MAXSAVESIZE]; +#endif +}; + +/* Empty list reuse scheme to save calls to malloc and free */ +#ifndef PyList_MAXFREELIST +# define PyList_MAXFREELIST 80 +#endif + +struct _Py_list_state { + PyListObject *free_list[PyList_MAXFREELIST]; + int numfree; +}; + +#ifndef PyDict_MAXFREELIST +# define PyDict_MAXFREELIST 80 +#endif + +struct _Py_dict_state { + /* 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; +}; + +struct _Py_frame_state { + PyFrameObject *free_list; + /* number of frames currently in free_list */ + int numfree; +}; + +#ifndef _PyAsyncGen_MAXFREELIST +# define _PyAsyncGen_MAXFREELIST 80 +#endif + +struct _Py_async_gen_state { + /* Freelists boost performance 6-10%; they also reduce memory + fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend + are short-living objects that are instantiated for every + __anext__() call. */ + struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST]; + int value_numfree; + + struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST]; + int asend_numfree; +}; + +struct _Py_context_state { + // List of free PyContext objects + PyContext *freelist; + int numfree; +}; + +struct _Py_exc_state { + // The dict mapping from errno codes to OSError subclasses + PyObject *errnomap; + PyBaseExceptionObject *memerrors_freelist; + int memerrors_numfree; +}; + + +// atexit state +typedef struct { + PyObject *func; + PyObject *args; + PyObject *kwargs; +} atexit_callback; + +struct atexit_state { + atexit_callback **callbacks; + int ncallbacks; + int callback_len; +}; + + +// Type attribute lookup cache: speed up attribute and method lookups, +// see _PyType_Lookup(). +struct type_cache_entry { + unsigned int version; // initialized from type->tp_version_tag + PyObject *name; // reference to exactly a str or None + PyObject *value; // borrowed reference or NULL +}; + +#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 }; @@ -67,6 +205,11 @@ struct _Py_unicode_state { #define _PY_NSMALLPOSINTS 257 #define _PY_NSMALLNEGINTS 5 +// _PyLong_GetZero() and _PyLong_GetOne() must always be available +#if _PY_NSMALLPOSINTS < 2 +# error "_PY_NSMALLPOSINTS must be greater than 1" +#endif + // The PyInterpreterState typedef is in Include/pystate.h. struct _is { @@ -88,10 +231,14 @@ struct _is { struct _ceval_state ceval; struct _gc_runtime_state gc; + // 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; /* Used in Modules/_threadmodule.c. */ @@ -107,8 +254,6 @@ struct _is { PyObject *codec_error_registry; int codecs_initialized; - struct _Py_unicode_state unicode; - PyConfig config; #ifdef HAVE_DLOPEN int dlopenflags; @@ -118,7 +263,7 @@ struct _is { PyObject *builtins_copy; PyObject *import_func; - /* Initialized to PyEval_EvalFrameDefault(). */ + // Initialized to _PyEval_EvalFrameDefault(). _PyFrameEvalFunction eval_frame; Py_ssize_t co_extra_user_count; @@ -129,40 +274,41 @@ struct _is { PyObject *after_forkers_parent; PyObject *after_forkers_child; #endif - /* AtExit module */ - void (*pyexitfunc)(PyObject *); - PyObject *pyexitmodule; uint64_t tstate_next_unique_id; struct _warnings_runtime_state warnings; + struct atexit_state atexit; PyObject *audit_hooks; - struct { - struct { - int level; - int atbol; - } listnode; - } parser; - -#if _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS > 0 /* Small integers are preallocated in this array so that they can be shared. The integers that are preallocated are those in the range -_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive). */ PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; -#endif + struct _Py_bytes_state bytes; + struct _Py_unicode_state unicode; + struct _Py_float_state float_state; + /* Using a cache is very effective since typically only a single slice is + created and then deleted again. */ + PySliceObject *slice_cache; + + struct _Py_tuple_state tuple; + struct _Py_list_state list; + struct _Py_dict_state dict_state; + struct _Py_frame_state frame; + struct _Py_async_gen_state async_gen; + struct _Py_context_state context; + struct _Py_exc_state exc_state; + + struct ast_state ast; + struct type_cache type_cache; }; -/* Used by _PyImport_Cleanup() */ extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp); - -extern PyStatus _PyInterpreterState_SetConfig( - PyInterpreterState *interp, - const PyConfig *config); - +extern void _PyInterpreterState_Clear(PyThreadState *tstate); /* cross-interpreter data registry */ @@ -182,11 +328,10 @@ struct _xidregitem { PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(int64_t); PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *); -PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *); +PyAPI_FUNC(int) _PyInterpreterState_IDIncref(struct _is *); PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *); #ifdef __cplusplus } #endif #endif /* !Py_INTERNAL_INTERP_H */ - diff --git a/contrib/tools/python3/src/Include/internal/pycore_list.h b/contrib/tools/python3/src/Include/internal/pycore_list.h new file mode 100644 index 00000000000..f18fb052c49 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_list.h @@ -0,0 +1,20 @@ +#ifndef Py_INTERNAL_LIST_H +#define Py_INTERNAL_LIST_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "listobject.h" // _PyList_CAST() + + +#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item) + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_LIST_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_long.h b/contrib/tools/python3/src/Include/internal/pycore_long.h new file mode 100644 index 00000000000..2bea3a55ec8 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_long.h @@ -0,0 +1,40 @@ +#ifndef Py_INTERNAL_LONG_H +#define Py_INTERNAL_LONG_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_interp.h" // PyInterpreterState.small_ints +#include "pycore_pystate.h" // _PyThreadState_GET() + +// Don't call this function but _PyLong_GetZero() and _PyLong_GetOne() +static inline PyObject* __PyLong_GetSmallInt_internal(int value) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(-_PY_NSMALLNEGINTS <= value && value < _PY_NSMALLPOSINTS); + size_t index = _PY_NSMALLNEGINTS + value; + PyObject *obj = (PyObject*)interp->small_ints[index]; + // _PyLong_GetZero(), _PyLong_GetOne() and get_small_int() must not be + // called before _PyLong_Init() nor after _PyLong_Fini(). + assert(obj != NULL); + return obj; +} + +// Return a borrowed reference to the zero singleton. +// The function cannot return NULL. +static inline PyObject* _PyLong_GetZero(void) +{ return __PyLong_GetSmallInt_internal(0); } + +// Return a borrowed reference to the one singleton. +// The function cannot return NULL. +static inline PyObject* _PyLong_GetOne(void) +{ return __PyLong_GetSmallInt_internal(1); } + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_LONG_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_moduleobject.h b/contrib/tools/python3/src/Include/internal/pycore_moduleobject.h new file mode 100644 index 00000000000..e9978abd25b --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_moduleobject.h @@ -0,0 +1,42 @@ +#ifndef Py_INTERNAL_MODULEOBJECT_H +#define Py_INTERNAL_MODULEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct { + PyObject_HEAD + PyObject *md_dict; + struct PyModuleDef *md_def; + void *md_state; + PyObject *md_weaklist; + // for logging purposes after md_dict is cleared + PyObject *md_name; +} PyModuleObject; + +static inline PyModuleDef* _PyModule_GetDef(PyObject *mod) { + assert(PyModule_Check(mod)); + return ((PyModuleObject *)mod)->md_def; +} + +static inline void* _PyModule_GetState(PyObject* mod) { + assert(PyModule_Check(mod)); + return ((PyModuleObject *)mod)->md_state; +} + +static inline PyObject* _PyModule_GetDict(PyObject *mod) { + assert(PyModule_Check(mod)); + PyObject *dict = ((PyModuleObject *)mod) -> md_dict; + // _PyModule_GetDict(mod) must not be used after calling module_clear(mod) + assert(dict != NULL); + return dict; +} + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_MODULEOBJECT_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_object.h b/contrib/tools/python3/src/Include/internal/pycore_object.h index c66ff12d7ec..90d98134b89 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_object.h +++ b/contrib/tools/python3/src/Include/internal/pycore_object.h @@ -8,17 +8,58 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() -#include "pycore_interp.h" // PyInterpreterState.gc -#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() +#include "pycore_interp.h" // PyInterpreterState.gc +#include "pycore_pystate.h" // _PyInterpreterState_GET() PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); +/* Update the Python traceback of an object. This function must be called + when a memory block is reused from a free list. + + Internal function called by _Py_NewReference(). */ +extern int _PyTraceMalloc_NewReference(PyObject *op); + +// Fast inlined version of PyType_HasFeature() +static inline int +_PyType_HasFeature(PyTypeObject *type, unsigned long feature) { + return ((type->tp_flags & feature) != 0); +} + +extern void _PyType_InitCache(PyInterpreterState *interp); + /* Only private in Python 3.10 and 3.9.8+; public in 3.11 */ extern PyObject *_PyType_GetQualName(PyTypeObject *type); +/* Inline functions trading binary compatibility for speed: + _PyObject_Init() is the fast version of PyObject_Init(), and + _PyObject_InitVar() is the fast version of PyObject_InitVar(). + + These inline functions must not be called with op=NULL. */ +static inline void +_PyObject_Init(PyObject *op, PyTypeObject *typeobj) +{ + assert(op != NULL); + Py_SET_TYPE(op, typeobj); + if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) { + Py_INCREF(typeobj); + } + _Py_NewReference(op); +} + +static inline void +_PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) +{ + assert(op != NULL); + Py_SET_SIZE(op, size); + _PyObject_Init((PyObject *)op, typeobj); +} + + /* Tell the GC to track this object. + * + * The object must not be tracked by the GC. * * NB: While the object is tracked by the collector, it must be safe to call the * ob_traverse method. @@ -27,23 +68,27 @@ extern PyObject *_PyType_GetQualName(PyTypeObject *type); * because it's not object header. So we don't use _PyGCHead_PREV() and * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. * - * The PyObject_GC_Track() function is the public version of this macro. + * See also the public PyObject_GC_Track() function. */ -static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, - PyObject *op) +static inline void _PyObject_GC_TRACK( +// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined +#ifndef NDEBUG + const char *filename, int lineno, +#endif + PyObject *op) { _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op), "object already tracked by the garbage collector", - filename, lineno, "_PyObject_GC_TRACK"); + filename, lineno, __func__); PyGC_Head *gc = _Py_AS_GC(op); _PyObject_ASSERT_FROM(op, (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0, "object is in generation which is garbage collected", - filename, lineno, "_PyObject_GC_TRACK"); + filename, lineno, __func__); - PyThreadState *tstate = _PyThreadState_GET(); - PyGC_Head *generation0 = tstate->interp->gc.generation0; + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyGC_Head *generation0 = interp->gc.generation0; PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); _PyGCHead_SET_NEXT(last, gc); _PyGCHead_SET_PREV(gc, last); @@ -51,9 +96,6 @@ static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, generation0->_gc_prev = (uintptr_t)gc; } -#define _PyObject_GC_TRACK(op) \ - _PyObject_GC_TRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) - /* Tell the GC to stop tracking this object. * * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING @@ -61,14 +103,19 @@ static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, * * The object must be tracked by the GC. * - * The PyObject_GC_UnTrack() function is the public version of this macro. + * See also the public PyObject_GC_UnTrack() which accept an object which is + * not tracked. */ -static inline void _PyObject_GC_UNTRACK_impl(const char *filename, int lineno, - PyObject *op) +static inline void _PyObject_GC_UNTRACK( +// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined +#ifndef NDEBUG + const char *filename, int lineno, +#endif + PyObject *op) { _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op), "object not tracked by the garbage collector", - filename, lineno, "_PyObject_GC_UNTRACK"); + filename, lineno, __func__); PyGC_Head *gc = _Py_AS_GC(op); PyGC_Head *prev = _PyGCHead_PREV(gc); @@ -79,8 +126,20 @@ static inline void _PyObject_GC_UNTRACK_impl(const char *filename, int lineno, gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; } -#define _PyObject_GC_UNTRACK(op) \ - _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) +// Macros to accept any type for the parameter, and to automatically pass +// the filename and the filename (if NDEBUG is not defined) where the macro +// is called. +#ifdef NDEBUG +# define _PyObject_GC_TRACK(op) \ + _PyObject_GC_TRACK(_PyObject_CAST(op)) +# define _PyObject_GC_UNTRACK(op) \ + _PyObject_GC_UNTRACK(_PyObject_CAST(op)) +#else +# define _PyObject_GC_TRACK(op) \ + _PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op)) +# define _PyObject_GC_UNTRACK(op) \ + _PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op)) +#endif #ifdef Py_REF_DEBUG extern void _PyDebug_PrintTotalRefs(void); @@ -99,12 +158,6 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) return (PyObject **)((char *)op + offset); } -// Fast inlined version of PyType_HasFeature() -static inline int -_PyType_HasFeature(PyTypeObject *type, unsigned long feature) { - return ((type->tp_flags & feature) != 0); -} - // Fast inlined version of PyObject_IS_GC() static inline int _PyObject_IS_GC(PyObject *obj) @@ -117,6 +170,16 @@ _PyObject_IS_GC(PyObject *obj) // Fast inlined version of PyType_IS_GC() #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) +// Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL)); +extern int _Py_CheckSlotResult( + PyObject *obj, + 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) + #ifdef __cplusplus } #endif diff --git a/contrib/tools/python3/src/Include/internal/pycore_parser.h b/contrib/tools/python3/src/Include/internal/pycore_parser.h new file mode 100644 index 00000000000..e2de24e2ca9 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_parser.h @@ -0,0 +1,31 @@ +#ifndef Py_INTERNAL_PARSER_H +#define Py_INTERNAL_PARSER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +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, + const char *enc, + int mode, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PARSER_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_pathconfig.h b/contrib/tools/python3/src/Include/internal/pycore_pathconfig.h index 42d61b1ca26..15447f54490 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_pathconfig.h +++ b/contrib/tools/python3/src/Include/internal/pycore_pathconfig.h @@ -65,6 +65,7 @@ extern wchar_t* _Py_GetDLLPath(void); extern PyStatus _PyConfig_WritePathConfig(const PyConfig *config); extern void _Py_DumpPathConfig(PyThreadState *tstate); +extern PyObject* _PyPathConfig_AsDict(void); #ifdef __cplusplus } diff --git a/contrib/tools/python3/src/Include/internal/pycore_pyarena.h b/contrib/tools/python3/src/Include/internal/pycore_pyarena.h new file mode 100644 index 00000000000..d78972a88ca --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_pyarena.h @@ -0,0 +1,64 @@ +/* An arena-like memory interface for the compiler. + */ + +#ifndef Py_INTERNAL_PYARENA_H +#define Py_INTERNAL_PYARENA_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct _arena PyArena; + +/* _PyArena_New() and _PyArena_Free() create a new arena and free it, + respectively. Once an arena has been created, it can be used + to allocate memory via _PyArena_Malloc(). Pointers to PyObject can + also be registered with the arena via _PyArena_AddPyObject(), and the + arena will ensure that the PyObjects stay alive at least until + _PyArena_Free() is called. When an arena is freed, all the memory it + allocated is freed, the arena releases internal references to registered + PyObject*, and none of its pointers are valid. + XXX (tim) What does "none of its pointers are valid" mean? Does it + XXX mean that pointers previously obtained via _PyArena_Malloc() are + XXX no longer valid? (That's clearly true, but not sure that's what + XXX the text is trying to say.) + + _PyArena_New() returns an arena pointer. On error, it + returns a negative number and sets an exception. + XXX (tim): Not true. On error, _PyArena_New() actually returns NULL, + XXX and looks like it may or may not set an exception (e.g., if the + XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on + XXX and an exception is set; OTOH, if the internal + XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but + XXX an exception is not set in that case). +*/ +PyAPI_FUNC(PyArena*) _PyArena_New(void); +PyAPI_FUNC(void) _PyArena_Free(PyArena *); + +/* Mostly like malloc(), return the address of a block of memory spanning + * `size` bytes, or return NULL (without setting an exception) if enough + * new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with + * size=0 does not guarantee to return a unique pointer (the pointer + * returned may equal one or more other pointers obtained from + * _PyArena_Malloc()). + * Note that pointers obtained via _PyArena_Malloc() must never be passed to + * the system free() or realloc(), or to any of Python's similar memory- + * management functions. _PyArena_Malloc()-obtained pointers remain valid + * until _PyArena_Free(ar) is called, at which point all pointers obtained + * from the arena `ar` become invalid simultaneously. + */ +PyAPI_FUNC(void*) _PyArena_Malloc(PyArena *, size_t size); + +/* This routine isn't a proper arena allocation routine. It takes + * a PyObject* and records it so that it can be DECREFed when the + * arena is freed. + */ +PyAPI_FUNC(int) _PyArena_AddPyObject(PyArena *, PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYARENA_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_pyerrors.h b/contrib/tools/python3/src/Include/internal/pycore_pyerrors.h index 2cf1160afc0..a5e97fe23fb 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_pyerrors.h +++ b/contrib/tools/python3/src/Include/internal/pycore_pyerrors.h @@ -84,6 +84,12 @@ PyAPI_FUNC(PyObject *) _PyErr_FormatFromCauseTstate( PyAPI_FUNC(int) _PyErr_CheckSignalsTstate(PyThreadState *tstate); +PyAPI_FUNC(void) _Py_DumpExtensionModules(int fd, PyInterpreterState *interp); + +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); + #ifdef __cplusplus } #endif diff --git a/contrib/tools/python3/src/Include/internal/pycore_pylifecycle.h b/contrib/tools/python3/src/Include/internal/pycore_pylifecycle.h index 50ab645fc74..524be9d4cbb 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_pylifecycle.h +++ b/contrib/tools/python3/src/Include/internal/pycore_pylifecycle.h @@ -8,6 +8,24 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#ifdef HAVE_SIGNAL_H +#include +#endif + +#include "pycore_runtime.h" // _PyRuntimeState + +#ifndef NSIG +# if defined(_NSIG) +# define NSIG _NSIG /* For BSD/SysV */ +# elif defined(_SIGMAX) +# define NSIG (_SIGMAX + 1) /* For QNX */ +# elif defined(SIGMAX) +# define NSIG (SIGMAX + 1) /* For djgpp */ +# else +# define NSIG 64 /* Use a reasonable default value */ +# endif +#endif + /* Forward declarations */ struct _PyArgv; struct pyruntimestate; @@ -31,64 +49,71 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); /* Various one-time initializers */ -extern PyStatus _PyUnicode_Init(void); +extern PyStatus _PyUnicode_Init(PyInterpreterState *interp); +extern PyStatus _PyUnicode_InitTypes(void); +extern PyStatus _PyBytes_Init(PyInterpreterState *interp); extern int _PyStructSequence_Init(void); -extern int _PyLong_Init(PyThreadState *tstate); +extern int _PyLong_Init(PyInterpreterState *interp); +extern int _PyLong_InitTypes(void); +extern PyStatus _PyTuple_Init(PyInterpreterState *interp); extern PyStatus _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); -extern PyObject * _PyBuiltin_Init(PyThreadState *tstate); +extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp); extern PyStatus _PySys_Create( PyThreadState *tstate, PyObject **sysmod_p); extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); -extern int _PySys_InitMain(PyThreadState *tstate); -extern PyStatus _PyExc_Init(void); -extern PyStatus _PyErr_Init(void); +extern int _PySys_UpdateConfig(PyThreadState *tstate); +extern PyStatus _PyExc_Init(PyInterpreterState *interp); +extern PyStatus _PyErr_InitTypes(void); extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod); -extern PyStatus _PyImportHooks_Init(PyThreadState *tstate); -extern int _PyFloat_Init(void); +extern void _PyFloat_Init(void); +extern int _PyFloat_InitTypes(void); extern PyStatus _Py_HashRandomization_Init(const PyConfig *); extern PyStatus _PyTypes_Init(void); extern PyStatus _PyTypes_InitSlotDefs(void); extern PyStatus _PyImportZip_Init(PyThreadState *tstate); -extern PyStatus _PyGC_Init(PyThreadState *tstate); +extern PyStatus _PyGC_Init(PyInterpreterState *interp); +extern PyStatus _PyAtExit_Init(PyInterpreterState *interp); /* Various internal finalizers */ -extern void _PyFrame_Fini(void); -extern void _PyDict_Fini(void); -extern void _PyTuple_Fini(void); -extern void _PyList_Fini(void); -extern void _PySet_Fini(void); -extern void _PyBytes_Fini(void); -extern void _PyFloat_Fini(void); -extern void _PySlice_Fini(void); -extern void _PyAsyncGen_Fini(void); +extern void _PyFrame_Fini(PyInterpreterState *interp); +extern void _PyDict_Fini(PyInterpreterState *interp); +extern void _PyTuple_Fini(PyInterpreterState *interp); +extern void _PyList_Fini(PyInterpreterState *interp); +extern void _PyBytes_Fini(PyInterpreterState *interp); +extern void _PyFloat_Fini(PyInterpreterState *interp); +extern void _PySlice_Fini(PyInterpreterState *interp); +extern void _PyAsyncGen_Fini(PyInterpreterState *interp); extern int _PySignal_Init(int install_signal_handlers); -extern void PyOS_FiniInterrupts(void); +extern void _PySignal_Fini(void); -extern void _PyExc_Fini(void); +extern void _PyExc_Fini(PyInterpreterState *interp); extern void _PyImport_Fini(void); extern void _PyImport_Fini2(void); -extern void _PyGC_Fini(PyThreadState *tstate); -extern void _PyType_Fini(void); +extern void _PyGC_Fini(PyInterpreterState *interp); +extern void _PyType_Fini(PyInterpreterState *interp); extern void _Py_HashRandomization_Fini(void); -extern void _PyUnicode_Fini(PyThreadState *tstate); -extern void _PyLong_Fini(PyThreadState *tstate); +extern void _PyUnicode_Fini(PyInterpreterState *interp); +extern void _PyUnicode_ClearInterned(PyInterpreterState *interp); +extern void _PyLong_Fini(PyInterpreterState *interp); extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); extern void _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); -extern void _PyAST_Fini(void); +extern void _PyAST_Fini(PyInterpreterState *interp); +extern void _PyAtExit_Fini(PyInterpreterState *interp); -extern PyStatus _PyGILState_Init(PyThreadState *tstate); -extern void _PyGILState_Fini(PyThreadState *tstate); +extern PyStatus _PyGILState_Init(_PyRuntimeState *runtime); +extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate); +extern void _PyGILState_Fini(PyInterpreterState *interp); -PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyThreadState *tstate); +PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyInterpreterState *interp); PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv( const PyPreConfig *src_config, @@ -108,6 +133,8 @@ PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(PyThreadState *tstate); +extern void _PyAtExit_Call(PyInterpreterState *interp); + #ifdef __cplusplus } #endif diff --git a/contrib/tools/python3/src/Include/internal/pycore_pymem.h b/contrib/tools/python3/src/Include/internal/pycore_pymem.h index 9bcb5f5efd7..49af17146ff 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_pymem.h +++ b/contrib/tools/python3/src/Include/internal/pycore_pymem.h @@ -69,9 +69,6 @@ PyAPI_FUNC(int) _PyMem_GetAllocatorName( PYMEM_ALLOCATOR_NOT_SET does nothing. */ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); -/* bpo-35053: Expose _Py_tracemalloc_config for _Py_NewReference() - which access directly _Py_tracemalloc_config.tracing for best - performances. */ struct _PyTraceMalloc_Config { /* Module initialized? Variable protected by the GIL */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_pystate.h b/contrib/tools/python3/src/Include/internal/pycore_pystate.h index 835d6e029c4..4b894f3eff4 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_pystate.h +++ b/contrib/tools/python3/src/Include/internal/pycore_pystate.h @@ -22,11 +22,11 @@ _Py_IsMainThread(void) static inline int -_Py_IsMainInterpreter(PyThreadState* tstate) +_Py_IsMainInterpreter(PyInterpreterState *interp) { /* Use directly _PyRuntime rather than tstate->interp->runtime, since this function is used in performance critical code path (ceval) */ - return (tstate->interp == _PyRuntime.interpreters.main); + return (interp == _PyRuntime.interpreters.main); } @@ -49,10 +49,18 @@ _Py_ThreadCanHandlePendingCalls(void) /* Variable and macro for in-line access to current thread and interpreter state */ +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS +PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void); +#endif + static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) { +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + return _PyThreadState_GetTSS(); +#else return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current); +#endif } /* Get the current Python thread state. @@ -67,7 +75,11 @@ _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) static inline PyThreadState* _PyThreadState_GET(void) { +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + return _PyThreadState_GetTSS(); +#else return _PyRuntimeState_GetThreadState(&_PyRuntime); +#endif } /* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */ @@ -119,9 +131,12 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( PyThreadState *newts); PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); -PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); -PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); +#ifdef HAVE_FORK +extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); +extern PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime); +extern void _PySignal_AfterFork(void); +#endif PyAPI_FUNC(int) _PyState_AddModule( diff --git a/contrib/tools/python3/src/Include/internal/pycore_runtime.h b/contrib/tools/python3/src/Include/internal/pycore_runtime.h index 34eb492b9f2..bcd710c4496 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_runtime.h +++ b/contrib/tools/python3/src/Include/internal/pycore_runtime.h @@ -19,7 +19,9 @@ struct _ceval_runtime_state { the main thread of the main interpreter can handle signals: see _Py_ThreadCanHandleSignals(). */ _Py_atomic_int signals_pending; +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS struct _gil_runtime_state gil; +#endif }; /* GIL state */ @@ -47,6 +49,13 @@ typedef struct _Py_AuditHookEntry { void *userData; } _Py_AuditHookEntry; +struct _Py_unicode_runtime_ids { + PyThread_type_lock lock; + // next_index value must be preserved when Py_Initialize()/Py_Finalize() + // is called multiple times: see _PyUnicode_FromId() implementation. + Py_ssize_t next_index; +}; + /* Full Python runtime state */ typedef struct pyruntimestate { @@ -100,10 +109,14 @@ typedef struct pyruntimestate { PyPreConfig preconfig; + // Audit values must be preserved when Py_Initialize()/Py_Finalize() + // is called multiple times. Py_OpenCodeHookFunction open_code_hook; void *open_code_userdata; _Py_AuditHookEntry *audit_hook_head; + struct _Py_unicode_runtime_ids unicode_ids; + // XXX Consolidate globals found via the check-c-globals script. } _PyRuntimeState; @@ -118,7 +131,7 @@ PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); #ifdef HAVE_FORK -PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); +extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); #endif /* Initialize _PyRuntimeState. diff --git a/contrib/tools/python3/src/Include/internal/pycore_structseq.h b/contrib/tools/python3/src/Include/internal/pycore_structseq.h new file mode 100644 index 00000000000..84c8d477e0d --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_structseq.h @@ -0,0 +1,21 @@ +#ifndef Py_INTERNAL_STRUCTSEQ_H +#define Py_INTERNAL_STRUCTSEQ_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +PyAPI_FUNC(int) _PyStructSequence_InitType( + PyTypeObject *type, + PyStructSequence_Desc *desc, + unsigned long tp_flags); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_STRUCTSEQ_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_symtable.h b/contrib/tools/python3/src/Include/internal/pycore_symtable.h new file mode 100644 index 00000000000..a2e520b8e25 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_symtable.h @@ -0,0 +1,133 @@ +#ifndef Py_INTERNAL_SYMTABLE_H +#define Py_INTERNAL_SYMTABLE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +struct _mod; // Type defined in pycore_ast.h + +typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock, AnnotationBlock } + _Py_block_ty; + +typedef enum _comprehension_type { + NoComprehension = 0, + ListComprehension = 1, + DictComprehension = 2, + SetComprehension = 3, + GeneratorExpression = 4 } _Py_comprehension_ty; + +struct _symtable_entry; + +struct symtable { + PyObject *st_filename; /* name of file being compiled, + decoded from the filesystem encoding */ + struct _symtable_entry *st_cur; /* current symbol table entry */ + struct _symtable_entry *st_top; /* symbol table entry for module */ + PyObject *st_blocks; /* dict: map AST node addresses + * to symbol table entries */ + PyObject *st_stack; /* list: stack of namespace info */ + PyObject *st_global; /* borrowed ref to st_top->ste_symbols */ + int st_nblocks; /* number of blocks used. kept for + consistency with the corresponding + compiler structure */ + PyObject *st_private; /* name of current class or NULL */ + PyFutureFeatures *st_future; /* module's future features that affect + the symbol table */ + int recursion_depth; /* current recursion depth */ + int recursion_limit; /* recursion limit */ +}; + +typedef struct _symtable_entry { + PyObject_HEAD + PyObject *ste_id; /* int: key in ste_table->st_blocks */ + PyObject *ste_symbols; /* dict: variable names to flags */ + PyObject *ste_name; /* string: name of current block */ + 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 */ + 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, + including free refs to globals */ + unsigned ste_generator : 1; /* true if namespace is a generator */ + unsigned ste_coroutine : 1; /* true if namespace is a coroutine */ + _Py_comprehension_ty ste_comprehension; /* Kind of comprehension (if any) */ + unsigned ste_varargs : 1; /* true if block has varargs */ + unsigned ste_varkeywords : 1; /* true if block has varkeywords */ + unsigned ste_returns_value : 1; /* true if namespace uses return with + an argument */ + unsigned ste_needs_class_closure : 1; /* for class scopes, true if a + closure over __class__ + should be created */ + unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */ + 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 */ + int ste_end_lineno; /* end line of block */ + int ste_end_col_offset; /* end offset of first line of block */ + int ste_opt_lineno; /* lineno of last exec or import * */ + int ste_opt_col_offset; /* offset of last exec or import * */ + struct symtable *ste_table; +} PySTEntryObject; + +extern PyTypeObject PySTEntry_Type; + +#define PySTEntry_Check(op) Py_IS_TYPE(op, &PySTEntry_Type) + +extern int _PyST_GetScope(PySTEntryObject *, PyObject *); + +extern struct symtable* _PySymtable_Build( + struct _mod *mod, + PyObject *filename, + PyFutureFeatures *future); +PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); + +extern void _PySymtable_Free(struct symtable *); + +/* Flags for def-use information */ + +#define DEF_GLOBAL 1 /* global stmt */ +#define DEF_LOCAL 2 /* assignment in code block */ +#define DEF_PARAM 2<<1 /* formal parameter */ +#define DEF_NONLOCAL 2<<2 /* nonlocal stmt */ +#define USE 2<<3 /* name is used */ +#define DEF_FREE 2<<4 /* name used but not defined in nested block */ +#define DEF_FREE_CLASS 2<<5 /* free variable from class's method */ +#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_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. +*/ +#define SCOPE_OFFSET 11 +#define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL) + +#define LOCAL 1 +#define GLOBAL_EXPLICIT 2 +#define GLOBAL_IMPLICIT 3 +#define FREE 4 +#define CELL 5 + +#define GENERATOR 1 +#define GENERATOR_EXPRESSION 2 + +// Used by symtablemodule.c +extern struct symtable* _Py_SymtableStringObjectFlags( + const char *str, + PyObject *filename, + int start, + PyCompilerFlags *flags); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_SYMTABLE_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_traceback.h b/contrib/tools/python3/src/Include/internal/pycore_traceback.h index c23290ebec5..c01a47639d5 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_traceback.h +++ b/contrib/tools/python3/src/Include/internal/pycore_traceback.h @@ -74,17 +74,13 @@ PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text); This function is signal safe. */ PyAPI_FUNC(void) _Py_DumpDecimal( int fd, - unsigned long value); + size_t value); -/* Format an integer as hexadecimal into the file descriptor fd with at least - width digits. - - The maximum width is sizeof(unsigned long)*2 digits. - - This function is signal safe. */ +/* Format an integer as hexadecimal with width digits into fd file descriptor. + The function is signal safe. */ PyAPI_FUNC(void) _Py_DumpHexadecimal( int fd, - unsigned long value, + uintptr_t value, Py_ssize_t width); PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame( diff --git a/contrib/tools/python3/src/Include/internal/pycore_tuple.h b/contrib/tools/python3/src/Include/internal/pycore_tuple.h new file mode 100644 index 00000000000..5353e18d083 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_tuple.h @@ -0,0 +1,20 @@ +#ifndef Py_INTERNAL_TUPLE_H +#define Py_INTERNAL_TUPLE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "tupleobject.h" /* _PyTuple_CAST() */ + +#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item) + +PyAPI_FUNC(PyObject *) _PyTuple_FromArray(PyObject *const *, Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TUPLE_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_tupleobject.h b/contrib/tools/python3/src/Include/internal/pycore_tupleobject.h deleted file mode 100644 index f95f16c0ed0..00000000000 --- a/contrib/tools/python3/src/Include/internal/pycore_tupleobject.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef Py_INTERNAL_TUPLEOBJECT_H -#define Py_INTERNAL_TUPLEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "tupleobject.h" /* _PyTuple_CAST() */ - -#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item) -PyAPI_FUNC(PyObject *) _PyTuple_FromArray(PyObject *const *, Py_ssize_t); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_TUPLEOBJECT_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_ucnhash.h b/contrib/tools/python3/src/Include/internal/pycore_ucnhash.h new file mode 100644 index 00000000000..187dd68e734 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_ucnhash.h @@ -0,0 +1,34 @@ +/* Unicode name database interface */ +#ifndef Py_INTERNAL_UCNHASH_H +#define Py_INTERNAL_UCNHASH_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* revised ucnhash CAPI interface (exported through a "wrapper") */ + +#define PyUnicodeData_CAPSULE_NAME "unicodedata._ucnhash_CAPI" + +typedef struct { + + /* Get name for a given character code. + Returns non-zero if success, zero if not. + Does not set Python exceptions. */ + int (*getname)(Py_UCS4 code, char* buffer, int buflen, + int with_alias_and_seq); + + /* Get character code for a given name. + Same error handling as for getname(). */ + int (*getcode)(const char* name, int namelen, Py_UCS4* code, + int with_named_seq); + +} _PyUnicode_Name_CAPI; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_UCNHASH_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_unionobject.h b/contrib/tools/python3/src/Include/internal/pycore_unionobject.h new file mode 100644 index 00000000000..9962f576103 --- /dev/null +++ b/contrib/tools/python3/src/Include/internal/pycore_unionobject.h @@ -0,0 +1,22 @@ +#ifndef Py_INTERNAL_UNIONOBJECT_H +#define Py_INTERNAL_UNIONOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +extern PyTypeObject _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) +extern PyObject *_Py_subs_parameters(PyObject *, PyObject *, PyObject *, PyObject *); +extern PyObject *_Py_make_parameters(PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_UNIONOBJECT_H */ diff --git a/contrib/tools/python3/src/Include/internal/pycore_warnings.h b/contrib/tools/python3/src/Include/internal/pycore_warnings.h index cafe305edb0..f728ec3077b 100644 --- a/contrib/tools/python3/src/Include/internal/pycore_warnings.h +++ b/contrib/tools/python3/src/Include/internal/pycore_warnings.h @@ -17,7 +17,7 @@ struct _warnings_runtime_state { long filters_version; }; -extern PyStatus _PyWarnings_InitState(PyThreadState *tstate); +extern int _PyWarnings_InitState(PyInterpreterState *interp); #ifdef __cplusplus } diff --git a/contrib/tools/python3/src/Include/intrcheck.h b/contrib/tools/python3/src/Include/intrcheck.h index e5bf5a834e4..b8cc6560168 100644 --- a/contrib/tools/python3/src/Include/intrcheck.h +++ b/contrib/tools/python3/src/Include/intrcheck.h @@ -1,4 +1,3 @@ - #ifndef Py_INTRCHECK_H #define Py_INTRCHECK_H #ifdef __cplusplus @@ -6,7 +5,6 @@ extern "C" { #endif PyAPI_FUNC(int) PyOS_InterruptOccurred(void); -PyAPI_FUNC(void) PyOS_InitInterrupts(void); #ifdef HAVE_FORK #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 PyAPI_FUNC(void) PyOS_BeforeFork(void); @@ -19,7 +17,6 @@ Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyOS_AfterFork(void); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyOS_IsMainThread(void); -PyAPI_FUNC(void) _PySignal_AfterFork(void); #ifdef MS_WINDOWS /* windows.h is not included by Python.h so use void* instead of HANDLE */ diff --git a/contrib/tools/python3/src/Include/iterobject.h b/contrib/tools/python3/src/Include/iterobject.h index 51139bf1874..6454611aebe 100644 --- a/contrib/tools/python3/src/Include/iterobject.h +++ b/contrib/tools/python3/src/Include/iterobject.h @@ -7,6 +7,9 @@ extern "C" { PyAPI_DATA(PyTypeObject) PySeqIter_Type; PyAPI_DATA(PyTypeObject) PyCallIter_Type; +#ifdef Py_BUILD_CORE +extern PyTypeObject _PyAnextAwaitable_Type; +#endif #define PySeqIter_Check(op) Py_IS_TYPE(op, &PySeqIter_Type) diff --git a/contrib/tools/python3/src/Include/longobject.h b/contrib/tools/python3/src/Include/longobject.h index 1b288099da8..e2301d7abfc 100644 --- a/contrib/tools/python3/src/Include/longobject.h +++ b/contrib/tools/python3/src/Include/longobject.h @@ -102,8 +102,6 @@ PyAPI_FUNC(long long) PyLong_AsLongLongAndOverflow(PyObject *, int *); PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int); #ifndef Py_LIMITED_API -Py_DEPRECATED(3.3) -PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int); PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base); PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int); #endif @@ -173,23 +171,6 @@ PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed); -/* _PyLong_FromNbInt: Convert the given object to a PyLongObject - using the nb_int slot, if available. Raise TypeError if either the - nb_int slot is not available or the result of the call to nb_int - returns something not of type int. -*/ -PyAPI_FUNC(PyObject *) _PyLong_FromNbInt(PyObject *); - -/* Convert the given object to a PyLongObject using the nb_index or - nb_int slots, if available (the latter is deprecated). - Raise TypeError if either nb_index and nb_int slots are not - available or the result of the call to nb_index or nb_int - returns something not of type int. - Should be replaced with PyNumber_Index after the end of the - deprecation period. -*/ -PyAPI_FUNC(PyObject *) _PyLong_FromNbIndexOrNbInt(PyObject *); - /* _PyLong_Format: Convert the long to a string object with given base, appending a base prefix of 0[box] if base is 2, 8 or 16. */ PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base); @@ -229,9 +210,6 @@ PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); #endif /* !Py_LIMITED_API */ #ifndef Py_LIMITED_API -PyAPI_DATA(PyObject *) _PyLong_Zero; -PyAPI_DATA(PyObject *) _PyLong_One; - PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t); PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t); #endif diff --git a/contrib/tools/python3/src/Include/methodobject.h b/contrib/tools/python3/src/Include/methodobject.h index 12e049b4043..9ffe8e1a3dd 100644 --- a/contrib/tools/python3/src/Include/methodobject.h +++ b/contrib/tools/python3/src/Include/methodobject.h @@ -41,7 +41,13 @@ struct PyMethodDef { }; typedef struct PyMethodDef PyMethodDef; +/* PyCFunction_New is declared as a function for stable ABI (declaration is + * needed for e.g. GCC with -fvisibility=hidden), but redefined as a macro + * that calls PyCFunction_NewEx. */ +PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *); #define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) + +/* PyCFunction_NewEx is similar: on 3.9+, this calls PyCMethod_New. */ PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, PyObject *); @@ -73,15 +79,15 @@ PyAPI_FUNC(PyObject *) PyCMethod_New(PyMethodDef *, PyObject *, #define METH_COEXIST 0x0040 -#ifndef Py_LIMITED_API -#define METH_FASTCALL 0x0080 +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030a0000 +# define METH_FASTCALL 0x0080 #endif /* This bit is preserved for Stackless Python */ #ifdef STACKLESS -#define METH_STACKLESS 0x0100 +# define METH_STACKLESS 0x0100 #else -#define METH_STACKLESS 0x0000 +# define METH_STACKLESS 0x0000 #endif /* METH_METHOD means the function stores an diff --git a/contrib/tools/python3/src/Include/modsupport.h b/contrib/tools/python3/src/Include/modsupport.h index 4c4aab65bac..f009d586bf6 100644 --- a/contrib/tools/python3/src/Include/modsupport.h +++ b/contrib/tools/python3/src/Include/modsupport.h @@ -136,7 +136,15 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( void _PyArg_Fini(void); #endif /* Py_LIMITED_API */ -PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); +// 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); + +// Similar to PyModule_AddObjectRef() but steal a reference to 'obj' +// (Py_DECREF(obj)) on success (if it returns 0). +PyAPI_FUNC(int) PyModule_AddObject(PyObject *mod, const char *, PyObject *value); + PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 diff --git a/contrib/tools/python3/src/Include/moduleobject.h b/contrib/tools/python3/src/Include/moduleobject.h index cf9ad40c0a1..49b116ca1c3 100644 --- a/contrib/tools/python3/src/Include/moduleobject.h +++ b/contrib/tools/python3/src/Include/moduleobject.h @@ -84,6 +84,12 @@ typedef struct PyModuleDef{ freefunc m_free; } PyModuleDef; + +// Internal C API +#ifdef Py_BUILD_CORE +extern int _PyModule_IsExtension(PyObject *obj); +#endif + #ifdef __cplusplus } #endif diff --git a/contrib/tools/python3/src/Include/node.h b/contrib/tools/python3/src/Include/node.h deleted file mode 100644 index ca24f289085..00000000000 --- a/contrib/tools/python3/src/Include/node.h +++ /dev/null @@ -1,47 +0,0 @@ - -/* Parse tree node interface */ - -#ifndef Py_NODE_H -#define Py_NODE_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _node { - short n_type; - char *n_str; - int n_lineno; - int n_col_offset; - int n_nchildren; - struct _node *n_child; - int n_end_lineno; - int n_end_col_offset; -} node; - -PyAPI_FUNC(node *) PyNode_New(int type); -PyAPI_FUNC(int) PyNode_AddChild(node *n, int type, - char *str, int lineno, int col_offset, - int end_lineno, int end_col_offset); -PyAPI_FUNC(void) PyNode_Free(node *n); -#ifndef Py_LIMITED_API -PyAPI_FUNC(Py_ssize_t) _PyNode_SizeOf(node *n); -#endif - -/* Node access functions */ -#define NCH(n) ((n)->n_nchildren) - -#define CHILD(n, i) (&(n)->n_child[i]) -#define TYPE(n) ((n)->n_type) -#define STR(n) ((n)->n_str) -#define LINENO(n) ((n)->n_lineno) - -/* Assert that the type of a node is what we expect */ -#define REQ(n, type) assert(TYPE(n) == (type)) - -PyAPI_FUNC(void) PyNode_ListTree(node *); -void _PyNode_FinalizeEndPos(node *n); // helper also used in parsetok.c - -#ifdef __cplusplus -} -#endif -#endif /* !Py_NODE_H */ diff --git a/contrib/tools/python3/src/Include/object.h b/contrib/tools/python3/src/Include/object.h index 9c1a7f479e4..61e638c3497 100644 --- a/contrib/tools/python3/src/Include/object.h +++ b/contrib/tools/python3/src/Include/object.h @@ -54,11 +54,11 @@ whose size is determined when the object is allocated. /* Py_DEBUG implies Py_REF_DEBUG. */ #if defined(Py_DEBUG) && !defined(Py_REF_DEBUG) -#define Py_REF_DEBUG +# define Py_REF_DEBUG #endif -#if defined(Py_LIMITED_API) && defined(Py_REF_DEBUG) -#error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG +#if defined(Py_LIMITED_API) && defined(Py_TRACE_REFS) +# error Py_LIMITED_API is incompatible with Py_TRACE_REFS #endif /* PyTypeObject structure is defined in cpython/object.h. @@ -74,8 +74,8 @@ typedef struct _typeobject PyTypeObject; #define _PyObject_EXTRA_INIT 0, 0, #else -#define _PyObject_HEAD_EXTRA -#define _PyObject_EXTRA_INIT +# define _PyObject_HEAD_EXTRA +# define _PyObject_EXTRA_INIT #endif /* PyObject_HEAD defines the initial segment of every PyObject. */ @@ -119,26 +119,47 @@ typedef struct { /* Cast argument to PyVarObject* type. */ #define _PyVarObject_CAST(op) ((PyVarObject*)(op)) +#define _PyVarObject_CAST_CONST(op) ((const PyVarObject*)(op)) -#define Py_REFCNT(ob) (_PyObject_CAST(ob)->ob_refcnt) + +// Test if the 'x' object is the 'y' object, the same as "x is y" in Python. +PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y); +#define Py_Is(x, y) ((x) == (y)) + + +static inline Py_ssize_t _Py_REFCNT(const PyObject *ob) { + return ob->ob_refcnt; +} +#define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST_CONST(ob)) + + +// bpo-39573: The Py_SET_TYPE() function must be used to set an object type. #define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type) + +// bpo-39573: The Py_SET_SIZE() function must be used to set an object size. #define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size) + static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { + // bpo-44378: Don't use Py_TYPE() since Py_TYPE() requires a non-const + // object. return ob->ob_type == type; } #define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type) + static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { ob->ob_refcnt = refcnt; } #define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) + static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { ob->ob_type = type; } #define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) + static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { ob->ob_size = size; } @@ -221,8 +242,11 @@ PyAPI_FUNC(void *) PyType_GetModuleState(struct _typeobject *); /* Generic type check */ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); -#define PyObject_TypeCheck(ob, tp) \ - (Py_IS_TYPE(ob, tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) + +static inline int _PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) { + return Py_IS_TYPE(ob, type) || PyType_IsSubtype(Py_TYPE(ob), type); +} +#define PyObject_TypeCheck(ob, type) _PyObject_TypeCheck(_PyObject_CAST(ob), type) PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ @@ -298,6 +322,20 @@ Code can use PyType_HasFeature(type_ob, flag_value) to test whether the given type object has a specified feature. */ +#ifndef Py_LIMITED_API +/* 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 */ +#define Py_TPFLAGS_MAPPING (1 << 6) +#endif + +/* Disallow creating instances of the type: set tp_new to NULL and don't create + * the "__new__" key in the type dictionary. */ +#define Py_TPFLAGS_DISALLOW_INSTANTIATION (1UL << 7) + +/* Set if the type object is immutable: type attributes cannot be set nor deleted */ +#define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8) + /* Set if the type object is dynamically allocated */ #define Py_TPFLAGS_HEAPTYPE (1UL << 9) @@ -330,13 +368,17 @@ given type object has a specified feature. /* Objects behave like an unbound method */ #define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17) -/* Objects support type attribute cache */ -#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) +/* Object has up-to-date type attribute cache */ #define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19) /* Type is abstract and cannot be instantiated */ #define Py_TPFLAGS_IS_ABSTRACT (1UL << 20) +// This undocumented flag gives certain built-ins their unique pattern-matching +// behavior, which allows a single positional subpattern to match against the +// subject itself (rather than a mapped attribute on it): +#define _Py_TPFLAGS_MATCH_SELF (1UL << 22) + /* 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) @@ -349,19 +391,23 @@ given type object has a specified feature. #define Py_TPFLAGS_DEFAULT ( \ Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ - Py_TPFLAGS_HAVE_VERSION_TAG | \ 0) -/* NOTE: The following flags reuse lower bits (removed as part of the +/* NOTE: Some of the following flags reuse lower bits (removed as part of the * Python 3.0 transition). */ -/* The following flag is kept for compatibility. Starting with 3.8, - * binary compatibility of C extensions across feature releases of - * Python is not supported anymore, except when using the stable ABI. +/* The following flags are kept for compatibility; in previous + * versions they indicated presence of newer tp_* fields on the + * type struct. + * Starting with 3.8, binary compatibility of C extensions across + * feature releases of Python is not supported anymore (except when + * using the stable ABI, in which all classes are created dynamically, + * using the interpreter's memory layout.) + * Note that older extensions using the stable ABI set these flags, + * so the bits must not be repurposed. */ - -/* Type structure has tp_finalize member (3.4) */ #define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) +#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) /* @@ -400,22 +446,46 @@ PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +/* +These are provided as conveniences to Python runtime embedders, so that +they can have object code that is not dependent on Python compilation flags. +*/ +PyAPI_FUNC(void) Py_IncRef(PyObject *); +PyAPI_FUNC(void) Py_DecRef(PyObject *); + +// Similar to Py_IncRef() and Py_DecRef() but the argument must be non-NULL. +// Private functions used by Py_INCREF() and Py_DECREF(). +PyAPI_FUNC(void) _Py_IncRef(PyObject *); +PyAPI_FUNC(void) _Py_DecRef(PyObject *); + static 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. + _Py_IncRef(op); +#else + // Non-limited C API and limited C API for Python 3.9 and older access + // directly PyObject.ob_refcnt. #ifdef Py_REF_DEBUG _Py_RefTotal++; #endif op->ob_refcnt++; +#endif } - #define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op)) static inline void _Py_DECREF( -#ifdef Py_REF_DEBUG +#if defined(Py_REF_DEBUG) && !(defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000) const char *filename, int lineno, #endif 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. + _Py_DecRef(op); +#else + // Non-limited C API and limited C API for Python 3.9 and older access + // directly PyObject.ob_refcnt. #ifdef Py_REF_DEBUG _Py_RefTotal--; #endif @@ -429,9 +499,9 @@ static inline void _Py_DECREF( else { _Py_Dealloc(op); } +#endif } - -#ifdef Py_REF_DEBUG +#if defined(Py_REF_DEBUG) && !(defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000) # define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) #else # define Py_DECREF(op) _Py_DECREF(_PyObject_CAST(op)) @@ -500,12 +570,31 @@ static inline void _Py_XDECREF(PyObject *op) #define Py_XDECREF(op) _Py_XDECREF(_PyObject_CAST(op)) -/* -These are provided as conveniences to Python runtime embedders, so that -they can have object code that is not dependent on Python compilation flags. -*/ -PyAPI_FUNC(void) Py_IncRef(PyObject *); -PyAPI_FUNC(void) Py_DecRef(PyObject *); +// Create a new strong reference to an object: +// increment the reference count of the object and return the object. +PyAPI_FUNC(PyObject*) Py_NewRef(PyObject *obj); + +// Similar to Py_NewRef(), but the object can be NULL. +PyAPI_FUNC(PyObject*) Py_XNewRef(PyObject *obj); + +static inline PyObject* _Py_NewRef(PyObject *obj) +{ + Py_INCREF(obj); + return obj; +} + +static inline PyObject* _Py_XNewRef(PyObject *obj) +{ + Py_XINCREF(obj); + return obj; +} + +// Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI. +// Names overridden with macros by static inline functions for best +// performances. +#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) +#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) + /* _Py_NoneStruct is an object of undefined type which can be used in contexts @@ -516,8 +605,12 @@ Don't forget to apply Py_INCREF() when returning this value!!! PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ #define Py_None (&_Py_NoneStruct) +// Test if an object is the None singleton, the same as "x is None" in Python. +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_INCREF(Py_None), Py_None +#define Py_RETURN_NONE return Py_NewRef(Py_None) /* Py_NotImplemented is a singleton used to signal that an operation is @@ -527,8 +620,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_INCREF(Py_NotImplemented), Py_NotImplemented +#define Py_RETURN_NOTIMPLEMENTED return Py_NewRef(Py_NotImplemented) /* Rich comparison opcodes */ #define Py_LT 0 @@ -538,6 +630,15 @@ PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ #define Py_GT 4 #define Py_GE 5 +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 +/* Result of calling PyIter_Send */ +typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, +} PySendResult; +#endif + /* * Macro for implementing rich comparisons * diff --git a/contrib/tools/python3/src/Include/objimpl.h b/contrib/tools/python3/src/Include/objimpl.h index 030d7eee297..450befad679 100644 --- a/contrib/tools/python3/src/Include/objimpl.h +++ b/contrib/tools/python3/src/Include/objimpl.h @@ -38,7 +38,7 @@ Functions and macros for modules that implement new object types. object with room for n items. In addition to the refcount and type pointer fields, this also fills in the ob_size field. - - PyObject_Del(op) releases the memory allocated for an object. It does not + - PyObject_Free(op) releases the memory allocated for an object. It does not run a destructor -- it only frees the memory. PyObject_Free is identical. - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't @@ -48,8 +48,8 @@ Functions and macros for modules that implement new object types. Note that objects created with PyObject_{New, NewVar} are allocated using the specialized Python allocator (implemented in obmalloc.c), if WITH_PYMALLOC is -enabled. In addition, a special debugging allocator is used if PYMALLOC_DEBUG -is also #defined. +enabled. In addition, a special debugging allocator is used if Py_DEBUG +macro is also defined. In case a specific form of memory management is needed (for example, if you must use the platform malloc heap(s), or shared memory, or C++ local storage or @@ -102,7 +102,9 @@ PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyObject_Free(void *ptr); -/* Macros */ +// Deprecated aliases only kept for backward compatibility. +// PyObject_Del and PyObject_DEL are defined with no parameter to be able to +// use them as function pointers (ex: tp_free = PyObject_Del). #define PyObject_MALLOC PyObject_Malloc #define PyObject_REALLOC PyObject_Realloc #define PyObject_FREE PyObject_Free @@ -118,7 +120,14 @@ PyAPI_FUNC(void) PyObject_Free(void *ptr); /* Functions */ PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *); PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *, - PyTypeObject *, Py_ssize_t); + PyTypeObject *, Py_ssize_t); + +#define PyObject_INIT(op, typeobj) \ + PyObject_Init(_PyObject_CAST(op), (typeobj)) +#define PyObject_INIT_VAR(op, typeobj, size) \ + PyObject_InitVar(_PyVarObject_CAST(op), (typeobj), (size)) + + PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); @@ -131,31 +140,22 @@ PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) -// Alias to PyObject_New(). In Python 3.8, PyObject_NEW() called directly -// PyObject_MALLOC() with _PyObject_VAR_SIZE(). +// 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) -#ifdef Py_LIMITED_API -/* Define PyObject_INIT() and PyObject_INIT_VAR() as aliases to PyObject_Init() - and PyObject_InitVar() in the limited C API for compatibility with the - CPython C API. */ -# define PyObject_INIT(op, typeobj) \ - PyObject_Init(_PyObject_CAST(op), (typeobj)) -# define PyObject_INIT_VAR(op, typeobj, size) \ - PyObject_InitVar(_PyVarObject_CAST(op), (typeobj), (size)) -#else -/* PyObject_INIT() and PyObject_INIT_VAR() are defined in cpython/objimpl.h */ -#endif - - /* * Garbage Collection Support * ========================== */ -/* C equivalent of gc.collect() which ignores the state of gc.enabled. */ +/* C equivalent of gc.collect(). */ PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void); +/* C API for controlling the state of the garbage collector */ +PyAPI_FUNC(int) PyGC_Enable(void); +PyAPI_FUNC(int) PyGC_Disable(void); +PyAPI_FUNC(int) PyGC_IsEnabled(void); /* Test if a type has a GC head */ #define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) diff --git a/contrib/tools/python3/src/Include/odictobject.h b/contrib/tools/python3/src/Include/odictobject.h deleted file mode 100644 index e070413017d..00000000000 --- a/contrib/tools/python3/src/Include/odictobject.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef Py_ODICTOBJECT_H -#define Py_ODICTOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* OrderedDict */ -/* This API is optional and mostly redundant. */ - -#ifndef Py_LIMITED_API - -typedef struct _odictobject PyODictObject; - -PyAPI_DATA(PyTypeObject) PyODict_Type; -PyAPI_DATA(PyTypeObject) PyODictIter_Type; -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_SIZE(op) PyDict_GET_SIZE((op)) - -PyAPI_FUNC(PyObject *) PyODict_New(void); -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_GetItemWithError(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) - -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_ODICTOBJECT_H */ diff --git a/contrib/tools/python3/src/Include/opcode.h b/contrib/tools/python3/src/Include/opcode.h index 19944fac0b9..52039754bd8 100644 --- a/contrib/tools/python3/src/Include/opcode.h +++ b/contrib/tools/python3/src/Include/opcode.h @@ -30,7 +30,11 @@ extern "C" { #define BINARY_TRUE_DIVIDE 27 #define INPLACE_FLOOR_DIVIDE 28 #define INPLACE_TRUE_DIVIDE 29 -#define RERAISE 48 +#define GET_LEN 30 +#define MATCH_MAPPING 31 +#define MATCH_SEQUENCE 32 +#define MATCH_KEYS 33 +#define COPY_DICT_WITHOUT_KEYS 34 #define WITH_EXCEPT_START 49 #define GET_AITER 50 #define GET_ANEXT 51 @@ -77,6 +81,7 @@ extern "C" { #define DELETE_ATTR 96 #define STORE_GLOBAL 97 #define DELETE_GLOBAL 98 +#define ROT_N 99 #define LOAD_CONST 100 #define LOAD_NAME 101 #define BUILD_TUPLE 102 @@ -96,11 +101,13 @@ extern "C" { #define LOAD_GLOBAL 116 #define IS_OP 117 #define CONTAINS_OP 118 +#define RERAISE 119 #define JUMP_IF_NOT_EXC_MATCH 121 #define SETUP_FINALLY 122 #define LOAD_FAST 124 #define STORE_FAST 125 #define DELETE_FAST 126 +#define GEN_START 129 #define RAISE_VARARGS 130 #define CALL_FUNCTION 131 #define MAKE_FUNCTION 132 @@ -117,6 +124,7 @@ extern "C" { #define SET_ADD 146 #define MAP_ADD 147 #define LOAD_CLASSDEREF 148 +#define MATCH_CLASS 152 #define SETUP_ASYNC_WITH 154 #define FORMAT_VALUE 155 #define BUILD_CONST_KEY_MAP 156 @@ -127,6 +135,28 @@ extern "C" { #define SET_UPDATE 163 #define DICT_MERGE 164 #define DICT_UPDATE 165 +#ifdef NEED_OPCODE_JUMP_TABLES +static uint32_t _PyOpcode_RelativeJump[8] = { + 0U, + 0U, + 536870912U, + 67125248U, + 67141632U, + 0U, + 0U, + 0U, +}; +static uint32_t _PyOpcode_Jump[8] = { + 0U, + 0U, + 536870912U, + 101695488U, + 67141632U, + 0U, + 0U, + 0U, +}; +#endif /* OPCODE_TABLES */ /* EXCEPT_HANDLER is a special, implicit block type which is created when entering an except handler. It is not an opcode but we define it here diff --git a/contrib/tools/python3/src/Include/parsetok.h b/contrib/tools/python3/src/Include/parsetok.h deleted file mode 100644 index 935d733e90a..00000000000 --- a/contrib/tools/python3/src/Include/parsetok.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Parser-tokenizer link interface */ - -#ifndef Py_LIMITED_API -#ifndef Py_PARSETOK_H -#define Py_PARSETOK_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "grammar.h" /* grammar */ -#include "node.h" /* node */ - -typedef struct { - int error; - PyObject *filename; - int lineno; - int offset; - char *text; /* UTF-8-encoded string */ - int token; - int expected; -} perrdetail; - -#if 0 -#define PyPARSE_YIELD_IS_KEYWORD 0x0001 -#endif - -#define PyPARSE_DONT_IMPLY_DEDENT 0x0002 - -#if 0 -#define PyPARSE_WITH_IS_KEYWORD 0x0003 -#define PyPARSE_PRINT_IS_FUNCTION 0x0004 -#define PyPARSE_UNICODE_LITERALS 0x0008 -#endif - -#define PyPARSE_IGNORE_COOKIE 0x0010 -#define PyPARSE_BARRY_AS_BDFL 0x0020 -#define PyPARSE_TYPE_COMMENTS 0x0040 -#define PyPARSE_ASYNC_HACKS 0x0080 - -PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, - perrdetail *); -PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int, - const char *, const char *, - perrdetail *); - -PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int, - perrdetail *, int); -PyAPI_FUNC(node *) PyParser_ParseFileFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - const char *enc, - grammar *g, - int start, - const char *ps1, - const char *ps2, - perrdetail *err_ret, - int flags); -PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - const char *enc, - grammar *g, - int start, - const char *ps1, - const char *ps2, - perrdetail *err_ret, - int *flags); -PyAPI_FUNC(node *) PyParser_ParseFileObject( - FILE *fp, - PyObject *filename, - const char *enc, - grammar *g, - int start, - const char *ps1, - const char *ps2, - perrdetail *err_ret, - int *flags); - -PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename( - const char *s, - const char *filename, /* decoded from the filesystem encoding */ - grammar *g, - int start, - perrdetail *err_ret, - int flags); -PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx( - const char *s, - const char *filename, /* decoded from the filesystem encoding */ - grammar *g, - int start, - perrdetail *err_ret, - int *flags); -PyAPI_FUNC(node *) PyParser_ParseStringObject( - const char *s, - PyObject *filename, - grammar *g, - int start, - perrdetail *err_ret, - int *flags); - -/* Note that the following functions are defined in pythonrun.c, - not in parsetok.c */ -PyAPI_FUNC(void) PyParser_SetError(perrdetail *); -PyAPI_FUNC(void) PyParser_ClearError(perrdetail *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PARSETOK_H */ -#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/patchlevel.h b/contrib/tools/python3/src/Include/patchlevel.h index a4418b0a6c6..482069c791a 100644 --- a/contrib/tools/python3/src/Include/patchlevel.h +++ b/contrib/tools/python3/src/Include/patchlevel.h @@ -17,13 +17,13 @@ /* Version parsed out into numeric values */ /*--start constants--*/ #define PY_MAJOR_VERSION 3 -#define PY_MINOR_VERSION 9 -#define PY_MICRO_VERSION 12 +#define PY_MINOR_VERSION 10 +#define PY_MICRO_VERSION 4 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.9.12" +#define PY_VERSION "3.10.4" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/contrib/tools/python3/src/Include/picklebufobject.h b/contrib/tools/python3/src/Include/picklebufobject.h deleted file mode 100644 index 0df2561dcea..00000000000 --- a/contrib/tools/python3/src/Include/picklebufobject.h +++ /dev/null @@ -1,31 +0,0 @@ -/* PickleBuffer object. This is built-in for ease of use from third-party - * C extensions. - */ - -#ifndef Py_PICKLEBUFOBJECT_H -#define Py_PICKLEBUFOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_LIMITED_API - -PyAPI_DATA(PyTypeObject) 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 *); -/* Get the PickleBuffer's underlying view to the original object - * (NULL if released) - */ -PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *); -/* Release the PickleBuffer. Returns 0 on success, -1 on error. */ -PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *); - -#endif /* !Py_LIMITED_API */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PICKLEBUFOBJECT_H */ diff --git a/contrib/tools/python3/src/Include/pyarena.h b/contrib/tools/python3/src/Include/pyarena.h deleted file mode 100644 index db3ad0188fe..00000000000 --- a/contrib/tools/python3/src/Include/pyarena.h +++ /dev/null @@ -1,64 +0,0 @@ -/* An arena-like memory interface for the compiler. - */ - -#ifndef Py_LIMITED_API -#ifndef Py_PYARENA_H -#define Py_PYARENA_H - -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct _arena PyArena; - - /* PyArena_New() and PyArena_Free() create a new arena and free it, - respectively. Once an arena has been created, it can be used - to allocate memory via PyArena_Malloc(). Pointers to PyObject can - also be registered with the arena via PyArena_AddPyObject(), and the - arena will ensure that the PyObjects stay alive at least until - PyArena_Free() is called. When an arena is freed, all the memory it - allocated is freed, the arena releases internal references to registered - PyObject*, and none of its pointers are valid. - XXX (tim) What does "none of its pointers are valid" mean? Does it - XXX mean that pointers previously obtained via PyArena_Malloc() are - XXX no longer valid? (That's clearly true, but not sure that's what - XXX the text is trying to say.) - - PyArena_New() returns an arena pointer. On error, it - returns a negative number and sets an exception. - XXX (tim): Not true. On error, PyArena_New() actually returns NULL, - XXX and looks like it may or may not set an exception (e.g., if the - XXX internal PyList_New(0) returns NULL, PyArena_New() passes that on - XXX and an exception is set; OTOH, if the internal - XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but - XXX an exception is not set in that case). - */ - PyAPI_FUNC(PyArena *) PyArena_New(void); - PyAPI_FUNC(void) PyArena_Free(PyArena *); - - /* Mostly like malloc(), return the address of a block of memory spanning - * `size` bytes, or return NULL (without setting an exception) if enough - * new memory can't be obtained. Unlike malloc(0), PyArena_Malloc() with - * size=0 does not guarantee to return a unique pointer (the pointer - * returned may equal one or more other pointers obtained from - * PyArena_Malloc()). - * Note that pointers obtained via PyArena_Malloc() must never be passed to - * the system free() or realloc(), or to any of Python's similar memory- - * management functions. PyArena_Malloc()-obtained pointers remain valid - * until PyArena_Free(ar) is called, at which point all pointers obtained - * from the arena `ar` become invalid simultaneously. - */ - PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t size); - - /* This routine isn't a proper arena allocation routine. It takes - * a PyObject* and records it so that it can be DECREFed when the - * arena is freed. - */ - PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *); - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_PYARENA_H */ -#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/pyconfig-linux.h b/contrib/tools/python3/src/Include/pyconfig-linux.h index 98de8abc72d..bcd40eab052 100644 --- a/contrib/tools/python3/src/Include/pyconfig-linux.h +++ b/contrib/tools/python3/src/Include/pyconfig-linux.h @@ -17,6 +17,12 @@ support for AIX C++ shared extension modules. */ /* #undef AIX_GENUINE_CPLUSPLUS */ +/* The normal alignment of `long', in bytes. */ +#define ALIGNOF_LONG 8 + +/* The normal alignment of `size_t', in bytes. */ +#define ALIGNOF_SIZE_T 8 + /* Alternative SOABI used in debug build to load C extensions built in release mode */ /* #undef ALT_SOABI */ @@ -39,6 +45,9 @@ /* Define if --enable-ipv6 is specified */ #define ENABLE_IPV6 1 +/* Better isolate subinterpreters, experimental build mode. */ +/* #undef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS */ + /* Define to 1 if your system stores words within floats with the most significant word first */ /* #undef FLOAT_WORDS_BIGENDIAN */ @@ -113,7 +122,7 @@ /* Define if `unsetenv` does not return an int. */ /* #undef HAVE_BROKEN_UNSETENV */ -/* Has builtin atomics */ +/* Has builtin __atomic_load_n() and __atomic_store_n() functions */ #define HAVE_BUILTIN_ATOMIC 1 /* Define to 1 if you have the 'chflags' function. */ @@ -137,6 +146,9 @@ /* Define to 1 if you have the `clock_settime' function. */ #define HAVE_CLOCK_SETTIME 1 +/* Define to 1 if you have the `close_range' function. */ +/* #undef HAVE_CLOSE_RANGE */ + /* Define if the C compiler supports computed gotos. */ #define HAVE_COMPUTED_GOTOS 1 @@ -282,6 +294,9 @@ /* Define to 1 if you have the `dup3' function. */ #define HAVE_DUP3 1 +/* Define if you have the '_dyld_shared_cache_contains_path' function. */ +/* #undef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH */ + /* Defined when any dynamic module loading is enabled. */ #define HAVE_DYNAMIC_LOADING 1 @@ -303,11 +318,14 @@ /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 +/* Define if you have the 'eventfd' function. */ +#define HAVE_EVENTFD 1 + /* Define to 1 if you have the `execv' function. */ #define HAVE_EXECV 1 /* Define to 1 if you have the `explicit_bzero' function. */ -/* #undef HAVE_EXPLICIT_BZERO */ +#define HAVE_EXPLICIT_BZERO 1 /* Define to 1 if you have the `explicit_memset' function. */ /* #undef HAVE_EXPLICIT_MEMSET */ @@ -427,7 +445,7 @@ #define HAVE_GETC_UNLOCKED 1 /* Define to 1 if you have the `getentropy' function. */ -/* #undef HAVE_GETENTROPY */ +#define HAVE_GETENTROPY 1 /* Define to 1 if you have the `getgrgid_r' function. */ #define HAVE_GETGRGID_R 1 @@ -496,10 +514,10 @@ #define HAVE_GETPWUID_R 1 /* Define to 1 if the getrandom() function is available */ -/* #undef HAVE_GETRANDOM */ +#define HAVE_GETRANDOM 1 /* Define to 1 if the Linux getrandom() syscall is available */ -/* #undef HAVE_GETRANDOM_SYSCALL */ +#define HAVE_GETRANDOM_SYSCALL 1 /* Define to 1 if you have the `getresgid' function. */ #define HAVE_GETRESGID 1 @@ -601,7 +619,7 @@ /* Define to 1 if you have the header file. */ #define HAVE_LIBINTL_H 1 -/* Define if you have the readline library (-lreadline). */ +/* Define to build the readline module. */ /* #undef HAVE_LIBREADLINE */ /* Define to 1 if you have the `resolv' library (-lresolv). */ @@ -613,12 +631,18 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_LIBUTIL_H */ +/* Define to 1 if you have the `uuid' library (-luuid). */ +/* #undef HAVE_LIBUUID */ + /* Define if you have the 'link' function. */ #define HAVE_LINK 1 /* Define to 1 if you have the `linkat' function. */ #define HAVE_LINKAT 1 +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_AUXVEC_H 1 + /* Define to 1 if you have the header file. */ #define HAVE_LINUX_CAN_BCM_H 1 @@ -686,7 +710,7 @@ #define HAVE_MBRTOWC 1 /* Define if you have the 'memfd_create' function. */ -/* #undef HAVE_MEMFD_CREATE */ +#define HAVE_MEMFD_CREATE 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 @@ -733,6 +757,10 @@ /* Define to 1 if you have the `nice' function. */ #define HAVE_NICE 1 +/* Define if the internal form of wchar_t in non-Unicode locales is not + Unicode. */ +/* #undef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION */ + /* Define to 1 if you have the `openat' function. */ #define HAVE_OPENAT 1 @@ -781,9 +809,6 @@ /* Define if you have the 'prlimit' functions. */ #define HAVE_PRLIMIT 1 -/* Define if you have the '_dyld_shared_cache_contains_path' function. */ -/* #undef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH */ - /* Define to 1 if you have the header file. */ /* #undef HAVE_PROCESS_H */ @@ -886,6 +911,9 @@ /* Define to 1 if you have the `sched_setscheduler' function. */ #define HAVE_SCHED_SETSCHEDULER 1 +/* Define to 1 if you have the `sem_clockwait' function. */ +/* #undef HAVE_SEM_CLOCKWAIT */ + /* Define to 1 if you have the `sem_getvalue' function. */ #define HAVE_SEM_GETVALUE 1 @@ -1012,6 +1040,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_SPAWN_H 1 +/* Define to 1 if you have the `splice' function. */ +#define HAVE_SPLICE 1 + /* Define if your compiler provides ssize_t */ #define HAVE_SSIZE_T 1 @@ -1037,9 +1068,6 @@ /* Has stdatomic.h with atomic_int and atomic_uintptr_t */ #define HAVE_STD_ATOMIC 1 -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - /* Define to 1 if you have the `strftime' function. */ #define HAVE_STRFTIME 1 @@ -1103,6 +1131,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_AUDIOIO_H */ +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_AUXV_H 1 + /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_BSDTTY_H */ @@ -1119,6 +1150,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_SYS_EPOLL_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_EVENTFD_H 1 + /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_EVENT_H */ @@ -1160,7 +1194,7 @@ #define HAVE_SYS_POLL_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_RANDOM_H */ +#define HAVE_SYS_RANDOM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_RESOURCE_H 1 @@ -1304,6 +1338,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_UUID_UUID_H */ +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + /* Define to 1 if you have the `wait3' function. */ #define HAVE_WAIT3 1 @@ -1338,9 +1375,6 @@ /* Define to 1 if you have the `writev' function. */ #define HAVE_WRITEV 1 -/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ -#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 - /* Define if the zlib library has inflateCopy */ #define HAVE_ZLIB_COPY 1 @@ -1353,7 +1387,7 @@ /* Define to 1 if `major', `minor', and `makedev' are declared in . */ -/* #undef MAJOR_IN_SYSMACROS */ +#define MAJOR_IN_SYSMACROS 1 /* Define if mvwdelch in curses.h is an expression. */ #define MVWDELCH_IS_EXPRESSION 1 @@ -1389,7 +1423,7 @@ /* #undef PYLONG_BITS_IN_DIGIT */ /* enabled builtin hash modules */ -/* #undef PY_BUILTIN_HASHLIB_HASHES */ +#define PY_BUILTIN_HASHLIB_HASHES "md5,sha1,sha256,sha512,sha3,blake2" /* Define if you want to coerce the C locale to a UTF-8 based locale */ #define PY_COERCE_C_LOCALE 1 @@ -1492,6 +1526,9 @@ (which you can't on SCO ODT 3.0). */ #define SYS_SELECT_WITH_SYS_TIME 1 +/* Custom thread stack size depending on chosen sanitizer runtimes. */ +/* #undef THREAD_STACK_SIZE */ + /* Library needed by timemodule.c: librt may be needed for clock_gettime() */ /* #undef TIMEMODULE_LIB */ @@ -1544,6 +1581,9 @@ Dyld is necessary to support frameworks. */ /* #undef WITH_DYLD */ +/* Define to build the readline module against Editline. */ +/* #undef WITH_EDITLINE */ + /* Define to 1 if libintl is needed for locale functions. */ /* #undef WITH_LIBINTL */ @@ -1629,11 +1669,6 @@ /* Define on FreeBSD to activate all library features */ #define __BSD_VISIBLE 1 -/* Define to 1 if type `char' is unsigned and you are not using gcc. */ -#ifndef __CHAR_UNSIGNED__ -/* # undef __CHAR_UNSIGNED__ */ -#endif - /* Define to 'long' if doesn't define. */ /* #undef clock_t */ diff --git a/contrib/tools/python3/src/Include/pyconfig-osx-arm64.h b/contrib/tools/python3/src/Include/pyconfig-osx-arm64.h index 280d771bae8..42bf65677d0 100644 --- a/contrib/tools/python3/src/Include/pyconfig-osx-arm64.h +++ b/contrib/tools/python3/src/Include/pyconfig-osx-arm64.h @@ -17,6 +17,12 @@ support for AIX C++ shared extension modules. */ /* #undef AIX_GENUINE_CPLUSPLUS */ +/* The normal alignment of `long', in bytes. */ +#define ALIGNOF_LONG 8 + +/* The normal alignment of `size_t', in bytes. */ +#define ALIGNOF_SIZE_T 8 + /* Alternative SOABI used in debug build to load C extensions built in release mode */ /* #undef ALT_SOABI */ @@ -39,6 +45,9 @@ /* Define if --enable-ipv6 is specified */ #define ENABLE_IPV6 1 +/* Better isolate subinterpreters, experimental build mode. */ +/* #undef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS */ + /* Define to 1 if your system stores words within floats with the most significant word first */ /* #undef FLOAT_WORDS_BIGENDIAN */ @@ -113,7 +122,7 @@ /* Define if `unsetenv` does not return an int. */ /* #undef HAVE_BROKEN_UNSETENV */ -/* Has builtin atomics */ +/* Has builtin __atomic_load_n() and __atomic_store_n() functions */ #define HAVE_BUILTIN_ATOMIC 1 /* Define to 1 if you have the 'chflags' function. */ @@ -137,6 +146,9 @@ /* Define to 1 if you have the `clock_settime' function. */ #define HAVE_CLOCK_SETTIME 1 +/* Define to 1 if you have the `close_range' function. */ +/* #undef HAVE_CLOSE_RANGE */ + /* Define if the C compiler supports computed gotos. */ #define HAVE_COMPUTED_GOTOS 1 @@ -306,6 +318,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 +/* Define if you have the 'eventfd' function. */ +/* #undef HAVE_EVENTFD */ + /* Define to 1 if you have the `execv' function. */ #define HAVE_EXECV 1 @@ -602,8 +617,8 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_LIBINTL_H */ -/* Define if you have the readline library (-lreadline). */ -#define HAVE_LIBREADLINE 1 +/* Define to build the readline module. */ +/* #undef HAVE_LIBREADLINE */ /* Define to 1 if you have the `resolv' library (-lresolv). */ /* #undef HAVE_LIBRESOLV */ @@ -614,12 +629,18 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_LIBUTIL_H */ +/* Define to 1 if you have the `uuid' library (-luuid). */ +/* #undef HAVE_LIBUUID */ + /* Define if you have the 'link' function. */ #define HAVE_LINK 1 /* Define to 1 if you have the `linkat' function. */ #define HAVE_LINKAT 1 +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_AUXVEC_H */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_LINUX_CAN_BCM_H */ @@ -734,6 +755,10 @@ /* Define to 1 if you have the `nice' function. */ #define HAVE_NICE 1 +/* Define if the internal form of wchar_t in non-Unicode locales is not + Unicode. */ +/* #undef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION */ + /* Define to 1 if you have the `openat' function. */ #define HAVE_OPENAT 1 @@ -843,19 +868,19 @@ /* #undef HAVE_RL_CATCH_SIGNAL */ /* Define if you have readline 2.2 */ -#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1 +/* #undef HAVE_RL_COMPLETION_APPEND_CHARACTER */ /* Define if you have readline 4.0 */ -#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1 +/* #undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK */ /* Define if you have readline 4.2 */ -#define HAVE_RL_COMPLETION_MATCHES 1 +/* #undef HAVE_RL_COMPLETION_MATCHES */ /* Define if you have rl_completion_suppress_append */ /* #undef HAVE_RL_COMPLETION_SUPPRESS_APPEND */ /* Define if you have readline 4.0 */ -#define HAVE_RL_PRE_INPUT_HOOK 1 +/* #undef HAVE_RL_PRE_INPUT_HOOK */ /* Define if you have readline 4.0 */ /* #undef HAVE_RL_RESIZE_TERMINAL */ @@ -884,6 +909,9 @@ /* Define to 1 if you have the `sched_setscheduler' function. */ /* #undef HAVE_SCHED_SETSCHEDULER */ +/* Define to 1 if you have the `sem_clockwait' function. */ +/* #undef HAVE_SEM_CLOCKWAIT */ + /* Define to 1 if you have the `sem_getvalue' function. */ #define HAVE_SEM_GETVALUE 1 @@ -1010,6 +1038,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_SPAWN_H 1 +/* Define to 1 if you have the `splice' function. */ +/* #undef HAVE_SPLICE */ + /* Define if your compiler provides ssize_t */ #define HAVE_SSIZE_T 1 @@ -1035,9 +1066,6 @@ /* Has stdatomic.h with atomic_int and atomic_uintptr_t */ #define HAVE_STD_ATOMIC 1 -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - /* Define to 1 if you have the `strftime' function. */ #define HAVE_STRFTIME 1 @@ -1101,6 +1129,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_AUDIOIO_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_AUXV_H */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_BSDTTY_H */ @@ -1117,6 +1148,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_EPOLL_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_EVENTFD_H */ + /* Define to 1 if you have the header file. */ #define HAVE_SYS_EVENT_H 1 @@ -1302,6 +1336,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_UUID_UUID_H 1 +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + /* Define to 1 if you have the `wait3' function. */ #define HAVE_WAIT3 1 @@ -1336,9 +1373,6 @@ /* Define to 1 if you have the `writev' function. */ #define HAVE_WRITEV 1 -/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ -/* #undef HAVE_X509_VERIFY_PARAM_SET1_HOST */ - /* Define if the zlib library has inflateCopy */ #define HAVE_ZLIB_COPY 1 @@ -1490,6 +1524,9 @@ (which you can't on SCO ODT 3.0). */ #define SYS_SELECT_WITH_SYS_TIME 1 +/* Custom thread stack size depending on chosen sanitizer runtimes. */ +#define THREAD_STACK_SIZE 0x1000000 + /* Library needed by timemodule.c: librt may be needed for clock_gettime() */ /* #undef TIMEMODULE_LIB */ @@ -1542,6 +1579,9 @@ Dyld is necessary to support frameworks. */ #define WITH_DYLD 1 +/* Define to build the readline module against Editline. */ +/* #undef WITH_EDITLINE */ + /* Define to 1 if libintl is needed for locale functions. */ /* #undef WITH_LIBINTL */ @@ -1627,11 +1667,6 @@ /* Define on FreeBSD to activate all library features */ #define __BSD_VISIBLE 1 -/* Define to 1 if type `char' is unsigned and you are not using gcc. */ -#ifndef __CHAR_UNSIGNED__ -/* # undef __CHAR_UNSIGNED__ */ -#endif - /* Define to 'long' if doesn't define. */ /* #undef clock_t */ diff --git a/contrib/tools/python3/src/Include/pyconfig-osx.h b/contrib/tools/python3/src/Include/pyconfig-osx.h index e7e69f735b6..626753c7709 100644 --- a/contrib/tools/python3/src/Include/pyconfig-osx.h +++ b/contrib/tools/python3/src/Include/pyconfig-osx.h @@ -17,6 +17,12 @@ support for AIX C++ shared extension modules. */ /* #undef AIX_GENUINE_CPLUSPLUS */ +/* The normal alignment of `long', in bytes. */ +#define ALIGNOF_LONG 8 + +/* The normal alignment of `size_t', in bytes. */ +#define ALIGNOF_SIZE_T 8 + /* Alternative SOABI used in debug build to load C extensions built in release mode */ /* #undef ALT_SOABI */ @@ -39,6 +45,9 @@ /* Define if --enable-ipv6 is specified */ #define ENABLE_IPV6 1 +/* Better isolate subinterpreters, experimental build mode. */ +/* #undef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS */ + /* Define to 1 if your system stores words within floats with the most significant word first */ /* #undef FLOAT_WORDS_BIGENDIAN */ @@ -113,7 +122,7 @@ /* Define if `unsetenv` does not return an int. */ /* #undef HAVE_BROKEN_UNSETENV */ -/* Has builtin atomics */ +/* Has builtin __atomic_load_n() and __atomic_store_n() functions */ #define HAVE_BUILTIN_ATOMIC 1 /* Define to 1 if you have the 'chflags' function. */ @@ -137,6 +146,9 @@ /* Define to 1 if you have the `clock_settime' function. */ #define HAVE_CLOCK_SETTIME 1 +/* Define to 1 if you have the `close_range' function. */ +/* #undef HAVE_CLOSE_RANGE */ + /* Define if the C compiler supports computed gotos. */ #define HAVE_COMPUTED_GOTOS 1 @@ -177,7 +189,7 @@ #define HAVE_CURSES_IMMEDOK 1 /* Define if you have the 'is_pad' function or macro. */ -#define HAVE_CURSES_IS_PAD 1 +/* #undef HAVE_CURSES_IS_PAD */ /* Define if you have the 'is_term_resized' function. */ #define HAVE_CURSES_IS_TERM_RESIZED 1 @@ -282,6 +294,9 @@ /* Define to 1 if you have the `dup3' function. */ /* #undef HAVE_DUP3 */ +/* Define if you have the '_dyld_shared_cache_contains_path' function. */ +#define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH 1 + /* Defined when any dynamic module loading is enabled. */ #define HAVE_DYNAMIC_LOADING 1 @@ -303,6 +318,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 +/* Define if you have the 'eventfd' function. */ +/* #undef HAVE_EVENTFD */ + /* Define to 1 if you have the `execv' function. */ #define HAVE_EXECV 1 @@ -599,7 +617,7 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_LIBINTL_H */ -/* Define if you have the readline library (-lreadline). */ +/* Define to build the readline module. */ /* #undef HAVE_LIBREADLINE */ /* Define to 1 if you have the `resolv' library (-lresolv). */ @@ -611,12 +629,18 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_LIBUTIL_H */ +/* Define to 1 if you have the `uuid' library (-luuid). */ +/* #undef HAVE_LIBUUID */ + /* Define if you have the 'link' function. */ #define HAVE_LINK 1 /* Define to 1 if you have the `linkat' function. */ #define HAVE_LINKAT 1 +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_AUXVEC_H */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_LINUX_CAN_BCM_H */ @@ -731,6 +755,10 @@ /* Define to 1 if you have the `nice' function. */ #define HAVE_NICE 1 +/* Define if the internal form of wchar_t in non-Unicode locales is not + Unicode. */ +/* #undef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION */ + /* Define to 1 if you have the `openat' function. */ #define HAVE_OPENAT 1 @@ -771,7 +799,7 @@ #define HAVE_PREAD 1 /* Define to 1 if you have the `preadv' function. */ -/* #undef HAVE_PREADV */ +#define HAVE_PREADV 1 /* Define to 1 if you have the `preadv2' function. */ /* #undef HAVE_PREADV2 */ @@ -779,9 +807,6 @@ /* Define if you have the 'prlimit' functions. */ /* #undef HAVE_PRLIMIT */ -/* Define if you have the '_dyld_shared_cache_contains_path' function. */ -#define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH 1 - /* Define to 1 if you have the header file. */ /* #undef HAVE_PROCESS_H */ @@ -816,7 +841,7 @@ #define HAVE_PWRITE 1 /* Define to 1 if you have the `pwritev' function. */ -/* #undef HAVE_PWRITEV */ +#define HAVE_PWRITEV 1 /* Define to 1 if you have the `pwritev2' function. */ /* #undef HAVE_PWRITEV2 */ @@ -884,6 +909,9 @@ /* Define to 1 if you have the `sched_setscheduler' function. */ /* #undef HAVE_SCHED_SETSCHEDULER */ +/* Define to 1 if you have the `sem_clockwait' function. */ +/* #undef HAVE_SEM_CLOCKWAIT */ + /* Define to 1 if you have the `sem_getvalue' function. */ #define HAVE_SEM_GETVALUE 1 @@ -1010,6 +1038,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_SPAWN_H 1 +/* Define to 1 if you have the `splice' function. */ +/* #undef HAVE_SPLICE */ + /* Define if your compiler provides ssize_t */ #define HAVE_SSIZE_T 1 @@ -1035,9 +1066,6 @@ /* Has stdatomic.h with atomic_int and atomic_uintptr_t */ #define HAVE_STD_ATOMIC 1 -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - /* Define to 1 if you have the `strftime' function. */ #define HAVE_STRFTIME 1 @@ -1101,6 +1129,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_AUDIOIO_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_AUXV_H */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_BSDTTY_H */ @@ -1117,6 +1148,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_EPOLL_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_EVENTFD_H */ + /* Define to 1 if you have the header file. */ #define HAVE_SYS_EVENT_H 1 @@ -1302,6 +1336,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_UUID_UUID_H 1 +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + /* Define to 1 if you have the `wait3' function. */ #define HAVE_WAIT3 1 @@ -1336,9 +1373,6 @@ /* Define to 1 if you have the `writev' function. */ #define HAVE_WRITEV 1 -/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ -#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 - /* Define if the zlib library has inflateCopy */ #define HAVE_ZLIB_COPY 1 @@ -1387,7 +1421,7 @@ /* #undef PYLONG_BITS_IN_DIGIT */ /* enabled builtin hash modules */ -/* #undef PY_BUILTIN_HASHLIB_HASHES */ +#define PY_BUILTIN_HASHLIB_HASHES "md5,sha1,sha256,sha512,sha3,blake2" /* Define if you want to coerce the C locale to a UTF-8 based locale */ #define PY_COERCE_C_LOCALE 1 @@ -1490,6 +1524,9 @@ (which you can't on SCO ODT 3.0). */ #define SYS_SELECT_WITH_SYS_TIME 1 +/* Custom thread stack size depending on chosen sanitizer runtimes. */ +#define THREAD_STACK_SIZE 0x1000000 + /* Library needed by timemodule.c: librt may be needed for clock_gettime() */ /* #undef TIMEMODULE_LIB */ @@ -1542,6 +1579,9 @@ Dyld is necessary to support frameworks. */ #define WITH_DYLD 1 +/* Define to build the readline module against Editline. */ +/* #undef WITH_EDITLINE */ + /* Define to 1 if libintl is needed for locale functions. */ /* #undef WITH_LIBINTL */ @@ -1627,11 +1667,6 @@ /* Define on FreeBSD to activate all library features */ #define __BSD_VISIBLE 1 -/* Define to 1 if type `char' is unsigned and you are not using gcc. */ -#ifndef __CHAR_UNSIGNED__ -/* # undef __CHAR_UNSIGNED__ */ -#endif - /* Define to 'long' if doesn't define. */ /* #undef clock_t */ diff --git a/contrib/tools/python3/src/Include/pyconfig.h b/contrib/tools/python3/src/Include/pyconfig.h index 965b9e1be4d..cabe1c7a6b3 100644 --- a/contrib/tools/python3/src/Include/pyconfig.h +++ b/contrib/tools/python3/src/Include/pyconfig.h @@ -4,18 +4,18 @@ #define ABIFLAGS "" #define PREFIX "/var/empty" #define EXEC_PREFIX "/var/empty" -#define VERSION "3.9" +#define VERSION "3.10" #define VPATH "" #define BLAKE2_USE_SSE #define USE_ZLIB_CRC32 #if defined(__linux__) #define PLATFORM "linux" #define MULTIARCH "x86_64-linux-gnu" -#define SOABI "cpython-39-x86_64-linux-gnu" +#define SOABI "cpython-310-x86_64-linux-gnu" #elif defined(__APPLE__) #define PLATFORM "darwin" #define MULTIARCH "darwin" -#define SOABI "cpython-39-darwin" +#define SOABI "cpython-310-darwin" #endif #endif diff --git a/contrib/tools/python3/src/Include/pyctype.h b/contrib/tools/python3/src/Include/pyctype.h deleted file mode 100644 index 729d93275e6..00000000000 --- a/contrib/tools/python3/src/Include/pyctype.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef PYCTYPE_H -#define PYCTYPE_H -#ifdef __cplusplus -extern "C" { -#endif - -#define PY_CTF_LOWER 0x01 -#define PY_CTF_UPPER 0x02 -#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) -#define PY_CTF_DIGIT 0x04 -#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) -#define PY_CTF_SPACE 0x08 -#define PY_CTF_XDIGIT 0x10 - -PyAPI_DATA(const unsigned int) _Py_ctype_table[256]; - -/* Unlike their C counterparts, the following macros are not meant to - * handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument - * must be a signed/unsigned char. */ -#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) -#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) -#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) -#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) -#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) -#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) -#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) - -PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256]; -PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256]; - -#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) -#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) - -#ifdef __cplusplus -} -#endif -#endif /* !PYCTYPE_H */ -#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/pydebug.h b/contrib/tools/python3/src/Include/pydebug.h deleted file mode 100644 index 78bcb118be4..00000000000 --- a/contrib/tools/python3/src/Include/pydebug.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_PYDEBUG_H -#define Py_PYDEBUG_H -#ifdef __cplusplus -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; - -#ifdef MS_WINDOWS -PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; -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 */ -#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s)) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYDEBUG_H */ -#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/pyerrors.h b/contrib/tools/python3/src/Include/pyerrors.h index 979a26ba68a..f5d1c711577 100644 --- a/contrib/tools/python3/src/Include/pyerrors.h +++ b/contrib/tools/python3/src/Include/pyerrors.h @@ -30,12 +30,6 @@ PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); macro is defined. */ PyAPI_FUNC(void) _Py_NO_RETURN Py_FatalError(const char *message); -#if defined(Py_DEBUG) || defined(Py_LIMITED_API) -#define _PyErr_OCCURRED() PyErr_Occurred() -#else -#define _PyErr_OCCURRED() (PyThreadState_GET()->curexc_type) -#endif - /* Error testing and normalization */ PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *); PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); @@ -152,6 +146,7 @@ PyAPI_DATA(PyObject *) PyExc_FutureWarning; PyAPI_DATA(PyObject *) PyExc_ImportWarning; PyAPI_DATA(PyObject *) PyExc_UnicodeWarning; PyAPI_DATA(PyObject *) PyExc_BytesWarning; +PyAPI_DATA(PyObject *) PyExc_EncodingWarning; PyAPI_DATA(PyObject *) PyExc_ResourceWarning; @@ -230,6 +225,9 @@ PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); /* In signalmodule.c */ PyAPI_FUNC(int) PyErr_CheckSignals(void); PyAPI_FUNC(void) PyErr_SetInterrupt(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 +PyAPI_FUNC(int) PyErr_SetInterruptEx(int signum); +#endif /* Support for adding program text to SyntaxErrors */ PyAPI_FUNC(void) PyErr_SyntaxLocation( diff --git a/contrib/tools/python3/src/Include/pyfpe.h b/contrib/tools/python3/src/Include/pyfpe.h deleted file mode 100644 index cc2def63aa5..00000000000 --- a/contrib/tools/python3/src/Include/pyfpe.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef Py_PYFPE_H -#define Py_PYFPE_H -/* Header excluded from the stable API */ -#ifndef Py_LIMITED_API - -/* These macros used to do something when Python was built with --with-fpectl, - * but support for that was dropped in 3.7. We continue to define them though, - * to avoid breaking API users. - */ - -#define PyFPE_START_PROTECT(err_string, leave_stmt) -#define PyFPE_END_PROTECT(v) - -#endif /* !defined(Py_LIMITED_API) */ -#endif /* !Py_PYFPE_H */ diff --git a/contrib/tools/python3/src/Include/pyhash.h b/contrib/tools/python3/src/Include/pyhash.h index 4437b870332..a314ea907b7 100644 --- a/contrib/tools/python3/src/Include/pyhash.h +++ b/contrib/tools/python3/src/Include/pyhash.h @@ -7,7 +7,7 @@ extern "C" { /* Helpers for hash functions */ #ifndef Py_LIMITED_API -PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double); +PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double); PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); // Similar to _Py_HashPointer(), but don't replace -1 with -2 PyAPI_FUNC(Py_hash_t) _Py_HashPointerRaw(const void*); @@ -29,7 +29,6 @@ PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); #define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1) #define _PyHASH_INF 314159 -#define _PyHASH_NAN 0 #define _PyHASH_IMAG _PyHASH_MULTIPLIER @@ -77,7 +76,6 @@ typedef union { } expat; } _Py_HashSecret_t; PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; -#endif #ifdef Py_DEBUG PyAPI_DATA(int) _Py_HashSecret_Initialized; @@ -85,7 +83,6 @@ PyAPI_DATA(int) _Py_HashSecret_Initialized; /* hash function definition */ -#ifndef Py_LIMITED_API typedef struct { Py_hash_t (*const hash)(const void *, Py_ssize_t); const char *name; diff --git a/contrib/tools/python3/src/Include/pylifecycle.h b/contrib/tools/python3/src/Include/pylifecycle.h index 783fcb455eb..2df7fe6e3c8 100644 --- a/contrib/tools/python3/src/Include/pylifecycle.h +++ b/contrib/tools/python3/src/Include/pylifecycle.h @@ -31,9 +31,6 @@ PyAPI_FUNC(void) _Py_NO_RETURN Py_Exit(int); /* Bootstrap __main__ (defined in Modules/main.c) */ PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); - -PyAPI_FUNC(int) Py_FrozenMain(int argc, char **argv); - PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv); /* In pathconfig.c */ diff --git a/contrib/tools/python3/src/Include/pymath.h b/contrib/tools/python3/src/Include/pymath.h index 63ca972784e..f869724334a 100644 --- a/contrib/tools/python3/src/Include/pymath.h +++ b/contrib/tools/python3/src/Include/pymath.h @@ -227,12 +227,4 @@ PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); * behavior. */ #define _Py_InIntegralTypeRange(type, v) (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) -/* Return the smallest integer k such that n < 2**k, or 0 if n == 0. - * Equivalent to floor(log2(x))+1. Also equivalent to: bitwidth_of_type - - * count_leading_zero_bits(x) - */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(unsigned int) _Py_bit_length(unsigned long d); -#endif - #endif /* Py_PYMATH_H */ diff --git a/contrib/tools/python3/src/Include/pymem.h b/contrib/tools/python3/src/Include/pymem.h index 607feb9484f..66cdb0d2973 100644 --- a/contrib/tools/python3/src/Include/pymem.h +++ b/contrib/tools/python3/src/Include/pymem.h @@ -25,8 +25,8 @@ extern "C" { heap used by the Python DLL; it could be a disaster if you free()'ed that directly in your own extension. Using PyMem_Free instead ensures Python can return the memory to the proper heap. As another example, in - PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_ - memory functions in special debugging wrappers that add additional + a debug build (Py_DEBUG macro), Python wraps all calls to all PyMem_ and + PyObject_ memory functions in special debugging wrappers that add additional debugging info to dynamic memory blocks. The system routines have no idea what to do with that stuff, and the Python wrappers have no idea what to do with raw blocks obtained directly by the system routines then. @@ -50,21 +50,10 @@ extern "C" { */ PyAPI_FUNC(void *) PyMem_Malloc(size_t size); +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_Free(void *ptr); -/* Macros. */ - -/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL - for malloc(0), which would be treated as an error. Some platforms - would return a pointer with no memory behind it, which would break - pymalloc. To solve these problems, allocate an extra byte. */ -/* Returns NULL to indicate error if a negative size or size larger than - Py_ssize_t can represent is supplied. Helps prevents security holes. */ -#define PyMem_MALLOC(n) PyMem_Malloc(n) -#define PyMem_REALLOC(p, n) PyMem_Realloc(p, n) -#define PyMem_FREE(p) PyMem_Free(p) - /* * Type-oriented memory interface * ============================== @@ -78,9 +67,6 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr); #define PyMem_New(type, n) \ ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ ( (type *) PyMem_Malloc((n) * sizeof(type)) ) ) -#define PyMem_NEW(type, n) \ - ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ - ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) ) /* * The value of (p) is always clobbered by this macro regardless of success. @@ -91,15 +77,18 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr); #define PyMem_Resize(p, type, n) \ ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) -#define PyMem_RESIZE(p, type, n) \ - ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ - (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) -/* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used - * anymore. They're just confusing aliases for PyMem_{Free,FREE} now. - */ -#define PyMem_Del PyMem_Free -#define PyMem_DEL PyMem_FREE + +// 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 #ifndef Py_LIMITED_API diff --git a/contrib/tools/python3/src/Include/pyport.h b/contrib/tools/python3/src/Include/pyport.h index d1e968bc100..07fe4712efa 100644 --- a/contrib/tools/python3/src/Include/pyport.h +++ b/contrib/tools/python3/src/Include/pyport.h @@ -101,7 +101,9 @@ typedef intptr_t Py_intptr_t; * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an * unsigned integral type). See PEP 353 for details. */ -#ifdef HAVE_SSIZE_T +#ifdef HAVE_PY_SSIZE_T + +#elif HAVE_SSIZE_T typedef ssize_t Py_ssize_t; #elif SIZEOF_VOID_P == SIZEOF_SIZE_T typedef Py_intptr_t Py_ssize_t; @@ -131,7 +133,9 @@ typedef int Py_ssize_clean_t; /* Smallest negative value of type Py_ssize_t. */ #define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) -/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf +/* Macro kept for backward compatibility: use "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" @@ -179,8 +183,9 @@ typedef int Py_ssize_clean_t; #if defined(_MSC_VER) # if defined(PY_LOCAL_AGGRESSIVE) - /* enable more aggressive optimization for visual studio */ -# pragma optimize("agtw", on) + /* enable more aggressive optimization for MSVC */ + /* active in both release and debug builds - see bpo-43271 */ +# pragma optimize("gt", on) #endif /* ignore warnings if the compiler decides not to inline a function */ # pragma warning(disable: 4710) @@ -843,12 +848,16 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #endif #if defined(__ANDROID__) || defined(__VXWORKS__) - /* Ignore the locale encoding: force UTF-8 */ + // Use UTF-8 as the locale encoding, ignore the LC_CTYPE locale. + // See _Py_GetLocaleEncoding(), PyUnicode_DecodeLocale() + // and PyUnicode_EncodeLocale(). # define _Py_FORCE_UTF8_LOCALE #endif #if defined(_Py_FORCE_UTF8_LOCALE) || defined(__APPLE__) - /* Use UTF-8 as filesystem encoding */ + // Use UTF-8 as the filesystem encoding. + // See PyUnicode_DecodeFSDefaultAndSize(), PyUnicode_EncodeFSDefault(), + // Py_DecodeLocale() and Py_EncodeLocale(). # define _Py_FORCE_UTF8_FS_ENCODING #endif @@ -856,6 +865,7 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); XLC support is intentionally omitted due to bpo-40244 */ +#ifndef _Py_NO_RETURN #if defined(__clang__) || \ (defined(__GNUC__) && \ ((__GNUC__ >= 3) || \ @@ -866,6 +876,7 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #else # define _Py_NO_RETURN #endif +#endif // Preprocessor check for a builtin preprocessor function. Always return 0 diff --git a/contrib/tools/python3/src/Include/pythonrun.h b/contrib/tools/python3/src/Include/pythonrun.h index 57529072432..b0a2fc3002d 100644 --- a/contrib/tools/python3/src/Include/pythonrun.h +++ b/contrib/tools/python3/src/Include/pythonrun.h @@ -7,194 +7,15 @@ extern "C" { #endif -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); -PyAPI_FUNC(int) PyRun_AnyFileExFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - int closeit, - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_SimpleFileExFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - int closeit, - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_InteractiveOneFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_InteractiveOneObject( - FILE *fp, - PyObject *filename, - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - PyCompilerFlags *flags); - -PyAPI_FUNC(struct _mod *) PyParser_ASTFromString( - const char *s, - const char *filename, /* decoded from the filesystem encoding */ - int start, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromStringObject( - const char *s, - PyObject *filename, - int start, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - const char* enc, - int start, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFileObject( - FILE *fp, - PyObject *filename, - const char* enc, - int start, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); -#endif - -#ifndef PyParser_SimpleParseString -#define PyParser_SimpleParseString(S, B) \ - PyParser_SimpleParseStringFlags(S, B, 0) -#define PyParser_SimpleParseFile(FP, S, B) \ - PyParser_SimpleParseFileFlags(FP, S, B, 0) -#endif - -#ifndef Py_BUILD_CORE -Py_DEPRECATED(3.9) -#endif -PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, int); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -#ifndef Py_BUILD_CORE -Py_DEPRECATED(3.9) -#endif -PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlagsFilename(const char *, - const char *, - int, int); -#endif -#ifndef Py_BUILD_CORE -Py_DEPRECATED(3.9) -#endif -PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, int, int); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, - PyObject *, PyCompilerFlags *); - -PyAPI_FUNC(PyObject *) PyRun_FileExFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - int start, - PyObject *globals, - PyObject *locals, - int closeit, - PyCompilerFlags *flags); -#endif - -#ifdef Py_LIMITED_API PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int); -#else -#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(PyObject *) Py_CompileStringExFlags( - const char *str, - const char *filename, /* decoded from the filesystem encoding */ - int start, - PyCompilerFlags *flags, - int optimize); -PyAPI_FUNC(PyObject *) Py_CompileStringObject( - const char *str, - PyObject *filename, int start, - PyCompilerFlags *flags, - int optimize); -#endif -PyAPI_FUNC(struct symtable *) Py_SymtableString( - const char *str, - const char *filename, /* decoded from the filesystem encoding */ - int start); -#ifndef Py_LIMITED_API -PyAPI_FUNC(const char *) _Py_SourceAsString( - PyObject *cmd, - const char *funcname, - const char *what, - PyCompilerFlags *cf, - PyObject **cmd_copy); - -PyAPI_FUNC(struct symtable *) Py_SymtableStringObject( - const char *str, - PyObject *filename, - int start); - -PyAPI_FUNC(struct symtable *) _Py_SymtableStringObjectFlags( - const char *str, - PyObject *filename, - int start, - PyCompilerFlags *flags); -#endif PyAPI_FUNC(void) PyErr_Print(void); PyAPI_FUNC(void) PyErr_PrintEx(int); PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); -#ifndef Py_LIMITED_API -/* A function flavor is also exported by libpython. It is required when - libpython is accessed directly rather than using header files which defines - macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to - export functions in pythonXX.dll. */ -PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l); -PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name); -PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit); -PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); -PyAPI_FUNC(int) PyRun_SimpleString(const char *s); -PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p); -PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c); -PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p); -PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p); -PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l); -PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c); -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_AnyFileEx(fp, name, closeit) \ - 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) -#define PyRun_File(fp, p, s, g, l) \ - 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) -#define PyRun_FileFlags(fp, p, s, g, l, flags) \ - PyRun_FileExFlags(fp, p, s, g, l, 0, flags) -#endif /* Stuff with no proper home (yet) */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); -#endif PyAPI_DATA(int) (*PyOS_InputHook)(void); -PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *); -#ifndef Py_LIMITED_API -PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; -#endif /* Stack size, in "pointers" (so we get extra safety margins on 64-bit platforms). On a 32-bit platform, this translates @@ -211,6 +32,12 @@ PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; PyAPI_FUNC(int) PyOS_CheckStack(void); #endif +#ifndef Py_LIMITED_API +# define Py_CPYTHON_PYTHONRUN_H +# include "cpython/pythonrun.h" +# undef Py_CPYTHON_PYTHONRUN_H +#endif + #ifdef __cplusplus } #endif diff --git a/contrib/tools/python3/src/Include/pytime.h b/contrib/tools/python3/src/Include/pytime.h deleted file mode 100644 index 2b9cbd06c3f..00000000000 --- a/contrib/tools/python3/src/Include/pytime.h +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_PYTIME_H -#define Py_PYTIME_H - -#include "pyconfig.h" /* include for defines */ -#include "object.h" - -struct timeval; - -/************************************************************************** -Symbols and macros to supply platform-independent interfaces to time related -functions and constants -**************************************************************************/ -#ifdef __cplusplus -extern "C" { -#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). */ -typedef int64_t _PyTime_t; -#define _PyTime_MIN INT64_MIN -#define _PyTime_MAX INT64_MAX - -typedef enum { - /* Round towards minus infinity (-inf). - For example, used to read a clock. */ - _PyTime_ROUND_FLOOR=0, - /* Round towards infinity (+inf). - For example, used for timeout to wait "at least" N seconds. */ - _PyTime_ROUND_CEILING=1, - /* Round to nearest with ties going to nearest even integer. - For example, used to round from a Python float. */ - _PyTime_ROUND_HALF_EVEN=2, - /* Round away from zero - For example, used for timeout. _PyTime_ROUND_CEILING rounds - -1e-9 to 0 milliseconds which causes bpo-31786 issue. - _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps - the timeout sign as expected. select.poll(timeout) must block - for negative values." */ - _PyTime_ROUND_UP=3, - /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be - used for timeouts. */ - _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP -} _PyTime_round_t; - - -/* Convert a time_t to a PyLong. */ -PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( - time_t sec); - -/* Convert a PyLong to a time_t. */ -PyAPI_FUNC(time_t) _PyLong_AsTime_t( - PyObject *obj); - -/* Convert a number of seconds, int or float, to time_t. */ -PyAPI_FUNC(int) _PyTime_ObjectToTime_t( - PyObject *obj, - time_t *sec, - _PyTime_round_t); - -/* Convert a number of seconds, int or float, to a timeval structure. - usec is in the range [0; 999999] and rounded towards zero. - For example, -1.2 is converted to (-2, 800000). */ -PyAPI_FUNC(int) _PyTime_ObjectToTimeval( - PyObject *obj, - time_t *sec, - long *usec, - _PyTime_round_t); - -/* Convert a number of seconds, int or float, to a timespec structure. - nsec is in the range [0; 999999999] and rounded towards zero. - For example, -1.2 is converted to (-2, 800000000). */ -PyAPI_FUNC(int) _PyTime_ObjectToTimespec( - PyObject *obj, - time_t *sec, - long *nsec, - _PyTime_round_t); - - -/* Create a timestamp from a number of seconds. */ -PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); - -/* Macro to create a timestamp from a number of seconds, no integer overflow. - Only use the macro for small values, prefer _PyTime_FromSeconds(). */ -#define _PYTIME_FROMSECONDS(seconds) \ - ((_PyTime_t)(seconds) * (1000 * 1000 * 1000)) - -/* Create a timestamp from a number of nanoseconds. */ -PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); - -/* Create a timestamp from nanoseconds (Python int). */ -PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, - PyObject *obj); - -/* Convert a number of seconds (Python float or int) to a timestamp. - Raise an exception and return -1 on error, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t, - PyObject *obj, - _PyTime_round_t round); - -/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp. - Raise an exception and return -1 on error, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, - PyObject *obj, - _PyTime_round_t round); - -/* Convert a timestamp to a number of seconds as a C double. */ -PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); - -/* Convert timestamp to a number of milliseconds (10^-3 seconds). */ -PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, - _PyTime_round_t round); - -/* Convert timestamp to a number of microseconds (10^-6 seconds). */ -PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t, - _PyTime_round_t round); - -/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int - object. */ -PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t); - -/* Create a timestamp from a timeval structure. - Raise an exception and return -1 on overflow, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); - -/* Convert a timestamp to a timeval structure (microsecond resolution). - tv_usec is always positive. - Raise an exception and return -1 if the conversion overflowed, - return 0 on success. */ -PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t, - struct timeval *tv, - _PyTime_round_t round); - -/* Similar to _PyTime_AsTimeval(), but don't raise an exception on error. */ -PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t, - struct timeval *tv, - _PyTime_round_t round); - -/* Convert a timestamp to a number of seconds (secs) and microseconds (us). - us is always positive. This function is similar to _PyTime_AsTimeval() - except that secs is always a time_t type, whereas the timeval structure - uses a C long for tv_sec on Windows. - Raise an exception and return -1 if the conversion overflowed, - return 0 on success. */ -PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( - _PyTime_t t, - time_t *secs, - int *us, - _PyTime_round_t round); - -#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) -/* Create a timestamp from a timespec structure. - Raise an exception and return -1 on overflow, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts); - -/* Convert a timestamp to a timespec structure (nanosecond resolution). - tv_nsec is always positive. - Raise an exception and return -1 on error, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts); -#endif - -/* Compute ticks * mul / div. - The caller must ensure that ((div - 1) * mul) cannot overflow. */ -PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks, - _PyTime_t mul, - _PyTime_t div); - -/* Get the current time from the system clock. - - The function cannot fail. _PyTime_Init() ensures that the system clock - works. */ -PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); - -/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. - The clock is not affected by system clock updates. The reference point of - the returned value is undefined, so that only the difference between the - results of consecutive calls is valid. - - The function cannot fail. _PyTime_Init() ensures that a monotonic clock - is available and works. */ -PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); - - -/* Structure used by time.get_clock_info() */ -typedef struct { - const char *implementation; - int monotonic; - int adjustable; - double resolution; -} _Py_clock_info_t; - -/* Get the current time from the system clock. - * Fill clock information if info is not NULL. - * Raise an exception and return -1 on error, return 0 on success. - */ -PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( - _PyTime_t *t, - _Py_clock_info_t *info); - -/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. - The clock is not affected by system clock updates. The reference point of - the returned value is undefined, so that only the difference between the - results of consecutive calls is valid. - - Fill info (if set) with information of the function used to get the time. - - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo( - _PyTime_t *t, - _Py_clock_info_t *info); - - -/* Initialize time. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_Init(void); - -/* Converts a timestamp to the Gregorian time, using the local time zone. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); - -/* Converts a timestamp to the Gregorian time, assuming UTC. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); - -/* Get the performance counter: clock with the highest available resolution to - measure a short duration. - - The function cannot fail. _PyTime_Init() ensures that the system clock - works. */ -PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); - -/* Get the performance counter: clock with the highest available resolution to - measure a short duration. - - Fill info (if set) with information of the function used to get the time. - - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo( - _PyTime_t *t, - _Py_clock_info_t *info); - -#ifdef __cplusplus -} -#endif - -#endif /* Py_PYTIME_H */ -#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/setobject.h b/contrib/tools/python3/src/Include/setobject.h index 119619ebe72..62516be5ab2 100644 --- a/contrib/tools/python3/src/Include/setobject.h +++ b/contrib/tools/python3/src/Include/setobject.h @@ -88,18 +88,21 @@ 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_Check(ob) \ + (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)) #define PyAnySet_Check(ob) \ (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) || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) -#define PyFrozenSet_Check(ob) \ - (Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ - PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) #ifdef __cplusplus } diff --git a/contrib/tools/python3/src/Include/structmember.h b/contrib/tools/python3/src/Include/structmember.h index b54f7081f45..93b7aff8091 100644 --- a/contrib/tools/python3/src/Include/structmember.h +++ b/contrib/tools/python3/src/Include/structmember.h @@ -62,6 +62,7 @@ typedef struct PyMemberDef { #define PY_WRITE_RESTRICTED 4 #define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED) +#define PY_AUDIT_READ READ_RESTRICTED /* Current API, use this */ PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *); diff --git a/contrib/tools/python3/src/Include/symtable.h b/contrib/tools/python3/src/Include/symtable.h deleted file mode 100644 index abd19a7923e..00000000000 --- a/contrib/tools/python3/src/Include/symtable.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_SYMTABLE_H -#define Py_SYMTABLE_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python-ast.h" /* mod_ty */ - -/* XXX(ncoghlan): This is a weird mix of public names and interpreter internal - * names. - */ - -typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock } - _Py_block_ty; - -struct _symtable_entry; - -struct symtable { - PyObject *st_filename; /* name of file being compiled, - decoded from the filesystem encoding */ - struct _symtable_entry *st_cur; /* current symbol table entry */ - struct _symtable_entry *st_top; /* symbol table entry for module */ - PyObject *st_blocks; /* dict: map AST node addresses - * to symbol table entries */ - PyObject *st_stack; /* list: stack of namespace info */ - PyObject *st_global; /* borrowed ref to st_top->ste_symbols */ - int st_nblocks; /* number of blocks used. kept for - consistency with the corresponding - compiler structure */ - PyObject *st_private; /* name of current class or NULL */ - PyFutureFeatures *st_future; /* module's future features that affect - the symbol table */ - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -}; - -typedef struct _symtable_entry { - PyObject_HEAD - PyObject *ste_id; /* int: key in ste_table->st_blocks */ - PyObject *ste_symbols; /* dict: variable names to flags */ - PyObject *ste_name; /* string: name of current block */ - 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 */ - 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, - including free refs to globals */ - unsigned ste_generator : 1; /* true if namespace is a generator */ - unsigned ste_coroutine : 1; /* true if namespace is a coroutine */ - unsigned ste_comprehension : 1; /* true if namespace is a list comprehension */ - unsigned ste_varargs : 1; /* true if block has varargs */ - unsigned ste_varkeywords : 1; /* true if block has varkeywords */ - unsigned ste_returns_value : 1; /* true if namespace uses return with - an argument */ - unsigned ste_needs_class_closure : 1; /* for class scopes, true if a - closure over __class__ - should be created */ - unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */ - 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 */ - int ste_opt_lineno; /* lineno of last exec or import * */ - int ste_opt_col_offset; /* offset of last exec or import * */ - struct symtable *ste_table; -} PySTEntryObject; - -PyAPI_DATA(PyTypeObject) PySTEntry_Type; - -#define PySTEntry_Check(op) Py_IS_TYPE(op, &PySTEntry_Type) - -PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *); - -PyAPI_FUNC(struct symtable *) PySymtable_Build( - mod_ty mod, - const char *filename, /* decoded from the filesystem encoding */ - PyFutureFeatures *future); -PyAPI_FUNC(struct symtable *) PySymtable_BuildObject( - mod_ty mod, - PyObject *filename, - PyFutureFeatures *future); -PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); - -PyAPI_FUNC(void) PySymtable_Free(struct symtable *); - -/* Flags for def-use information */ - -#define DEF_GLOBAL 1 /* global stmt */ -#define DEF_LOCAL 2 /* assignment in code block */ -#define DEF_PARAM 2<<1 /* formal parameter */ -#define DEF_NONLOCAL 2<<2 /* nonlocal stmt */ -#define USE 2<<3 /* name is used */ -#define DEF_FREE 2<<4 /* name used but not defined in nested block */ -#define DEF_FREE_CLASS 2<<5 /* free variable from class's method */ -#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_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. -*/ -#define SCOPE_OFFSET 11 -#define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL) - -#define LOCAL 1 -#define GLOBAL_EXPLICIT 2 -#define GLOBAL_IMPLICIT 3 -#define FREE 4 -#define CELL 5 - -#define GENERATOR 1 -#define GENERATOR_EXPRESSION 2 - -#ifdef __cplusplus -} -#endif -#endif /* !Py_SYMTABLE_H */ -#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/token.h b/contrib/tools/python3/src/Include/token.h index 9b8a3aae074..eb1b9ea47b4 100644 --- a/contrib/tools/python3/src/Include/token.h +++ b/contrib/tools/python3/src/Include/token.h @@ -69,8 +69,9 @@ extern "C" { #define ASYNC 56 #define TYPE_IGNORE 57 #define TYPE_COMMENT 58 -#define ERRORTOKEN 59 -#define N_TOKENS 63 +#define SOFT_KEYWORD 59 +#define ERRORTOKEN 60 +#define N_TOKENS 64 #define NT_OFFSET 256 /* Special definitions for cooperation with parser */ diff --git a/contrib/tools/python3/src/Include/typeslots.h b/contrib/tools/python3/src/Include/typeslots.h index 64f6fff5144..5800d0158bc 100644 --- a/contrib/tools/python3/src/Include/typeslots.h +++ b/contrib/tools/python3/src/Include/typeslots.h @@ -88,3 +88,7 @@ /* New in 3.5 */ #define Py_tp_finalize 80 #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 +/* New in 3.10 */ +#define Py_am_send 81 +#endif diff --git a/contrib/tools/python3/src/Include/ucnhash.h b/contrib/tools/python3/src/Include/ucnhash.h deleted file mode 100644 index 45362e997df..00000000000 --- a/contrib/tools/python3/src/Include/ucnhash.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Unicode name database interface */ -#ifndef Py_LIMITED_API -#ifndef Py_UCNHASH_H -#define Py_UCNHASH_H -#ifdef __cplusplus -extern "C" { -#endif - -/* revised ucnhash CAPI interface (exported through a "wrapper") */ - -#define PyUnicodeData_CAPSULE_NAME "unicodedata.ucnhash_CAPI" - -typedef struct { - - /* Size of this struct */ - int size; - - /* Get name for a given character code. Returns non-zero if - success, zero if not. Does not set Python exceptions. - If self is NULL, data come from the default version of the database. - If it is not NULL, it should be a unicodedata.ucd_X_Y_Z object */ - int (*getname)(PyObject *self, Py_UCS4 code, char* buffer, int buflen, - int with_alias_and_seq); - - /* Get character code for a given name. Same error handling - as for getname. */ - int (*getcode)(PyObject *self, const char* name, int namelen, Py_UCS4* code, - int with_named_seq); - -} _PyUnicode_Name_CAPI; - -#ifdef __cplusplus -} -#endif -#endif /* !Py_UCNHASH_H */ -#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/src/Include/unicodeobject.h b/contrib/tools/python3/src/Include/unicodeobject.h index 500ce242e9f..b0ac086a6be 100644 --- a/contrib/tools/python3/src/Include/unicodeobject.h +++ b/contrib/tools/python3/src/Include/unicodeobject.h @@ -261,11 +261,14 @@ PyAPI_FUNC(PyObject *) PyUnicode_FromFormat( ); PyAPI_FUNC(void) PyUnicode_InternInPlace(PyObject **); -PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); 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 **); + /* Use only if you know it's a string */ #define PyUnicode_CHECK_INTERNED(op) \ (((PyASCIIObject *)(op))->state.interned) @@ -465,6 +468,23 @@ PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String( PyObject *unicode /* Unicode object */ ); +/* Returns a pointer to the default encoding (UTF-8) of the + Unicode object unicode and the size of the encoded representation + in bytes stored in *size. + + In case of an error, no *size is set. + + This function caches the UTF-8 encoded string in the unicodeobject + and subsequent calls will return the same string. The memory is released + when the unicodeobject is deallocated. +*/ + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 +PyAPI_FUNC(const char *) PyUnicode_AsUTF8AndSize( + PyObject *unicode, + Py_ssize_t *size); +#endif + /* --- UTF-32 Codecs ------------------------------------------------------ */ /* Decodes length bytes from a UTF-32 encoded buffer string and returns diff --git a/contrib/tools/python3/src/LICENSE b/contrib/tools/python3/src/LICENSE index 739c90c2840..02a5145f0e3 100644 --- a/contrib/tools/python3/src/LICENSE +++ b/contrib/tools/python3/src/LICENSE @@ -191,9 +191,9 @@ version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with -Python 1.6.1 may be located on the Internet using the following +Python 1.6.1 may be located on the internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This -Agreement may also be obtained from a proxy server on the Internet +Agreement may also be obtained from a proxy server on the internet using the following URL: http://hdl.handle.net/1895.22/1013". 3. In the event Licensee prepares a derivative work that is based on diff --git a/contrib/tools/python3/src/Lib/__future__.py b/contrib/tools/python3/src/Lib/__future__.py index 0e7b5552343..97dc90c6e46 100644 --- a/contrib/tools/python3/src/Lib/__future__.py +++ b/contrib/tools/python3/src/Lib/__future__.py @@ -42,7 +42,7 @@ CompilerFlag is the (bitfield) flag that should be passed in the fourth argument to the builtin function compile() to enable the feature in dynamically compiled code. This flag is stored in the .compiler_flag attribute on _Future instances. These values must match the appropriate -#defines of CO_xxx flags in Include/compile.h. +#defines of CO_xxx flags in Include/cpython/compile.h. No feature line is ever to be deleted from this file. """ @@ -143,5 +143,5 @@ generator_stop = _Feature((3, 5, 0, "beta", 1), CO_FUTURE_GENERATOR_STOP) annotations = _Feature((3, 7, 0, "beta", 1), - (3, 10, 0, "alpha", 0), + (3, 11, 0, "alpha", 0), CO_FUTURE_ANNOTATIONS) diff --git a/contrib/tools/python3/src/Lib/_aix_support.py b/contrib/tools/python3/src/Lib/_aix_support.py index d27a1e8735d..45504934063 100644 --- a/contrib/tools/python3/src/Lib/_aix_support.py +++ b/contrib/tools/python3/src/Lib/_aix_support.py @@ -15,9 +15,8 @@ def _aix_tag(vrtl, bd): # type: (List[int], int) -> str # Infer the ABI bitwidth from maxsize (assuming 64 bit as the default) _sz = 32 if sys.maxsize == (2**31-1) else 64 - _bd = bd if bd != 0 else 9988 # vrtl[version, release, technology_level] - return "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(vrtl[0], vrtl[1], vrtl[2], _bd, _sz) + return "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(vrtl[0], vrtl[1], vrtl[2], bd, _sz) # extract version, release and technology level from a VRMF string @@ -27,20 +26,19 @@ def _aix_vrtl(vrmf): return [int(v[-1]), int(r), int(tl)] -def _aix_bos_rte(): +def _aix_bosmp64(): # type: () -> Tuple[str, int] """ Return a Tuple[str, int] e.g., ['7.1.4.34', 1806] - The fileset bos.rte represents the current AIX run-time level. It's VRMF and - builddate reflect the current ABI levels of the runtime environment. - If no builddate is found give a value that will satisfy pep425 related queries + The fileset bos.mp64 is the AIX kernel. It's VRMF and builddate + reflect the current ABI levels of the runtime environment. """ - # All AIX systems to have lslpp installed in this location - out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.rte"]) + # We expect all AIX systems to have lslpp installed in this location + out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.mp64"]) out = out.decode("utf-8") out = out.strip().split(":") # type: ignore - _bd = int(out[-1]) if out[-1] != '' else 9988 - return (str(out[2]), _bd) + # Use str() and int() to help mypy see types + return (str(out[2]), int(out[-1])) def aix_platform(): @@ -49,11 +47,11 @@ def aix_platform(): AIX filesets are identified by four decimal values: V.R.M.F. V (version) and R (release) can be retreived using ``uname`` Since 2007, starting with AIX 5.3 TL7, the M value has been - included with the fileset bos.rte and represents the Technology + included with the fileset bos.mp64 and represents the Technology Level (TL) of AIX. The F (Fix) value also increases, but is not relevant for comparing releases and binary compatibility. For binary compatibility the so-called builddate is needed. - Again, the builddate of an AIX release is associated with bos.rte. + Again, the builddate of an AIX release is associated with bos.mp64. AIX ABI compatibility is described as guaranteed at: https://www.ibm.com/\ support/knowledgecenter/en/ssw_aix_72/install/binary_compatability.html @@ -62,7 +60,7 @@ def aix_platform(): e.g., "aix-6107-1415-32" for AIX 6.1 TL7 bd 1415, 32-bit and, "aix-6107-1415-64" for AIX 6.1 TL7 bd 1415, 64-bit """ - vrmf, bd = _aix_bos_rte() + vrmf, bd = _aix_bosmp64() return _aix_tag(_aix_vrtl(vrmf), bd) @@ -81,7 +79,7 @@ def aix_buildtag(): Return the platform_tag of the system Python was built on. """ # AIX_BUILDDATE is defined by configure with: - # lslpp -Lcq bos.rte | awk -F: '{ print $NF }' + # lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }' build_date = sysconfig.get_config_var("AIX_BUILDDATE") try: build_date = int(build_date) diff --git a/contrib/tools/python3/src/Lib/_bootlocale.py b/contrib/tools/python3/src/Lib/_bootlocale.py deleted file mode 100644 index 3273a3b4225..00000000000 --- a/contrib/tools/python3/src/Lib/_bootlocale.py +++ /dev/null @@ -1,46 +0,0 @@ -"""A minimal subset of the locale module used at interpreter startup -(imported by the _io module), in order to reduce startup time. - -Don't import directly from third-party code; use the `locale` module instead! -""" - -import sys -import _locale - -if sys.platform.startswith("win"): - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - return _locale._getdefaultlocale()[1] -else: - try: - _locale.CODESET - except AttributeError: - if hasattr(sys, 'getandroidapilevel'): - # On Android langinfo.h and CODESET are missing, and UTF-8 is - # always used in mbstowcs() and wcstombs(). - def getpreferredencoding(do_setlocale=True): - return 'UTF-8' - else: - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - # This path for legacy systems needs the more complex - # getdefaultlocale() function, import the full locale module. - import locale - return locale.getpreferredencoding(do_setlocale) - else: - def getpreferredencoding(do_setlocale=True): - assert not do_setlocale - if sys.flags.utf8_mode: - return 'UTF-8' - result = _locale.nl_langinfo(_locale.CODESET) - if not result and sys.platform == 'darwin': - # nl_langinfo can return an empty string - # when the setting has an invalid value. - # Default to UTF-8 in that case because - # UTF-8 is the default charset on OSX and - # returning nothing will crash the - # interpreter. - result = 'UTF-8' - return result diff --git a/contrib/tools/python3/src/Lib/_collections_abc.py b/contrib/tools/python3/src/Lib/_collections_abc.py index 023ac7cf036..40417dc1d31 100644 --- a/contrib/tools/python3/src/Lib/_collections_abc.py +++ b/contrib/tools/python3/src/Lib/_collections_abc.py @@ -416,7 +416,7 @@ class Collection(Sized, Iterable, Container): class _CallableGenericAlias(GenericAlias): """ Represent `Callable[argtypes, resulttype]`. - This sets ``__args__`` to a tuple containing the flattened``argtypes`` + This sets ``__args__`` to a tuple containing the flattened ``argtypes`` followed by ``resulttype``. Example: ``Callable[[int, str], float]`` sets ``__args__`` to @@ -426,32 +426,31 @@ class _CallableGenericAlias(GenericAlias): __slots__ = () def __new__(cls, origin, args): - try: - return cls.__create_ga(origin, args) - except TypeError as exc: - import warnings - warnings.warn(f'{str(exc)} ' - f'(This will raise a TypeError in Python 3.10.)', - DeprecationWarning) - return GenericAlias(origin, args) - - @classmethod - def __create_ga(cls, origin, args): - if not isinstance(args, tuple) or len(args) != 2: + if not (isinstance(args, tuple) and len(args) == 2): raise TypeError( "Callable must be used as Callable[[arg, ...], result].") t_args, t_result = args - if isinstance(t_args, (list, tuple)): - ga_args = tuple(t_args) + (t_result,) - # This relaxes what t_args can be on purpose to allow things like - # PEP 612 ParamSpec. Responsibility for whether a user is using - # Callable[...] properly is deferred to static type checkers. - else: - ga_args = args - return super().__new__(cls, origin, ga_args) + if isinstance(t_args, list): + args = (*t_args, t_result) + elif not _is_param_expr(t_args): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {t_args}") + return super().__new__(cls, origin, args) + + @property + def __parameters__(self): + params = [] + for arg in self.__args__: + # Looks like a genericalias + if hasattr(arg, "__parameters__") and isinstance(arg.__parameters__, tuple): + params.extend(arg.__parameters__) + else: + if _is_typevarlike(arg): + params.append(arg) + return tuple(dict.fromkeys(params)) def __repr__(self): - if len(self.__args__) == 2 and self.__args__[0] is Ellipsis: + if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]): return super().__repr__() return (f'collections.abc.Callable' f'[[{", ".join([_type_repr(a) for a in self.__args__[:-1]])}], ' @@ -459,20 +458,78 @@ class _CallableGenericAlias(GenericAlias): def __reduce__(self): args = self.__args__ - if not (len(args) == 2 and args[0] is Ellipsis): + if not (len(args) == 2 and _is_param_expr(args[0])): args = list(args[:-1]), args[-1] return _CallableGenericAlias, (Callable, args) def __getitem__(self, item): # Called during TypeVar substitution, returns the custom subclass - # rather than the default types.GenericAlias object. - ga = super().__getitem__(item) - args = ga.__args__ - t_result = args[-1] - t_args = args[:-1] - args = (t_args, t_result) - return _CallableGenericAlias(Callable, args) - + # rather than the default types.GenericAlias object. Most of the + # code is copied from typing's _GenericAlias and the builtin + # types.GenericAlias. + + # A special case in PEP 612 where if X = Callable[P, int], + # then X[int, str] == X[[int, str]]. + param_len = len(self.__parameters__) + if param_len == 0: + raise TypeError(f'{self} is not a generic class') + if not isinstance(item, tuple): + item = (item,) + if (param_len == 1 and _is_param_expr(self.__parameters__[0]) + and item and not _is_param_expr(item[0])): + item = (list(item),) + item_len = len(item) + if item_len != param_len: + raise TypeError(f'Too {"many" if item_len > param_len else "few"}' + f' arguments for {self};' + f' actual {item_len}, expected {param_len}') + subst = dict(zip(self.__parameters__, item)) + new_args = [] + for arg in self.__args__: + if _is_typevarlike(arg): + if _is_param_expr(arg): + arg = subst[arg] + if not _is_param_expr(arg): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {arg}") + else: + arg = subst[arg] + # Looks like a GenericAlias + elif hasattr(arg, '__parameters__') and isinstance(arg.__parameters__, tuple): + subparams = arg.__parameters__ + if subparams: + subargs = tuple(subst[x] for x in subparams) + arg = arg[subargs] + if isinstance(arg, tuple): + new_args.extend(arg) + else: + new_args.append(arg) + + # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612 + if not isinstance(new_args[0], list): + t_result = new_args[-1] + t_args = new_args[:-1] + new_args = (t_args, t_result) + return _CallableGenericAlias(Callable, tuple(new_args)) + + +def _is_typevarlike(arg): + obj = type(arg) + # looks like a TypeVar/ParamSpec + return (obj.__module__ == 'typing' + and obj.__name__ in {'ParamSpec', 'TypeVar'}) + +def _is_param_expr(obj): + """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or + ``_ConcatenateGenericAlias`` from typing.py + """ + if obj is Ellipsis: + return True + if isinstance(obj, list): + return True + obj = type(obj) + names = ('ParamSpec', '_ConcatenateGenericAlias') + return obj.__module__ == 'typing' and any(obj.__name__ == name for name in names) def _type_repr(obj): """Return the repr() of an object, special-casing types (internal helper). @@ -514,7 +571,6 @@ class Callable(metaclass=ABCMeta): class Set(Collection): - """A set is a finite, iterable container. This class provides concrete generic implementations of all @@ -740,19 +796,19 @@ MutableSet.register(set) ### MAPPINGS ### - class Mapping(Collection): - - __slots__ = () - """A Mapping is a generic container for associating key/value pairs. This class provides concrete generic implementations of all methods except for __getitem__, __iter__, and __len__. - """ + __slots__ = () + + # Tell ABCMeta.__new__ that this class should have TPFLAGS_MAPPING set. + __abc_tpflags__ = 1 << 6 # Py_TPFLAGS_MAPPING + @abstractmethod def __getitem__(self, key): raise KeyError @@ -791,7 +847,6 @@ class Mapping(Collection): __reversed__ = None - Mapping.register(mappingproxy) @@ -874,18 +929,16 @@ ValuesView.register(dict_values) class MutableMapping(Mapping): - - __slots__ = () - """A MutableMapping is a generic container for associating key/value pairs. This class provides concrete generic implementations of all methods except for __getitem__, __setitem__, __delitem__, __iter__, and __len__. - """ + __slots__ = () + @abstractmethod def __setitem__(self, key, value): raise KeyError @@ -962,9 +1015,7 @@ MutableMapping.register(dict) ### SEQUENCES ### - class Sequence(Reversible, Collection): - """All the operations on a read-only sequence. Concrete subclasses must override __new__ or __init__, @@ -973,6 +1024,9 @@ class Sequence(Reversible, Collection): __slots__ = () + # Tell ABCMeta.__new__ that this class should have TPFLAGS_SEQUENCE set. + __abc_tpflags__ = 1 << 5 # Py_TPFLAGS_SEQUENCE + @abstractmethod def __getitem__(self, index): raise IndexError @@ -1024,7 +1078,6 @@ class Sequence(Reversible, Collection): 'S.count(value) -> integer -- return number of occurrences of value' return sum(1 for v in self if v is value or v == value) - Sequence.register(tuple) Sequence.register(str) Sequence.register(range) @@ -1032,7 +1085,6 @@ Sequence.register(memoryview) class ByteString(Sequence): - """This unifies bytes and bytearray. XXX Should add all their methods. @@ -1045,16 +1097,14 @@ ByteString.register(bytearray) class MutableSequence(Sequence): - - __slots__ = () - """All the operations on a read-write sequence. Concrete subclasses must provide __new__ or __init__, __getitem__, __setitem__, __delitem__, __len__, and insert(). - """ + __slots__ = () + @abstractmethod def __setitem__(self, index, value): raise IndexError diff --git a/contrib/tools/python3/src/Lib/_compression.py b/contrib/tools/python3/src/Lib/_compression.py index b00f31b400c..e8b70aa0a3e 100644 --- a/contrib/tools/python3/src/Lib/_compression.py +++ b/contrib/tools/python3/src/Lib/_compression.py @@ -1,7 +1,7 @@ """Internal classes used by the gzip, lzma and bz2 modules""" import io - +import sys BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE # Compressed data read chunk size @@ -110,6 +110,16 @@ class DecompressReader(io.RawIOBase): self._pos += len(data) return data + def readall(self): + chunks = [] + # sys.maxsize means the max length of output buffer is unlimited, + # so that the whole input buffer can be decompressed within one + # .decompress() call. + while data := self.read(sys.maxsize): + chunks.append(data) + + return b"".join(chunks) + # Rewind the file to the beginning of the data stream. def _rewind(self): self._fp.seek(0) diff --git a/contrib/tools/python3/src/Lib/_markupbase.py b/contrib/tools/python3/src/Lib/_markupbase.py index 2af5f1c23b6..3ad7e279960 100644 --- a/contrib/tools/python3/src/Lib/_markupbase.py +++ b/contrib/tools/python3/src/Lib/_markupbase.py @@ -29,10 +29,6 @@ class ParserBase: raise RuntimeError( "_markupbase.ParserBase must be subclassed") - def error(self, message): - raise NotImplementedError( - "subclasses of ParserBase must override error()") - def reset(self): self.lineno = 1 self.offset = 0 @@ -131,12 +127,11 @@ class ParserBase: # also in data attribute specifications of attlist declaration # also link type declaration subsets in linktype declarations # also link attribute specification lists in link declarations - self.error("unsupported '[' char in %s declaration" % decltype) + raise AssertionError("unsupported '[' char in %s declaration" % decltype) else: - self.error("unexpected '[' char in declaration") + raise AssertionError("unexpected '[' char in declaration") else: - self.error( - "unexpected %r char in declaration" % rawdata[j]) + raise AssertionError("unexpected %r char in declaration" % rawdata[j]) if j < 0: return j return -1 # incomplete @@ -156,7 +151,9 @@ class ParserBase: # look for MS Office ]> ending match= _msmarkedsectionclose.search(rawdata, i+3) else: - self.error('unknown status keyword %r in marked section' % rawdata[i+3:j]) + raise AssertionError( + 'unknown status keyword %r in marked section' % rawdata[i+3:j] + ) if not match: return -1 if report: @@ -168,7 +165,7 @@ class ParserBase: def parse_comment(self, i, report=1): rawdata = self.rawdata if rawdata[i:i+4] != ' diff --git a/contrib/tools/python3/src/Lib/codecs.py b/contrib/tools/python3/src/Lib/codecs.py index d2edd148a29..e6ad6e3a052 100644 --- a/contrib/tools/python3/src/Lib/codecs.py +++ b/contrib/tools/python3/src/Lib/codecs.py @@ -83,7 +83,7 @@ BOM64_BE = BOM_UTF32_BE class CodecInfo(tuple): """Codec details when looking up the codec registry""" - # Private API to allow Python 3.4 to blacklist the known non-Unicode + # Private API to allow Python 3.4 to denylist the known non-Unicode # codecs in the standard library. A more general mechanism to # reliably distinguish test encodings from other codecs will hopefully # be defined for Python 3.5 diff --git a/contrib/tools/python3/src/Lib/codeop.py b/contrib/tools/python3/src/Lib/codeop.py index 4c10470aee7..568e9bbc118 100644 --- a/contrib/tools/python3/src/Lib/codeop.py +++ b/contrib/tools/python3/src/Lib/codeop.py @@ -10,30 +10,6 @@ and: syntax error (OverflowError and ValueError can be produced by malformed literals). -Approach: - -First, check if the source consists entirely of blank lines and -comments; if so, replace it with 'pass', because the built-in -parser doesn't always do the right thing for these. - -Compile three times: as is, with \n, and with \n\n appended. If it -compiles as is, it's complete. If it compiles with one \n appended, -we expect more. If it doesn't compile either way, we compare the -error we get when compiling with \n or \n\n appended. If the errors -are the same, the code is broken. But if the errors are different, we -expect more. Not intuitive; not even guaranteed to hold in future -releases; but this matches the compiler's behavior from Python 1.4 -through 2.2, at least. - -Caveat: - -It is possible (but not likely) that the parser stops parsing with a -successful outcome before reaching the end of the source; in this -case, trailing symbols may be ignored instead of causing an error. -For example, a backslash followed by two newlines may be followed by -arbitrary garbage. This will be fixed once the API for the parser is -better. - The two interfaces are: compile_command(source, filename, symbol): @@ -64,24 +40,25 @@ _features = [getattr(__future__, fname) __all__ = ["compile_command", "Compile", "CommandCompiler"] -PyCF_DONT_IMPLY_DEDENT = 0x200 # Matches pythonrun.h +# The following flags match the values from Include/cpython/compile.h +# Caveat emptor: These flags are undocumented on purpose and depending +# on their effect outside the standard library is **unsupported**. +PyCF_DONT_IMPLY_DEDENT = 0x200 +PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000 def _maybe_compile(compiler, source, filename, symbol): - # Check for source consisting of only blank lines and comments + # Check for source consisting of only blank lines and comments. for line in source.split("\n"): line = line.strip() if line and line[0] != '#': - break # Leave it alone + break # Leave it alone. else: if symbol != "eval": source = "pass" # Replace it with a 'pass' statement - err = err1 = err2 = None - code = code1 = code2 = None - try: - code = compiler(source, filename, symbol) - except SyntaxError: + return compiler(source, filename, symbol) + except SyntaxError: # Let other compile() errors propagate. pass # Catch syntax warnings after the first compile @@ -90,25 +67,23 @@ def _maybe_compile(compiler, source, filename, symbol): warnings.simplefilter("error") try: - code1 = compiler(source + "\n", filename, symbol) + compiler(source + "\n", filename, symbol) except SyntaxError as e: - err1 = e - - try: - code2 = compiler(source + "\n\n", filename, symbol) - except SyntaxError as e: - err2 = e - - try: - if code: - return code - if not code1 and repr(err1) == repr(err2): - raise err1 - finally: - err1 = err2 = None + if "incomplete input" in str(e): + return None + raise + +def _is_syntax_error(err1, err2): + rep1 = repr(err1) + rep2 = repr(err2) + if "was never closed" in rep1 and "was never closed" in rep2: + return False + if rep1 == rep2: + return True + return False def _compile(source, filename, symbol): - return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) + return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT) def compile_command(source, filename="", symbol="single"): r"""Compile a command and determine whether it is incomplete. @@ -137,7 +112,7 @@ class Compile: statement, it "remembers" and compiles all subsequent program texts with the statement in force.""" def __init__(self): - self.flags = PyCF_DONT_IMPLY_DEDENT + self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT def __call__(self, source, filename, symbol): codeob = compile(source, filename, symbol, self.flags, True) diff --git a/contrib/tools/python3/src/Lib/collections/__init__.py b/contrib/tools/python3/src/Lib/collections/__init__.py index 5bdd3b3516d..818588f7403 100644 --- a/contrib/tools/python3/src/Lib/collections/__init__.py +++ b/contrib/tools/python3/src/Lib/collections/__init__.py @@ -27,7 +27,6 @@ __all__ = [ ] import _collections_abc -import heapq as _heapq import sys as _sys from itertools import chain as _chain @@ -52,22 +51,6 @@ except ImportError: pass -def __getattr__(name): - # For backwards compatibility, continue to make the collections ABCs - # through Python 3.6 available through the collections module. - # Note, no new collections ABCs were added in Python 3.7 - if name in _collections_abc.__all__: - obj = getattr(_collections_abc, name) - import warnings - warnings.warn("Using or importing the ABCs from 'collections' instead " - "of from 'collections.abc' is deprecated since Python 3.3, " - "and in 3.10 it will stop working", - DeprecationWarning, stacklevel=2) - globals()[name] = obj - return obj - raise AttributeError(f'module {__name__!r} has no attribute {name!r}') - - ################################################################################ ### OrderedDict ################################################################################ @@ -489,6 +472,7 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non '__repr__': __repr__, '_asdict': _asdict, '__getnewargs__': __getnewargs__, + '__match_args__': field_names, } for index, name in enumerate(field_names): doc = _sys.intern(f'Alias for field number {index}') @@ -597,6 +581,10 @@ class Counter(dict): # Needed so that self[missing_item] does not raise KeyError return 0 + def total(self): + 'Sum of the counts' + return sum(self.values()) + def most_common(self, n=None): '''List the n most common elements and their counts from the most common to the least. If n is None, then list all element counts. @@ -608,7 +596,10 @@ class Counter(dict): # Emulate Bag.sortedByCount from Smalltalk if n is None: return sorted(self.items(), key=_itemgetter(1), reverse=True) - return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) + + # Lazy import to speedup Python startup time + import heapq + return heapq.nlargest(n, self.items(), key=_itemgetter(1)) def elements(self): '''Iterator over elements repeating each as many times as its count. @@ -719,6 +710,42 @@ class Counter(dict): if elem in self: super().__delitem__(elem) + def __eq__(self, other): + 'True if all counts agree. Missing counts are treated as zero.' + if not isinstance(other, Counter): + return NotImplemented + return all(self[e] == other[e] for c in (self, other) for e in c) + + def __ne__(self, other): + 'True if any counts disagree. Missing counts are treated as zero.' + if not isinstance(other, Counter): + return NotImplemented + return not self == other + + def __le__(self, other): + 'True if all counts in self are a subset of those in other.' + if not isinstance(other, Counter): + return NotImplemented + return all(self[e] <= other[e] for c in (self, other) for e in c) + + def __lt__(self, other): + 'True if all counts in self are a proper subset of those in other.' + if not isinstance(other, Counter): + return NotImplemented + return self <= other and self != other + + def __ge__(self, other): + 'True if all counts in self are a superset of those in other.' + if not isinstance(other, Counter): + return NotImplemented + return all(self[e] >= other[e] for c in (self, other) for e in c) + + def __gt__(self, other): + 'True if all counts in self are a proper superset of those in other.' + if not isinstance(other, Counter): + return NotImplemented + return self >= other and self != other + def __repr__(self): if not self: return f'{self.__class__.__name__}()' @@ -739,12 +766,30 @@ class Counter(dict): # To strip negative and zero counts, add-in an empty counter: # c += Counter() # - # Rich comparison operators for multiset subset and superset tests - # are deliberately omitted due to semantic conflicts with the - # existing inherited dict equality method. Subset and superset - # semantics ignore zero counts and require that p≤q ∧ p≥q → p=q; - # however, that would not be the case for p=Counter(a=1, b=0) - # and q=Counter(a=1) where the dictionaries are not equal. + # Results are ordered according to when an element is first + # encountered in the left operand and then by the order + # encountered in the right operand. + # + # When the multiplicities are all zero or one, multiset operations + # are guaranteed to be equivalent to the corresponding operations + # for regular sets. + # Given counter multisets such as: + # cp = Counter(a=1, b=0, c=1) + # cq = Counter(c=1, d=0, e=1) + # The corresponding regular sets would be: + # sp = {'a', 'c'} + # sq = {'c', 'e'} + # All of the following relations would hold: + # set(cp + cq) == sp | sq + # set(cp - cq) == sp - sq + # set(cp | cq) == sp | sq + # set(cp & cq) == sp & sq + # (cp == cq) == (sp == sq) + # (cp != cq) == (sp != sq) + # (cp <= cq) == (sp <= sq) + # (cp < cq) == (sp < sq) + # (cp >= cq) == (sp >= sq) + # (cp > cq) == (sp > sq) def __add__(self, other): '''Add counts from two counters. @@ -973,12 +1018,15 @@ class ChainMap(_collections_abc.MutableMapping): __copy__ = copy - def new_child(self, m=None): # like Django's Context.push() + def new_child(self, m=None, **kwargs): # like Django's Context.push() '''New ChainMap with a new map followed by all previous maps. If no map is provided, an empty dict is used. + Keyword arguments update the map or new empty dict. ''' if m is None: - m = {} + m = kwargs + elif kwargs: + m.update(kwargs) return self.__class__(m, *self.maps) @property diff --git a/contrib/tools/python3/src/Lib/colorsys.py b/contrib/tools/python3/src/Lib/colorsys.py index b93e3844067..0f52512a67d 100644 --- a/contrib/tools/python3/src/Lib/colorsys.py +++ b/contrib/tools/python3/src/Lib/colorsys.py @@ -75,17 +75,18 @@ def yiq_to_rgb(y, i, q): def rgb_to_hls(r, g, b): maxc = max(r, g, b) minc = min(r, g, b) - # XXX Can optimize (maxc+minc) and (maxc-minc) - l = (minc+maxc)/2.0 + sumc = (maxc+minc) + rangec = (maxc-minc) + l = sumc/2.0 if minc == maxc: return 0.0, l, 0.0 if l <= 0.5: - s = (maxc-minc) / (maxc+minc) + s = rangec / sumc else: - s = (maxc-minc) / (2.0-maxc-minc) - rc = (maxc-r) / (maxc-minc) - gc = (maxc-g) / (maxc-minc) - bc = (maxc-b) / (maxc-minc) + s = rangec / (2.0-sumc) + rc = (maxc-r) / rangec + gc = (maxc-g) / rangec + bc = (maxc-b) / rangec if r == maxc: h = bc-gc elif g == maxc: diff --git a/contrib/tools/python3/src/Lib/compileall.py b/contrib/tools/python3/src/Lib/compileall.py index 25ad83c2290..3755e76ba81 100644 --- a/contrib/tools/python3/src/Lib/compileall.py +++ b/contrib/tools/python3/src/Lib/compileall.py @@ -84,12 +84,14 @@ def compile_dir(dir, maxlevels=None, ddir=None, force=False, if workers < 0: raise ValueError('workers must be greater or equal to 0') if workers != 1: + # Check if this is a system where ProcessPoolExecutor can function. + from concurrent.futures.process import _check_system_limits try: - # Only import when needed, as low resource platforms may - # fail to import it - from concurrent.futures import ProcessPoolExecutor - except ImportError: + _check_system_limits() + except NotImplementedError: workers = 1 + else: + from concurrent.futures import ProcessPoolExecutor if maxlevels is None: maxlevels = sys.getrecursionlimit() files = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels) @@ -404,7 +406,8 @@ def main(): # if flist is provided then load it if args.flist: try: - with (sys.stdin if args.flist=='-' else open(args.flist)) as f: + with (sys.stdin if args.flist=='-' else + open(args.flist, encoding="utf-8")) as f: for line in f: compile_dests.append(line.strip()) except OSError: diff --git a/contrib/tools/python3/src/Lib/concurrent/futures/process.py b/contrib/tools/python3/src/Lib/concurrent/futures/process.py index a29e5247ab8..6ee2ce626e4 100644 --- a/contrib/tools/python3/src/Lib/concurrent/futures/process.py +++ b/contrib/tools/python3/src/Lib/concurrent/futures/process.py @@ -532,6 +532,14 @@ def _check_system_limits(): if _system_limited: raise NotImplementedError(_system_limited) _system_limits_checked = True + try: + import multiprocessing.synchronize + except ImportError: + _system_limited = ( + "This Python build lacks multiprocessing.synchronize, usually due " + "to named semaphores being unavailable on this platform." + ) + raise NotImplementedError(_system_limited) try: nsems_max = os.sysconf("SC_SEM_NSEMS_MAX") except (AttributeError, ValueError): diff --git a/contrib/tools/python3/src/Lib/configparser.py b/contrib/tools/python3/src/Lib/configparser.py index 8dd5c13bcc0..3470624e63f 100644 --- a/contrib/tools/python3/src/Lib/configparser.py +++ b/contrib/tools/python3/src/Lib/configparser.py @@ -316,7 +316,7 @@ class ParsingError(Error): def filename(self): """Deprecated, use `source'.""" warnings.warn( - "The 'filename' attribute will be removed in future versions. " + "The 'filename' attribute will be removed in Python 3.12. " "Use 'source' instead.", DeprecationWarning, stacklevel=2 ) @@ -326,7 +326,7 @@ class ParsingError(Error): def filename(self, value): """Deprecated, user `source'.""" warnings.warn( - "The 'filename' attribute will be removed in future versions. " + "The 'filename' attribute will be removed in Python 3.12. " "Use 'source' instead.", DeprecationWarning, stacklevel=2 ) @@ -563,7 +563,7 @@ class RawConfigParser(MutableMapping): # Regular expressions for parsing section headers and options _SECT_TMPL = r""" \[ # [ - (?P
[^]]+) # very permissive! + (?P
.+) # very permissive! \] # ] """ _OPT_TMPL = r""" @@ -690,6 +690,7 @@ class RawConfigParser(MutableMapping): """ if isinstance(filenames, (str, bytes, os.PathLike)): filenames = [filenames] + encoding = io.text_encoding(encoding) read_ok = [] for filename in filenames: try: @@ -756,7 +757,7 @@ class RawConfigParser(MutableMapping): def readfp(self, fp, filename=None): """Deprecated, use read_file instead.""" warnings.warn( - "This method will be removed in future versions. " + "This method will be removed in Python 3.12. " "Use 'parser.read_file()' instead.", DeprecationWarning, stacklevel=2 ) @@ -1231,7 +1232,7 @@ class SafeConfigParser(ConfigParser): super().__init__(*args, **kwargs) warnings.warn( "The SafeConfigParser class has been renamed to ConfigParser " - "in Python 3.2. This alias will be removed in future versions." + "in Python 3.2. This alias will be removed in Python 3.12." " Use ConfigParser directly instead.", DeprecationWarning, stacklevel=2 ) diff --git a/contrib/tools/python3/src/Lib/contextlib.py b/contrib/tools/python3/src/Lib/contextlib.py index 4e8f5f75939..c63a8492e2d 100644 --- a/contrib/tools/python3/src/Lib/contextlib.py +++ b/contrib/tools/python3/src/Lib/contextlib.py @@ -9,7 +9,7 @@ from types import MethodType, GenericAlias __all__ = ["asynccontextmanager", "contextmanager", "closing", "nullcontext", "AbstractContextManager", "AbstractAsyncContextManager", "AsyncExitStack", "ContextDecorator", "ExitStack", - "redirect_stdout", "redirect_stderr", "suppress"] + "redirect_stdout", "redirect_stderr", "suppress", "aclosing"] class AbstractContextManager(abc.ABC): @@ -80,6 +80,22 @@ class ContextDecorator(object): return inner +class AsyncContextDecorator(object): + "A base class or mixin that enables async context managers to work as decorators." + + def _recreate_cm(self): + """Return a recreated instance of self. + """ + return self + + def __call__(self, func): + @wraps(func) + async def inner(*args, **kwds): + async with self._recreate_cm(): + return await func(*args, **kwds) + return inner + + class _GeneratorContextManagerBase: """Shared functionality for @contextmanager and @asynccontextmanager.""" @@ -168,9 +184,11 @@ class _GeneratorContextManager( return False raise RuntimeError("generator didn't stop after throw()") - -class _AsyncGeneratorContextManager(_GeneratorContextManagerBase, - AbstractAsyncContextManager): +class _AsyncGeneratorContextManager( + _GeneratorContextManagerBase, + AbstractAsyncContextManager, + AsyncContextDecorator, +): """Helper for @asynccontextmanager decorator.""" async def __aenter__(self): @@ -178,14 +196,14 @@ class _AsyncGeneratorContextManager(_GeneratorContextManagerBase, # they are only needed for recreation, which is not possible anymore del self.args, self.kwds, self.func try: - return await self.gen.__anext__() + return await anext(self.gen) except StopAsyncIteration: raise RuntimeError("generator didn't yield") from None async def __aexit__(self, typ, value, traceback): if typ is None: try: - await self.gen.__anext__() + await anext(self.gen) except StopAsyncIteration: return False else: @@ -322,6 +340,32 @@ class closing(AbstractContextManager): self.thing.close() +class aclosing(AbstractAsyncContextManager): + """Async context manager for safely finalizing an asynchronously cleaned-up + resource such as an async generator, calling its ``aclose()`` method. + + Code like this: + + async with aclosing(.fetch()) as agen: + + + is equivalent to this: + + agen = .fetch() + try: + + finally: + await agen.aclose() + + """ + def __init__(self, thing): + self.thing = thing + async def __aenter__(self): + return self.thing + async def __aexit__(self, *exc_info): + await self.thing.aclose() + + class _RedirectStream(AbstractContextManager): _stream = None @@ -674,7 +718,7 @@ class AsyncExitStack(_BaseExitStack, AbstractAsyncContextManager): return received_exc and suppressed_exc -class nullcontext(AbstractContextManager): +class nullcontext(AbstractContextManager, AbstractAsyncContextManager): """Context manager that does no additional processing. Used as a stand-in for a normal context manager, when a particular @@ -693,3 +737,9 @@ class nullcontext(AbstractContextManager): def __exit__(self, *excinfo): pass + + async def __aenter__(self): + return self.enter_result + + async def __aexit__(self, *excinfo): + pass diff --git a/contrib/tools/python3/src/Lib/copy.py b/contrib/tools/python3/src/Lib/copy.py index 1081d43952e..69bac980be2 100644 --- a/contrib/tools/python3/src/Lib/copy.py +++ b/contrib/tools/python3/src/Lib/copy.py @@ -192,6 +192,7 @@ d[bytes] = _deepcopy_atomic d[str] = _deepcopy_atomic d[types.CodeType] = _deepcopy_atomic d[type] = _deepcopy_atomic +d[range] = _deepcopy_atomic d[types.BuiltinFunctionType] = _deepcopy_atomic d[types.FunctionType] = _deepcopy_atomic d[weakref.ref] = _deepcopy_atomic diff --git a/contrib/tools/python3/src/Lib/copyreg.py b/contrib/tools/python3/src/Lib/copyreg.py index 7ab8c128eb0..356db6f083e 100644 --- a/contrib/tools/python3/src/Lib/copyreg.py +++ b/contrib/tools/python3/src/Lib/copyreg.py @@ -36,6 +36,12 @@ else: pickle(complex, pickle_complex, complex) +def pickle_union(obj): + import functools, operator + return functools.reduce, (operator.or_, obj.__args__) + +pickle(type(int | str), pickle_union) + # Support for pickling new-style objects def _reconstructor(cls, base, state): diff --git a/contrib/tools/python3/src/Lib/csv.py b/contrib/tools/python3/src/Lib/csv.py index dc85077f3ec..bb3ee269ae7 100644 --- a/contrib/tools/python3/src/Lib/csv.py +++ b/contrib/tools/python3/src/Lib/csv.py @@ -409,14 +409,10 @@ class Sniffer: continue # skip rows that have irregular number of columns for col in list(columnTypes.keys()): - - for thisType in [int, float, complex]: - try: - thisType(row[col]) - break - except (ValueError, OverflowError): - pass - else: + thisType = complex + try: + thisType(row[col]) + except (ValueError, OverflowError): # fallback to length of string thisType = len(row[col]) diff --git a/contrib/tools/python3/src/Lib/dataclasses.py b/contrib/tools/python3/src/Lib/dataclasses.py index 5ff67ad2ea9..105a95b9554 100644 --- a/contrib/tools/python3/src/Lib/dataclasses.py +++ b/contrib/tools/python3/src/Lib/dataclasses.py @@ -6,8 +6,9 @@ import inspect import keyword import builtins import functools +import abc import _thread -from types import GenericAlias +from types import FunctionType, GenericAlias __all__ = ['dataclass', @@ -15,6 +16,7 @@ __all__ = ['dataclass', 'Field', 'FrozenInstanceError', 'InitVar', + 'KW_ONLY', 'MISSING', # Helper functions. @@ -151,6 +153,20 @@ __all__ = ['dataclass', # # See _hash_action (below) for a coded version of this table. +# __match_args__ +# +# +--- match_args= parameter +# | +# v | | | +# | no | yes | <--- class has __match_args__ in __dict__? +# +=======+=======+=======+ +# | False | | | +# +-------+-------+-------+ +# | True | add | | <- the default +# +=======+=======+=======+ +# __match_args__ is always added unless the class already defines it. It is a +# tuple of __init__ parameter names; non-init fields must be matched by keyword. + # Raised when an attempt is made to modify a frozen class. class FrozenInstanceError(AttributeError): pass @@ -169,6 +185,12 @@ class _MISSING_TYPE: pass MISSING = _MISSING_TYPE() +# A sentinel object to indicate that following fields are keyword-only by +# default. Use a class to give it a better repr. +class _KW_ONLY_TYPE: + pass +KW_ONLY = _KW_ONLY_TYPE() + # Since most per-field metadata will be unused, create an empty # read-only proxy that can be shared among all fields. _EMPTY_METADATA = types.MappingProxyType({}) @@ -217,7 +239,6 @@ class InitVar: def __class_getitem__(cls, type): return InitVar(type) - # Instances of Field are only ever created from within this module, # and only from the field() function, although Field instances are # exposed externally as (conceptually) read-only objects. @@ -238,11 +259,12 @@ class Field: 'init', 'compare', 'metadata', + 'kw_only', '_field_type', # Private: not to be used by user code. ) def __init__(self, default, default_factory, init, repr, hash, compare, - metadata): + metadata, kw_only): self.name = None self.type = None self.default = default @@ -254,6 +276,7 @@ class Field: self.metadata = (_EMPTY_METADATA if metadata is None else types.MappingProxyType(metadata)) + self.kw_only = kw_only self._field_type = None def __repr__(self): @@ -267,6 +290,7 @@ class Field: f'hash={self.hash!r},' f'compare={self.compare!r},' f'metadata={self.metadata!r},' + f'kw_only={self.kw_only!r},' f'_field_type={self._field_type}' ')') @@ -320,17 +344,19 @@ class _DataclassParams: # so that a type checker can be told (via overloads) that this is a # function whose type depends on its parameters. def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, - hash=None, compare=True, metadata=None): + hash=None, compare=True, metadata=None, kw_only=MISSING): """Return an object to identify dataclass fields. default is the default value of the field. default_factory is a 0-argument function called to initialize a field's value. If init - is True, the field will be a parameter to the class's __init__() - function. If repr is True, the field will be included in the - object's repr(). If hash is True, the field will be included in - the object's hash(). If compare is True, the field will be used - in comparison functions. metadata, if specified, must be a - mapping which is stored but not otherwise examined by dataclass. + is true, the field will be a parameter to the class's __init__() + function. If repr is true, the field will be included in the + object's repr(). If hash is true, the field will be included in the + object's hash(). If compare is true, the field will be used in + comparison functions. metadata, if specified, must be a mapping + which is stored but not otherwise examined by dataclass. If kw_only + is true, the field will become a keyword-only parameter to + __init__(). It is an error to specify both default and default_factory. """ @@ -338,7 +364,16 @@ def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, if default is not MISSING and default_factory is not MISSING: raise ValueError('cannot specify both default and default_factory') return Field(default, default_factory, init, repr, hash, compare, - metadata) + metadata, kw_only) + + +def _fields_in_init_order(fields): + # Returns the fields as __init__ will output them. It returns 2 tuples: + # the first for normal args, and the second for keyword args. + + return (tuple(f for f in fields if f.init and not f.kw_only), + tuple(f for f in fields if f.init and f.kw_only) + ) def _tuple_str(obj_name, fields): @@ -395,7 +430,6 @@ def _create_fn(name, args, body, *, globals=None, locals=None, local_vars = ', '.join(locals.keys()) txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}" - ns = {} exec(txt, globals, ns) return ns['__create_fn__'](**locals) @@ -413,7 +447,7 @@ def _field_assign(frozen, name, value, self_name): return f'{self_name}.{name}={value}' -def _field_init(f, frozen, globals, self_name): +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. @@ -453,9 +487,15 @@ def _field_init(f, frozen, globals, self_name): globals[default_name] = f.default value = f.name else: - # This field does not need initialization. Signify that - # to the caller by returning None. - return None + # If the class has slots, then initialize this field. + if slots and f.default is not MISSING: + globals[default_name] = f.default + value = default_name + else: + # This field does not need initialization: reading from it will + # just use the class attribute that contains the default. + # Signify that to the caller by returning None. + return None # Only test this now, so that we can create variables for the # default. However, return None to signify that we're not going @@ -486,7 +526,8 @@ def _init_param(f): return f'{f.name}:_type_{f.name}{default}' -def _init_fn(fields, frozen, has_post_init, self_name, globals): +def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init, + self_name, globals, slots): # fields contains both real fields and InitVar pseudo-fields. # Make sure we don't have fields without defaults following fields @@ -494,9 +535,10 @@ def _init_fn(fields, frozen, has_post_init, self_name, globals): # function source code, but catching it here gives a better error # message, and future-proofs us in case we build up the function # using ast. + seen_default = False - for f in fields: - # Only consider fields in the __init__ call. + for f in std_fields: + # Only consider the non-kw-only fields in the __init__ call. if f.init: if not (f.default is MISSING and f.default_factory is MISSING): seen_default = True @@ -512,7 +554,7 @@ def _init_fn(fields, frozen, has_post_init, self_name, globals): body_lines = [] for f in fields: - line = _field_init(f, frozen, locals, self_name) + line = _field_init(f, frozen, locals, self_name, slots) # line is None means that this field doesn't require # initialization (it's a pseudo-field). Just skip it. if line: @@ -528,8 +570,15 @@ def _init_fn(fields, frozen, has_post_init, self_name, globals): if not body_lines: body_lines = ['pass'] + _init_params = [_init_param(f) for f in std_fields] + if kw_only_fields: + # Add the keyword-only args. Because the * can only be added if + # there's at least one keyword-only arg, there needs to be a test here + # (instead of just concatenting the lists together). + _init_params += ['*'] + _init_params += [_init_param(f) for f in kw_only_fields] return _create_fn('__init__', - [self_name] + [_init_param(f) for f in fields if f.init], + [self_name] + _init_params, body_lines, locals=locals, globals=globals, @@ -608,6 +657,9 @@ def _is_initvar(a_type, dataclasses): return (a_type is dataclasses.InitVar or type(a_type) is dataclasses.InitVar) +def _is_kw_only(a_type, dataclasses): + return a_type is dataclasses.KW_ONLY + def _is_type(annotation, cls, a_module, a_type, is_type_predicate): # Given a type annotation string, does it refer to a_type in @@ -668,10 +720,11 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate): return False -def _get_field(cls, a_name, a_type): - # Return a Field object for this field name and type. ClassVars - # and InitVars are also returned, but marked as such (see - # f._field_type). +def _get_field(cls, a_name, a_type, default_kw_only): + # Return a Field object for this field name and type. ClassVars and + # InitVars are also returned, but marked as such (see f._field_type). + # default_kw_only is the value of kw_only to use if there isn't a field() + # that defines it. # If the default value isn't derived from Field, then it's only a # normal default value. Convert it to a Field(). @@ -742,6 +795,19 @@ def _get_field(cls, a_name, a_type): # init=)? It makes no sense for # ClassVar and InitVar to specify init=. + # kw_only validation and assignment. + if f._field_type in (_FIELD, _FIELD_INITVAR): + # For real and InitVar fields, if kw_only wasn't specified use the + # default value. + if f.kw_only is MISSING: + f.kw_only = default_kw_only + else: + # Make sure kw_only isn't set for ClassVars + assert f._field_type is _FIELD_CLASSVAR + if f.kw_only is not MISSING: + raise TypeError(f'field {f.name} is a ClassVar but specifies ' + 'kw_only') + # For real fields, disallow mutable defaults for known types. if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)): raise ValueError(f'mutable default {type(f.default)} for field ' @@ -749,12 +815,19 @@ def _get_field(cls, a_name, a_type): return f +def _set_qualname(cls, value): + # Ensure that the functions returned from _create_fn uses the proper + # __qualname__ (the class they belong to). + if isinstance(value, FunctionType): + value.__qualname__ = f"{cls.__qualname__}.{value.__name__}" + return value def _set_new_attribute(cls, name, value): # Never overwrites an existing attribute. Returns True if the # attribute already exists. if name in cls.__dict__: return True + _set_qualname(cls, value) setattr(cls, name, value) return False @@ -769,7 +842,7 @@ def _hash_set_none(cls, fields, globals): def _hash_add(cls, fields, globals): flds = [f for f in fields if (f.compare if f.hash is None else f.hash)] - return _hash_fn(flds, globals) + return _set_qualname(cls, _hash_fn(flds, globals)) def _hash_exception(cls, fields, globals): # Raise an exception. @@ -806,7 +879,8 @@ _hash_action = {(False, False, False, False): None, # version of this table. -def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): +def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, + match_args, kw_only, slots): # Now that dicts retain insertion order, there's no reason to use # an ordered dict. I am leveraging that ordering here, because # derived class fields overwrite base class fields, but the order @@ -860,8 +934,27 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): # Now find fields in our class. While doing so, validate some # things, and set the default values (as class attributes) where # we can. - cls_fields = [_get_field(cls, name, type) - for name, type in cls_annotations.items()] + cls_fields = [] + # Get a reference to this module for the _is_kw_only() test. + KW_ONLY_seen = False + dataclasses = sys.modules[__name__] + for name, type in cls_annotations.items(): + # See if this is a marker to change the value of kw_only. + if (_is_kw_only(type, dataclasses) + or (isinstance(type, str) + and _is_type(type, cls, dataclasses, dataclasses.KW_ONLY, + _is_kw_only))): + # Switch the default to kw_only=True, and ignore this + # annotation: it's not a real field. + if KW_ONLY_seen: + raise TypeError(f'{name!r} is KW_ONLY, but KW_ONLY ' + 'has already been specified') + KW_ONLY_seen = True + kw_only = True + else: + # Otherwise it's a field of some type. + cls_fields.append(_get_field(cls, name, type, kw_only)) + for f in cls_fields: fields[f.name] = f @@ -916,15 +1009,22 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): if order and not eq: raise ValueError('eq must be true if order is true') + # Include InitVars and regular fields (so, not ClassVars). This is + # initialized here, outside of the "if init:" test, because std_init_fields + # is used with match_args, below. + all_init_fields = [f for f in fields.values() + if f._field_type in (_FIELD, _FIELD_INITVAR)] + (std_init_fields, + kw_only_init_fields) = _fields_in_init_order(all_init_fields) + if init: # Does this class have a post-init function? has_post_init = hasattr(cls, _POST_INIT_NAME) - # Include InitVars and regular fields (so, not ClassVars). - flds = [f for f in fields.values() - if f._field_type in (_FIELD, _FIELD_INITVAR)] _set_new_attribute(cls, '__init__', - _init_fn(flds, + _init_fn(all_init_fields, + std_init_fields, + kw_only_init_fields, frozen, has_post_init, # The name to use for the "self" @@ -933,6 +1033,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): '__dataclass_self__' if 'self' in fields else 'self', globals, + slots, )) # Get the fields as a list, and include only real fields. This is @@ -992,11 +1093,70 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): cls.__doc__ = (cls.__name__ + str(inspect.signature(cls)).replace(' -> None', '')) + if match_args: + # I could probably compute this once + _set_new_attribute(cls, '__match_args__', + tuple(f.name for f in std_init_fields)) + + if slots: + cls = _add_slots(cls, frozen) + + abc.update_abstractmethods(cls) + + return cls + + +# _dataclass_getstate and _dataclass_setstate are needed for pickling frozen +# classes with slots. These could be slighly more performant if we generated +# the code instead of iterating over fields. But that can be a project for +# another day, if performance becomes an issue. +def _dataclass_getstate(self): + return [getattr(self, f.name) for f in fields(self)] + + +def _dataclass_setstate(self, state): + for field, value in zip(fields(self), state): + # use setattr because dataclass may be frozen + object.__setattr__(self, field.name, value) + + +def _add_slots(cls, is_frozen): + # Need to create a new class, since we can't set __slots__ + # after a class has been created. + + # Make sure __slots__ isn't already set. + if '__slots__' in cls.__dict__: + raise TypeError(f'{cls.__name__} already specifies __slots__') + + # Create a new dict for our new class. + cls_dict = dict(cls.__dict__) + field_names = tuple(f.name for f in fields(cls)) + cls_dict['__slots__'] = field_names + for field_name in field_names: + # Remove our attributes, if present. They'll still be + # available in _MARKER. + cls_dict.pop(field_name, None) + + # Remove __dict__ itself. + cls_dict.pop('__dict__', None) + + # And finally create the class. + qualname = getattr(cls, '__qualname__', None) + cls = type(cls)(cls.__name__, cls.__bases__, cls_dict) + if qualname is not None: + cls.__qualname__ = qualname + + if is_frozen: + # Need this for pickling frozen classes with slots. + cls.__getstate__ = _dataclass_getstate + cls.__setstate__ = _dataclass_setstate + return cls def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, - unsafe_hash=False, frozen=False): + unsafe_hash=False, frozen=False, match_args=True, + kw_only=False, slots=False): """Returns the same class as was passed in, with dunder methods added based on the fields defined in the class. @@ -1006,11 +1166,15 @@ def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, repr is true, a __repr__() method is added. If order is true, rich comparison dunder methods are added. If unsafe_hash is true, a __hash__() method function is added. If frozen is true, fields may - not be assigned to after instance creation. + not be assigned to after instance creation. If match_args is true, + the __match_args__ tuple is added. If kw_only is true, then by + default all fields are keyword-only. If slots is true, an + __slots__ attribute is added. """ def wrap(cls): - return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen) + return _process_class(cls, init, repr, eq, order, unsafe_hash, + frozen, match_args, kw_only, slots) # See if we're being called as @dataclass or @dataclass(). if cls is None: @@ -1169,7 +1333,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): + frozen=False, match_args=True, kw_only=False, slots=False): """Return a new dynamically created dataclass. The dataclass name will be 'cls_name'. 'fields' is an iterable @@ -1195,14 +1359,12 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, if namespace is None: namespace = {} - else: - # Copy namespace since we're going to mutate it. - namespace = namespace.copy() # While we're looking through the field names, validate that they # are identifiers, are not keywords, and not duplicates. seen = set() - anns = {} + annotations = {} + defaults = {} for item in fields: if isinstance(item, str): name = item @@ -1211,7 +1373,7 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, name, tp, = item elif len(item) == 3: name, tp, spec = item - namespace[name] = spec + defaults[name] = spec else: raise TypeError(f'Invalid field: {item!r}') @@ -1223,14 +1385,22 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, raise TypeError(f'Field name duplicated: {name!r}') seen.add(name) - anns[name] = tp + annotations[name] = tp + + # Update 'ns' with the user-supplied namespace plus our calculated values. + def exec_body_callback(ns): + ns.update(namespace) + ns.update(defaults) + ns['__annotations__'] = annotations - namespace['__annotations__'] = anns # We use `types.new_class()` instead of simply `type()` to allow dynamic creation - # of generic dataclassses. - cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace)) + # of generic dataclasses. + cls = types.new_class(cls_name, bases, {}, exec_body_callback) + + # Apply the normal decorator. return dataclass(cls, init=init, repr=repr, eq=eq, order=order, - unsafe_hash=unsafe_hash, frozen=frozen) + unsafe_hash=unsafe_hash, frozen=frozen, + match_args=match_args, kw_only=kw_only, slots=slots) def replace(obj, /, **changes): diff --git a/contrib/tools/python3/src/Lib/datetime.py b/contrib/tools/python3/src/Lib/datetime.py index 23d2bf09181..6bf37ccfab7 100644 --- a/contrib/tools/python3/src/Lib/datetime.py +++ b/contrib/tools/python3/src/Lib/datetime.py @@ -11,6 +11,7 @@ __all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", 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 @@ -380,42 +381,10 @@ def _check_utc_offset(name, offset): "-timedelta(hours=24) and timedelta(hours=24)" % (name, offset)) -def _check_int_field(value): - if isinstance(value, int): - return value - if isinstance(value, float): - raise TypeError('integer argument expected, got float') - try: - value = value.__index__() - except AttributeError: - pass - else: - if not isinstance(value, int): - raise TypeError('__index__ returned non-int (type %s)' % - type(value).__name__) - return value - orig = value - try: - value = value.__int__() - except AttributeError: - pass - else: - if not isinstance(value, int): - raise TypeError('__int__ returned non-int (type %s)' % - type(value).__name__) - import warnings - warnings.warn("an integer is required (got type %s)" % - type(orig).__name__, - DeprecationWarning, - stacklevel=2) - return value - raise TypeError('an integer is required (got type %s)' % - type(value).__name__) - def _check_date_fields(year, month, day): - year = _check_int_field(year) - month = _check_int_field(month) - day = _check_int_field(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: @@ -426,10 +395,10 @@ def _check_date_fields(year, month, day): return year, month, day def _check_time_fields(hour, minute, second, microsecond, fold): - hour = _check_int_field(hour) - minute = _check_int_field(minute) - second = _check_int_field(second) - microsecond = _check_int_field(microsecond) + 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: @@ -2541,10 +2510,10 @@ 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_int_field, _check_time_fields, + _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, _is_leap, _isoweek1monday, _math, + _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) diff --git a/contrib/tools/python3/src/Lib/dis.py b/contrib/tools/python3/src/Lib/dis.py index e289e176c78..fe5d24e8805 100644 --- a/contrib/tools/python3/src/Lib/dis.py +++ b/contrib/tools/python3/src/Lib/dis.py @@ -338,8 +338,11 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None, argval, argrepr = _get_const_info(arg, constants) elif op in hasname: argval, argrepr = _get_name_info(arg, names) + elif op in hasjabs: + argval = arg*2 + argrepr = "to " + repr(argval) elif op in hasjrel: - argval = offset + 2 + arg + argval = offset + 2 + arg*2 argrepr = "to " + repr(argval) elif op in haslocal: argval, argrepr = _get_name_info(arg, varnames) @@ -384,7 +387,7 @@ def _disassemble_bytes(code, lasti=-1, varnames=None, names=None, constants=None, cells=None, linestarts=None, *, file=None, line_offset=0): # Omit the line number column entirely if we have no line number info - show_lineno = linestarts is not None + show_lineno = bool(linestarts) if show_lineno: maxlineno = max(linestarts.values()) + line_offset if maxlineno >= 1000: @@ -425,6 +428,7 @@ def _unpack_opargs(code): extended_arg = (arg << 8) if op == EXTENDED_ARG else 0 else: arg = None + extended_arg = 0 yield (i, op, arg) def findlabels(code): @@ -437,9 +441,9 @@ def findlabels(code): for offset, op, arg in _unpack_opargs(code): if arg is not None: if op in hasjrel: - label = offset + 2 + arg + label = offset + 2 + arg*2 elif op in hasjabs: - label = arg + label = arg*2 else: continue if label not in labels: @@ -449,32 +453,15 @@ def findlabels(code): def findlinestarts(code): """Find the offsets in a byte code which are start of lines in the source. - Generate pairs (offset, lineno) as described in Python/compile.c. - + Generate pairs (offset, lineno) """ - byte_increments = code.co_lnotab[0::2] - line_increments = code.co_lnotab[1::2] - bytecode_len = len(code.co_code) - - lastlineno = None - lineno = code.co_firstlineno - addr = 0 - for byte_incr, line_incr in zip(byte_increments, line_increments): - if byte_incr: - if lineno != lastlineno: - yield (addr, lineno) - lastlineno = lineno - addr += byte_incr - if addr >= bytecode_len: - # The rest of the lnotab byte offsets are past the end of - # the bytecode, so the lines were optimized away. - return - if line_incr >= 0x80: - # line_increments is an array of 8-bit signed integers - line_incr -= 0x100 - lineno += line_incr - if lineno != lastlineno: - yield (addr, lineno) + lastline = None + for start, end, line in code.co_lines(): + if line is not None and line != lastline: + lastline = line + yield start, line + return + class Bytecode: """The bytecode operations of a piece of code diff --git a/contrib/tools/python3/src/Lib/distutils/__init__.py b/contrib/tools/python3/src/Lib/distutils/__init__.py index d823d040a1c..fdad6f65a78 100644 --- a/contrib/tools/python3/src/Lib/distutils/__init__.py +++ b/contrib/tools/python3/src/Lib/distutils/__init__.py @@ -9,5 +9,12 @@ used from a setup script as """ 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/contrib/tools/python3/src/Lib/distutils/command/__init__.py b/contrib/tools/python3/src/Lib/distutils/command/__init__.py index 481eea9fd4b..fd0bfae7ade 100644 --- a/contrib/tools/python3/src/Lib/distutils/command/__init__.py +++ b/contrib/tools/python3/src/Lib/distutils/command/__init__.py @@ -19,7 +19,6 @@ __all__ = ['build', 'bdist', 'bdist_dumb', 'bdist_rpm', - 'bdist_wininst', 'check', 'upload', # These two are reserved for future use: diff --git a/contrib/tools/python3/src/Lib/distutils/command/bdist.py b/contrib/tools/python3/src/Lib/distutils/command/bdist.py index 014871d280e..d580a8090bd 100644 --- a/contrib/tools/python3/src/Lib/distutils/command/bdist.py +++ b/contrib/tools/python3/src/Lib/distutils/command/bdist.py @@ -62,7 +62,7 @@ class bdist(Command): # Establish the preferred order (for the --help-formats option). format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar', - 'wininst', 'zip', 'msi'] + 'zip', 'msi'] # And the real information. format_command = {'rpm': ('bdist_rpm', "RPM distribution"), @@ -71,8 +71,6 @@ class bdist(Command): 'xztar': ('bdist_dumb', "xz'ed tar file"), 'ztar': ('bdist_dumb', "compressed tar file"), 'tar': ('bdist_dumb', "tar file"), - 'wininst': ('bdist_wininst', - "Windows executable installer"), 'zip': ('bdist_dumb', "ZIP file"), 'msi': ('bdist_msi', "Microsoft Installer") } diff --git a/contrib/tools/python3/src/Lib/distutils/command/bdist_msi.py b/contrib/tools/python3/src/Lib/distutils/command/bdist_msi.py index 0863a1883e7..2ed017b4d66 100644 --- a/contrib/tools/python3/src/Lib/distutils/command/bdist_msi.py +++ b/contrib/tools/python3/src/Lib/distutils/command/bdist_msi.py @@ -1,7 +1,5 @@ # Copyright (C) 2005, 2006 Martin von Löwis # Licensed to PSF under a Contributor Agreement. -# The bdist_wininst command proper -# based on bdist_wininst """ Implements the bdist_msi command. """ diff --git a/contrib/tools/python3/src/Lib/distutils/command/bdist_wininst.py b/contrib/tools/python3/src/Lib/distutils/command/bdist_wininst.py deleted file mode 100644 index 0e9ddaa2141..00000000000 --- a/contrib/tools/python3/src/Lib/distutils/command/bdist_wininst.py +++ /dev/null @@ -1,377 +0,0 @@ -"""distutils.command.bdist_wininst - -Implements the Distutils 'bdist_wininst' command: create a windows installer -exe-program.""" - -import os -import sys -import warnings -from distutils.core import Command -from distutils.util import get_platform -from distutils.dir_util import remove_tree -from distutils.errors import * -from distutils.sysconfig import get_python_version -from distutils import log - -class bdist_wininst(Command): - - description = "create an executable installer for MS Windows" - - user_options = [('bdist-dir=', None, - "temporary directory for creating the distribution"), - ('plat-name=', 'p', - "platform name to embed in generated filenames " - "(default: %s)" % get_platform()), - ('keep-temp', 'k', - "keep the pseudo-installation tree around after " + - "creating the distribution archive"), - ('target-version=', None, - "require a specific python version" + - " on the target system"), - ('no-target-compile', 'c', - "do not compile .py to .pyc on the target system"), - ('no-target-optimize', 'o', - "do not compile .py to .pyo (optimized) " - "on the target system"), - ('dist-dir=', 'd', - "directory to put final built distributions in"), - ('bitmap=', 'b', - "bitmap to use for the installer instead of python-powered logo"), - ('title=', 't', - "title to display on the installer background instead of default"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), - ('install-script=', None, - "basename of installation script to be run after " - "installation or before deinstallation"), - ('pre-install-script=', None, - "Fully qualified filename of a script to be run before " - "any files are installed. This script need not be in the " - "distribution"), - ('user-access-control=', None, - "specify Vista's UAC handling - 'none'/default=no " - "handling, 'auto'=use UAC if target Python installed for " - "all users, 'force'=always use UAC"), - ] - - boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', - 'skip-build'] - - # bpo-10945: bdist_wininst requires mbcs encoding only available on Windows - _unsupported = (sys.platform != "win32") - - def __init__(self, *args, **kw): - super().__init__(*args, **kw) - warnings.warn("bdist_wininst command is deprecated since Python 3.8, " - "use bdist_wheel (wheel packages) instead", - DeprecationWarning, 2) - - def initialize_options(self): - self.bdist_dir = None - self.plat_name = None - self.keep_temp = 0 - self.no_target_compile = 0 - self.no_target_optimize = 0 - self.target_version = None - self.dist_dir = None - self.bitmap = None - self.title = None - self.skip_build = None - self.install_script = None - self.pre_install_script = None - self.user_access_control = None - - - def finalize_options(self): - self.set_undefined_options('bdist', ('skip_build', 'skip_build')) - - if self.bdist_dir is None: - if self.skip_build and self.plat_name: - # If build is skipped and plat_name is overridden, bdist will - # not see the correct 'plat_name' - so set that up manually. - bdist = self.distribution.get_command_obj('bdist') - bdist.plat_name = self.plat_name - # next the command will be initialized using that name - bdist_base = self.get_finalized_command('bdist').bdist_base - self.bdist_dir = os.path.join(bdist_base, 'wininst') - - if not self.target_version: - self.target_version = "" - - if not self.skip_build and self.distribution.has_ext_modules(): - short_version = get_python_version() - if self.target_version and self.target_version != short_version: - raise DistutilsOptionError( - "target version can only be %s, or the '--skip-build'" \ - " option must be specified" % (short_version,)) - self.target_version = short_version - - self.set_undefined_options('bdist', - ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name'), - ) - - if self.install_script: - for script in self.distribution.scripts: - if self.install_script == os.path.basename(script): - break - else: - raise DistutilsOptionError( - "install_script '%s' not found in scripts" - % self.install_script) - - def run(self): - if (sys.platform != "win32" and - (self.distribution.has_ext_modules() or - self.distribution.has_c_libraries())): - raise DistutilsPlatformError \ - ("distribution contains extensions and/or C libraries; " - "must be compiled on a Windows 32 platform") - - 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 - install.plat_name = self.plat_name - - install_lib = self.reinitialize_command('install_lib') - # we do not want to include pyc or pyo files - install_lib.compile = 0 - install_lib.optimize = 0 - - if self.distribution.has_ext_modules(): - # If we are building an installer for a Python version other - # than the one we are currently running, then we need to ensure - # our build_lib reflects the other Python version rather than ours. - # Note that for target_version!=sys.version, we must have skipped the - # build step, so there is no issue with enforcing the build of this - # version. - target_version = self.target_version - if not target_version: - assert self.skip_build, "Should have already checked this" - target_version = '%d.%d' % sys.version_info[:2] - plat_specifier = ".%s-%s" % (self.plat_name, target_version) - build = self.get_finalized_command('build') - build.build_lib = os.path.join(build.build_base, - 'lib' + plat_specifier) - - # Use a custom scheme for the zip-file, because we have to decide - # at installation time which scheme to use. - for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): - value = key.upper() - if key == 'headers': - value = value + '/Include/$dist_name' - setattr(install, - 'install_' + key, - value) - - log.info("installing to %s", self.bdist_dir) - install.ensure_finalized() - - # avoid warning of 'install_lib' about installing - # into a directory not in sys.path - sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) - - install.run() - - del sys.path[0] - - # And make an archive relative to the root of the - # pseudo-installation tree. - from tempfile import mktemp - archive_basename = mktemp() - fullname = self.distribution.get_fullname() - arcname = self.make_archive(archive_basename, "zip", - root_dir=self.bdist_dir) - # create an exe containing the zip-file - self.create_exe(arcname, fullname, self.bitmap) - if self.distribution.has_ext_modules(): - pyversion = get_python_version() - else: - pyversion = 'any' - self.distribution.dist_files.append(('bdist_wininst', pyversion, - self.get_installer_filename(fullname))) - # remove the zip-file again - log.debug("removing temporary file '%s'", arcname) - os.remove(arcname) - - if not self.keep_temp: - remove_tree(self.bdist_dir, dry_run=self.dry_run) - - def get_inidata(self): - # Return data describing the installation. - lines = [] - metadata = self.distribution.metadata - - # Write the [metadata] section. - lines.append("[metadata]") - - # 'info' will be displayed in the installer's dialog box, - # describing the items to be installed. - info = (metadata.long_description or '') + '\n' - - # Escape newline characters - def escape(s): - return s.replace("\n", "\\n") - - for name in ["author", "author_email", "description", "maintainer", - "maintainer_email", "name", "url", "version"]: - data = getattr(metadata, name, "") - if data: - info = info + ("\n %s: %s" % \ - (name.capitalize(), escape(data))) - lines.append("%s=%s" % (name, escape(data))) - - # The [setup] section contains entries controlling - # the installer runtime. - lines.append("\n[Setup]") - if self.install_script: - lines.append("install_script=%s" % self.install_script) - lines.append("info=%s" % escape(info)) - lines.append("target_compile=%d" % (not self.no_target_compile)) - lines.append("target_optimize=%d" % (not self.no_target_optimize)) - if self.target_version: - lines.append("target_version=%s" % self.target_version) - if self.user_access_control: - lines.append("user_access_control=%s" % self.user_access_control) - - title = self.title or self.distribution.get_fullname() - lines.append("title=%s" % escape(title)) - import time - import distutils - build_info = "Built %s with distutils-%s" % \ - (time.ctime(time.time()), distutils.__version__) - lines.append("build_info=%s" % build_info) - return "\n".join(lines) - - def create_exe(self, arcname, fullname, bitmap=None): - import struct - - self.mkpath(self.dist_dir) - - cfgdata = self.get_inidata() - - installer_name = self.get_installer_filename(fullname) - self.announce("creating %s" % installer_name) - - if bitmap: - with open(bitmap, "rb") as f: - bitmapdata = f.read() - bitmaplen = len(bitmapdata) - else: - bitmaplen = 0 - - with open(installer_name, "wb") as file: - file.write(self.get_exe_bytes()) - if bitmap: - file.write(bitmapdata) - - # Convert cfgdata from unicode to ascii, mbcs encoded - if isinstance(cfgdata, str): - cfgdata = cfgdata.encode("mbcs") - - # Append the pre-install script - cfgdata = cfgdata + b"\0" - if self.pre_install_script: - # We need to normalize newlines, so we open in text mode and - # convert back to bytes. "latin-1" simply avoids any possible - # failures. - with open(self.pre_install_script, "r", - encoding="latin-1") as script: - script_data = script.read().encode("latin-1") - cfgdata = cfgdata + script_data + b"\n\0" - else: - # empty pre-install script - cfgdata = cfgdata + b"\0" - file.write(cfgdata) - - # The 'magic number' 0x1234567B is used to make sure that the - # binary layout of 'cfgdata' is what the wininst.exe binary - # expects. If the layout changes, increment that number, make - # the corresponding changes to the wininst.exe sources, and - # recompile them. - header = struct.pack("", 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', @@ -64,11 +86,6 @@ if HAS_USER_SITE: 'data' : '$userbase', } -# The keys to an installation scheme; if any new types of files are to be -# installed, be sure to add an entry to every installation scheme above, -# and to SCHEME_KEYS here. -SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') - class install(Command): @@ -169,8 +186,9 @@ class install(Command): self.install_lib = None # set to either purelib or platlib self.install_scripts = None self.install_data = None - self.install_userbase = USER_BASE - self.install_usersite = USER_SITE + if HAS_USER_SITE: + self.install_userbase = USER_BASE + self.install_usersite = USER_SITE self.compile = None self.optimize = None @@ -305,6 +323,9 @@ class install(Command): 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()") @@ -343,8 +364,9 @@ class install(Command): # Convert directories from Unix /-separated syntax to the local # convention. self.convert_paths('lib', 'purelib', 'platlib', - 'scripts', 'data', 'headers', - 'userbase', 'usersite') + 'scripts', 'data', 'headers') + if HAS_USER_SITE: + self.convert_paths('userbase', 'usersite') # Deprecated # Well, we're not actually fully completely finalized yet: we still diff --git a/contrib/tools/python3/src/Lib/distutils/extension.py b/contrib/tools/python3/src/Lib/distutils/extension.py index c507da360aa..e85032ece89 100644 --- a/contrib/tools/python3/src/Lib/distutils/extension.py +++ b/contrib/tools/python3/src/Lib/distutils/extension.py @@ -4,6 +4,7 @@ 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 @@ -161,7 +162,7 @@ def read_setup_file(filename): line = file.readline() if line is None: # eof break - if _variable_rx.match(line): # VAR=VALUE, handled in first pass + if re.match(_variable_rx, line): # VAR=VALUE, handled in first pass continue if line[0] == line[-1] == "*": diff --git a/contrib/tools/python3/src/Lib/distutils/sysconfig.py b/contrib/tools/python3/src/Lib/distutils/sysconfig.py index 4e5464705b8..3414a761e76 100644 --- a/contrib/tools/python3/src/Lib/distutils/sysconfig.py +++ b/contrib/tools/python3/src/Lib/distutils/sysconfig.py @@ -13,298 +13,69 @@ import _imp import os import re import sys +import warnings -from .errors import DistutilsPlatformError - -# These are needed in a couple of spots, so just compute them once. -PREFIX = os.path.normpath(sys.prefix) -EXEC_PREFIX = os.path.normpath(sys.exec_prefix) -BASE_PREFIX = os.path.normpath(sys.base_prefix) -BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) - -# Path to the base directory of the project. On Windows the binary may -# live in project/PCbuild/win32 or project/PCbuild/amd64. -# set for cross builds -if "_PYTHON_PROJECT_BASE" in os.environ: - project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"]) -else: - if sys.executable: - project_base = os.path.dirname(os.path.abspath(sys.executable)) - else: - # sys.executable can be empty if argv[0] has been changed and Python is - # unable to retrieve the real program name - project_base = os.getcwd() - - -# python_build: (Boolean) if true, we're either building Python or -# building an extension with an un-installed Python, so we use -# different (hard-wired) directories. -def _is_python_source_dir(d): - for fn in ("Setup", "Setup.local"): - if os.path.isfile(os.path.join(d, "Modules", fn)): - return True - return False - -_sys_home = getattr(sys, '_home', None) - -if os.name == 'nt': - def _fix_pcbuild(d): - if d and os.path.normcase(d).startswith( - os.path.normcase(os.path.join(PREFIX, "PCbuild"))): - return PREFIX - return d - project_base = _fix_pcbuild(project_base) - _sys_home = _fix_pcbuild(_sys_home) - -def _python_build(): - if _sys_home: - return _is_python_source_dir(_sys_home) - return _is_python_source_dir(project_base) - -python_build = _python_build() - - -# 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 get_python_version(): - """Return a string containing the major and minor Python version, - leaving off the patchlevel. Sample return values could be '1.5' - or '2.2'. - """ - return '%d.%d' % sys.version_info[:2] - - -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 _sys_home or 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) - - - -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. - global _config_vars - # Use get_config_var() to ensure _config_vars is initialized. - if not get_config_var('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_config_h_filename(): - """Return full pathname of installed pyconfig.h file.""" - if python_build: - if os.name == "nt": - inc_dir = os.path.join(_sys_home or project_base, "PC") - else: - inc_dir = _sys_home or project_base - else: - inc_dir = get_python_inc(plat_specific=1) - - return os.path.join(inc_dir, 'pyconfig.h') - - -def get_makefile_filename(): - """Return full pathname of installed Makefile from the Python build.""" - if python_build: - return os.path.join(_sys_home or project_base, "Makefile") - lib_dir = get_python_lib(plat_specific=0, standard_lib=1) - config_file = 'config-{}{}'.format(get_python_version(), build_flags) - if hasattr(sys.implementation, '_multiarch'): - config_file += '-%s' % sys.implementation._multiarch - return os.path.join(lib_dir, config_file, 'Makefile') +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, + _is_python_source_dir, + _sys_home, + + _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() + +if os.name == "nt": + from sysconfig import _fix_pcbuild + +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): - """Parse a config.h-style file. + return sysconfig_parse_config_h(fp, vars=g) - 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. - """ - if g is None: - g = {} - define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") - undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") - # - while True: - line = fp.readline() - if not line: - break - m = define_rx.match(line) - if m: - n, v = m.group(1, 2) - try: v = int(v) - except ValueError: pass - g[n] = v - else: - m = undef_rx.match(line) - if m: - g[m.group(1)] = 0 - return 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) -# Regexes needed for parsing Makefile (and similar syntaxes, -# like old-style Setup files). -_variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") -_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") -_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") +# 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. @@ -321,7 +92,7 @@ def parse_makefile(fn, g=None): line = fp.readline() if line is None: # eof break - m = _variable_rx.match(line) + m = re.match(_variable_rx, line) if m: n, v = m.group(1, 2) v = v.strip() @@ -349,7 +120,7 @@ def parse_makefile(fn, g=None): while notdone: for name in list(notdone): value = notdone[name] - m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + m = re.search(_findvar1_rx, value) or re.search(_findvar2_rx, value) if m: n = m.group(1) found = True @@ -408,148 +179,173 @@ def parse_makefile(fn, g=None): return g -def expand_makefile_vars(s, vars): - """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in - 'string' according to 'vars' (a dictionary mapping variable names to - values). Variables not present in 'vars' are silently expanded to the - empty string. The variable values in 'vars' should not contain further - variable expansions; if 'vars' is the output of 'parse_makefile()', - you're fine. Returns a variable-expanded version of 's'. +# 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' - # This algorithm does multiple expansion, so if vars['foo'] contains - # "${bar}", it will expand ${foo} to ${bar}, and then expand - # ${bar}... and so forth. This is fine as long as 'vars' comes from - # 'parse_makefile()', which takes care of such expansions eagerly, - # according to make's variable expansion semantics. + (cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \ + get_config_vars('CC', 'CXX', 'CFLAGS', + 'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS') - while True: - m = _findvar1_rx.search(s) or _findvar2_rx.search(s) - if m: - (beg, end) = m.span() - s = s[0:beg] + vars.get(m.group(1)) + s[end:] + 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: - break - return s - - -_config_vars = None - -def _init_posix(): - """Initialize the module as appropriate for POSIX systems.""" - # _sysconfigdata is generated at build time, see the sysconfig module - #name = os.environ.get('_PYTHON_SYSCONFIGDATA_NAME', - # '_sysconfigdata_{abi}_{platform}_{multiarch}'.format( - # abi=sys.abiflags, - # platform=sys.platform, - # multiarch=getattr(sys.implementation, '_multiarch', ''), - #)) - #_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) - #build_time_vars = _temp.build_time_vars - global _config_vars - _config_vars = {'SO': '.so'} - #_config_vars.update(build_time_vars) - - -def _init_nt(): - """Initialize the module as appropriate for NT""" - g = {} - # set basic install directories - g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) - g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) - - # XXX hmmm.. a normal install puts include files here - g['INCLUDEPY'] = get_python_inc(plat_specific=0) - - g['EXT_SUFFIX'] = _imp.extension_suffixes()[0] - g['EXE'] = ".exe" - g['VERSION'] = get_python_version().replace(".", "") - g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable)) - - global _config_vars - _config_vars = g - - -def get_config_vars(*args): - """With no arguments, return a dictionary of all configuration - variables relevant for the current platform. Generally this includes - everything needed to build extensions and install both pure modules and - extensions. On Unix, this means every variable defined in Python's - installed Makefile; on Windows it's a much smaller set. - - 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: - func = globals().get("_init_" + os.name) - if func: - func() + 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: - _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 - - # For backward compatibility, see issue19555 - SO = _config_vars.get('EXT_SUFFIX') - if SO is not None: - _config_vars['SO'] = SO - - # 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) + 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 _sys_home or project_base 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'] = os.path.abspath(os.path.normpath(srcdir)) - - # Convert srcdir into an absolute path if it appears necessary. - # Normally it is relative to the build directory. However, during - # testing, for example, we might be running a non-installed python - # from a different directory. - if python_build and os.name == "posix": - base = project_base - if (not os.path.isabs(_config_vars['srcdir']) and - base != os.getcwd()): - # srcdir is relative and we are not in the same directory - # as the executable. Assume executable is in the build - # directory and make srcdir absolute. - srcdir = os.path.join(base, _config_vars['srcdir']) - _config_vars['srcdir'] = os.path.normpath(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) - - if args: - vals = [] - for name in args: - vals.append(_config_vars.get(name)) - return vals + 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: - return _config_vars + 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). -def get_config_var(name): - """Return the value of a single variable using the dictionary - returned by 'get_config_vars()'. Equivalent to - get_config_vars().get(name) + 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 name == 'SO': - import warnings - warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2) - return get_config_vars().get(name) + 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/contrib/tools/python3/src/Lib/distutils/util.py b/contrib/tools/python3/src/Lib/distutils/util.py index 4b002ecef1d..2ce5c5b64d6 100644 --- a/contrib/tools/python3/src/Lib/distutils/util.py +++ b/contrib/tools/python3/src/Lib/distutils/util.py @@ -9,6 +9,7 @@ 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 @@ -419,8 +420,10 @@ byte_compile(files, optimize=%r, force=%r, 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, diff --git a/contrib/tools/python3/src/Lib/doctest.py b/contrib/tools/python3/src/Lib/doctest.py index 54ae93bcf19..80a14bccfbf 100644 --- a/contrib/tools/python3/src/Lib/doctest.py +++ b/contrib/tools/python3/src/Lib/doctest.py @@ -102,7 +102,7 @@ import re import sys import traceback import unittest -from io import StringIO +from io import StringIO, IncrementalNewlineDecoder from collections import namedtuple TestResults = namedtuple('TestResults', 'failed attempted') @@ -212,23 +212,24 @@ def _normalize_module(module, depth=2): raise TypeError("Expected a module, string, or None") def _newline_convert(data): - # We have two cases to cover and we need to make sure we do - # them in the right order - for newline in ('\r\n', '\r'): - data = data.replace(newline, '\n') - return data + # The IO module provides a handy decoder for universal newline conversion + return IncrementalNewlineDecoder(None, True).decode(data, True) def _load_testfile(filename, package, module_relative, encoding): if module_relative: package = _normalize_module(package, 3) filename = _module_relative_path(package, filename) - if getattr(package, '__loader__', None) is not None: - if hasattr(package.__loader__, 'get_data'): - file_contents = package.__loader__.get_data(filename) - file_contents = file_contents.decode(encoding) - # get_data() opens files as 'rb', so one must do the equivalent - # conversion as universal newlines would do. - return _newline_convert(file_contents), filename + if (loader := getattr(package, '__loader__', None)) is None: + try: + loader = package.__spec__.loader + except AttributeError: + pass + if hasattr(loader, 'get_data'): + file_contents = loader.get_data(filename) + file_contents = file_contents.decode(encoding) + # get_data() opens files as 'rb', so one must do the equivalent + # conversion as universal newlines would do. + return _newline_convert(file_contents), filename with open(filename, encoding=encoding) as f: return f.read(), filename @@ -975,6 +976,17 @@ class DocTestFinder: else: raise ValueError("object must be a class or function") + def _is_routine(self, obj): + """ + Safely unwrap objects and determine if they are functions. + """ + maybe_routine = obj + try: + maybe_routine = inspect.unwrap(maybe_routine) + except ValueError: + pass + return inspect.isroutine(maybe_routine) + def _find(self, tests, obj, name, module, source_lines, globs, seen): """ Find tests for the given object and any contained objects, and @@ -997,9 +1009,9 @@ class DocTestFinder: if inspect.ismodule(obj) and self._recurse: for valname, val in obj.__dict__.items(): valname = '%s.%s' % (name, valname) + # Recurse to functions & classes. - if ((inspect.isroutine(inspect.unwrap(val)) - or inspect.isclass(val)) and + if ((self._is_routine(val) or inspect.isclass(val)) and self._from_module(module, val)): self._find(tests, val, valname, module, source_lines, globs, seen) diff --git a/contrib/tools/python3/src/Lib/email/_parseaddr.py b/contrib/tools/python3/src/Lib/email/_parseaddr.py index c5a7b23193e..ba5ad5a36d0 100644 --- a/contrib/tools/python3/src/Lib/email/_parseaddr.py +++ b/contrib/tools/python3/src/Lib/email/_parseaddr.py @@ -65,7 +65,7 @@ def _parsedate_tz(data): """ if not data: - return + return None data = data.split() if not data: # This happens for whitespace-only input. return None diff --git a/contrib/tools/python3/src/Lib/email/base64mime.py b/contrib/tools/python3/src/Lib/email/base64mime.py index 17f0818f6ca..a7cc37365c6 100644 --- a/contrib/tools/python3/src/Lib/email/base64mime.py +++ b/contrib/tools/python3/src/Lib/email/base64mime.py @@ -84,7 +84,7 @@ def body_encode(s, maxlinelen=76, eol=NL): in an email. """ if not s: - return s + return "" encvec = [] max_unencoded = maxlinelen * 3 // 4 diff --git a/contrib/tools/python3/src/Lib/email/errors.py b/contrib/tools/python3/src/Lib/email/errors.py index d28a6800104..3ad00565549 100644 --- a/contrib/tools/python3/src/Lib/email/errors.py +++ b/contrib/tools/python3/src/Lib/email/errors.py @@ -108,3 +108,6 @@ class NonASCIILocalPartDefect(HeaderDefect): """local_part contains non-ASCII characters""" # This defect only occurs during unicode parsing, not when # parsing messages decoded from binary. + +class InvalidDateDefect(HeaderDefect): + """Header has unparsable or invalid date""" diff --git a/contrib/tools/python3/src/Lib/email/headerregistry.py b/contrib/tools/python3/src/Lib/email/headerregistry.py index 5d84fc0d82d..b590d69e8b7 100644 --- a/contrib/tools/python3/src/Lib/email/headerregistry.py +++ b/contrib/tools/python3/src/Lib/email/headerregistry.py @@ -2,10 +2,6 @@ This module provides an implementation of the HeaderRegistry API. The implementation is designed to flexibly follow RFC5322 rules. - -Eventually HeaderRegistry will be a public API, but it isn't yet, -and will probably change some before that happens. - """ from types import MappingProxyType @@ -302,7 +298,14 @@ class DateHeader: kwds['parse_tree'] = parser.TokenList() return if isinstance(value, str): - value = utils.parsedate_to_datetime(value) + kwds['decoded'] = value + try: + value = utils.parsedate_to_datetime(value) + except ValueError: + kwds['defects'].append(errors.InvalidDateDefect('Invalid date value or format')) + kwds['datetime'] = None + kwds['parse_tree'] = parser.TokenList() + return kwds['datetime'] = value kwds['decoded'] = utils.format_datetime(kwds['datetime']) kwds['parse_tree'] = cls.value_parser(kwds['decoded']) diff --git a/contrib/tools/python3/src/Lib/email/utils.py b/contrib/tools/python3/src/Lib/email/utils.py index 48d30160aa6..cfdfeb3f1a8 100644 --- a/contrib/tools/python3/src/Lib/email/utils.py +++ b/contrib/tools/python3/src/Lib/email/utils.py @@ -195,7 +195,10 @@ def make_msgid(idstring=None, domain=None): def parsedate_to_datetime(data): - *dtuple, tz = _parsedate_tz(data) + parsed_date_tz = _parsedate_tz(data) + if parsed_date_tz is None: + raise ValueError('Invalid date value or format "%s"' % str(data)) + *dtuple, tz = parsed_date_tz if tz is None: return datetime.datetime(*dtuple[:6]) return datetime.datetime(*dtuple[:6], diff --git a/contrib/tools/python3/src/Lib/encodings/__init__.py b/contrib/tools/python3/src/Lib/encodings/__init__.py index ddd5afdcf2d..4b37d3321c9 100644 --- a/contrib/tools/python3/src/Lib/encodings/__init__.py +++ b/contrib/tools/python3/src/Lib/encodings/__init__.py @@ -61,7 +61,8 @@ def normalize_encoding(encoding): if c.isalnum() or c == '.': if punct and chars: chars.append('_') - chars.append(c) + if c.isascii(): + chars.append(c) punct = False else: punct = True diff --git a/contrib/tools/python3/src/Lib/ensurepip/__init__.py b/contrib/tools/python3/src/Lib/ensurepip/__init__.py index e510cc7fb2b..3fbe8b2a5b1 100644 --- a/contrib/tools/python3/src/Lib/ensurepip/__init__.py +++ b/contrib/tools/python3/src/Lib/ensurepip/__init__.py @@ -1,16 +1,16 @@ +import collections import os import os.path +import subprocess import sys -import runpy +import sysconfig import tempfile -import subprocess from importlib import resources -from . import _bundled - __all__ = ["version", "bootstrap"] +_PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "58.1.0" _PIP_VERSION = "22.0.4" _PROJECTS = [ @@ -18,6 +18,65 @@ _PROJECTS = [ ("pip", _PIP_VERSION, "py3"), ] +# Packages bundled in ensurepip._bundled have wheel_name set. +# Packages from WHEEL_PKG_DIR have wheel_path set. +_Package = collections.namedtuple('Package', + ('version', 'wheel_name', 'wheel_path')) + +# Directory of system 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. +_WHEEL_PKG_DIR = sysconfig.get_config_var('WHEEL_PKG_DIR') + + +def _find_packages(path): + packages = {} + try: + filenames = os.listdir(path) + except OSError: + # Ignore: path doesn't exist or permission error + filenames = () + # Make the code deterministic if a directory contains multiple wheel files + # of the same package, but don't attempt to implement correct version + # comparison since this case should not happen. + filenames = sorted(filenames) + for filename in filenames: + # filename is like 'pip-21.2.4-py3-none-any.whl' + if not filename.endswith(".whl"): + continue + for name in _PACKAGE_NAMES: + prefix = name + '-' + if filename.startswith(prefix): + break + else: + continue + + # Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl' + version = filename.removeprefix(prefix).partition('-')[0] + wheel_path = os.path.join(path, filename) + packages[name] = _Package(version, None, wheel_path) + return packages + + +def _get_packages(): + global _PACKAGES, _WHEEL_PKG_DIR + if _PACKAGES is not None: + return _PACKAGES + + packages = {} + for name, version, py_tag in _PROJECTS: + wheel_name = f"{name}-{version}-{py_tag}-none-any.whl" + packages[name] = _Package(version, wheel_name, None) + if _WHEEL_PKG_DIR: + dir_packages = _find_packages(_WHEEL_PKG_DIR) + # only used the wheel package directory if all packages are found there + if all(name in dir_packages for name in _PACKAGE_NAMES): + packages = dir_packages + _PACKAGES = packages + return packages +_PACKAGES = None + def _run_pip(args, additional_paths=None): # Run the bootstraping in a subprocess to avoid leaking any state that happens @@ -31,14 +90,16 @@ sys.path = {additional_paths or []} + sys.path sys.argv[1:] = {args} runpy.run_module("pip", run_name="__main__", alter_sys=True) """ - return subprocess.run([sys.executable, "-c", code], check=True).returncode + return subprocess.run([sys.executable, '-W', 'ignore::DeprecationWarning', + "-c", code], check=True).returncode def version(): """ Returns a string specifying the bundled version of pip. """ - return _PIP_VERSION + return _get_packages()['pip'].version + def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables @@ -100,16 +161,23 @@ def _bootstrap(*, root=None, upgrade=False, user=False, # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] - for project, version, py_tag in _PROJECTS: - wheel_name = "{}-{}-{}-none-any.whl".format(project, version, py_tag) - whl = resources.read_binary( - _bundled, - wheel_name, - ) - with open(os.path.join(tmpdir, wheel_name), "wb") as fp: + for name, package in _get_packages().items(): + if package.wheel_name: + # Use bundled wheel package + from ensurepip import _bundled + wheel_name = package.wheel_name + whl = resources.read_binary(_bundled, wheel_name) + else: + # Use the wheel package directory + with open(package.wheel_path, "rb") as fp: + whl = fp.read() + wheel_name = os.path.basename(package.wheel_path) + + filename = os.path.join(tmpdir, wheel_name) + with open(filename, "wb") as fp: fp.write(whl) - additional_paths.append(os.path.join(tmpdir, wheel_name)) + additional_paths.append(filename) # Construct the arguments to be passed to the pip command args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir] @@ -122,7 +190,7 @@ def _bootstrap(*, root=None, upgrade=False, user=False, if verbosity: args += ["-" + "v" * verbosity] - return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) + return _run_pip([*args, *_PACKAGE_NAMES], additional_paths) def _uninstall_helper(*, verbosity=0): """Helper to support a clean default uninstall process on Windows @@ -135,11 +203,14 @@ def _uninstall_helper(*, verbosity=0): except ImportError: return - # If the pip version doesn't match the bundled one, leave it alone - if pip.__version__ != _PIP_VERSION: - msg = ("ensurepip will only uninstall a matching version " - "({!r} installed, {!r} bundled)") - print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) + # If the installed pip version doesn't match the available one, + # leave it alone + available_version = version() + if pip.__version__ != available_version: + print(f"ensurepip will only uninstall a matching version " + f"({pip.__version__!r} installed, " + f"{available_version!r} available)", + file=sys.stderr) return _disable_pip_configuration_settings() @@ -149,7 +220,7 @@ def _uninstall_helper(*, verbosity=0): if verbosity: args += ["-" + "v" * verbosity] - return _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) + return _run_pip([*args, *reversed(_PACKAGE_NAMES)]) def _main(argv=None): diff --git a/contrib/tools/python3/src/Lib/enum.py b/contrib/tools/python3/src/Lib/enum.py index ee4c4c04f98..f5657a6eba2 100644 --- a/contrib/tools/python3/src/Lib/enum.py +++ b/contrib/tools/python3/src/Lib/enum.py @@ -44,10 +44,11 @@ def _is_sunder(name): def _is_private(cls_name, name): # do not use `re` as `re` imports `enum` pattern = '_%s__' % (cls_name, ) + pat_len = len(pattern) if ( - len(name) >= 5 + len(name) > pat_len and name.startswith(pattern) - and name[len(pattern)] != '_' + and name[pat_len:pat_len+1] != ['_'] and (name[-1] != '_' or name[-2] != '_') ): return True @@ -97,7 +98,7 @@ class _EnumDict(dict): if _is_private(self._cls_name, key): import warnings warnings.warn( - "private variables, such as %r, will be normal attributes in 3.10" + "private variables, such as %r, will be normal attributes in 3.11" % (key, ), DeprecationWarning, stacklevel=2, @@ -392,12 +393,19 @@ class EnumMeta(type): start=start, ) - def __contains__(cls, member): - if not isinstance(member, Enum): + def __contains__(cls, obj): + if not isinstance(obj, Enum): + import warnings + warnings.warn( + "in 3.12 __contains__ will no longer raise TypeError, but will return True if\n" + "obj is a member or a member's value", + 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_ + type(obj).__qualname__, cls.__class__.__qualname__)) + return isinstance(obj, cls) and obj._name_ in cls._member_map_ def __delattr__(cls, attr): # nicer error message when someone tries to delete an attribute @@ -705,7 +713,8 @@ class Enum(metaclass=EnumMeta): 'error in %s._missing_: returned %r instead of None or a valid member' % (cls.__name__, result) ) - exc.__context__ = ve_exc + if not isinstance(exc, ValueError): + exc.__context__ = ve_exc raise exc finally: # ensure all variables that could hold an exception are destroyed diff --git a/contrib/tools/python3/src/Lib/filecmp.py b/contrib/tools/python3/src/Lib/filecmp.py index 1893f909de8..70a4b23c982 100644 --- a/contrib/tools/python3/src/Lib/filecmp.py +++ b/contrib/tools/python3/src/Lib/filecmp.py @@ -116,7 +116,9 @@ class dircmp: same_files: list of identical files. diff_files: list of filenames which differ. funny_files: list of files which could not be compared. - subdirs: a dictionary of dircmp objects, keyed by names in common_dirs. + subdirs: a dictionary of dircmp instances (or MyDirCmp instances if this + object is of type MyDirCmp, a subclass of dircmp), keyed by names + in common_dirs. """ def __init__(self, a, b, ignore=None, hide=None): # Initialize @@ -186,14 +188,15 @@ class dircmp: self.same_files, self.diff_files, self.funny_files = xx def phase4(self): # Find out differences between common subdirectories - # A new dircmp object is created for each common subdirectory, + # A new dircmp (or MyDirCmp if dircmp was subclassed) object is created + # for each common subdirectory, # these are stored in a dictionary indexed by filename. # The hide and ignore properties are inherited from the parent self.subdirs = {} for x in self.common_dirs: a_x = os.path.join(self.left, x) b_x = os.path.join(self.right, x) - self.subdirs[x] = dircmp(a_x, b_x, self.ignore, self.hide) + self.subdirs[x] = self.__class__(a_x, b_x, self.ignore, self.hide) def phase4_closure(self): # Recursively call phase4() on subdirectories self.phase4() diff --git a/contrib/tools/python3/src/Lib/fileinput.py b/contrib/tools/python3/src/Lib/fileinput.py index 0c31f93ed8f..35347185da0 100644 --- a/contrib/tools/python3/src/Lib/fileinput.py +++ b/contrib/tools/python3/src/Lib/fileinput.py @@ -3,7 +3,7 @@ Typical use is: import fileinput - for line in fileinput.input(): + for line in fileinput.input(encoding="utf-8"): process(line) This iterates over the lines of all files listed in sys.argv[1:], @@ -63,15 +63,9 @@ file remains around; by default, the extension is ".bak" and it is deleted when the output file is closed. In-place filtering is disabled when standard input is read. XXX The current implementation does not work for MS-DOS 8+3 filesystems. - -XXX Possible additions: - -- optional getopt argument processing -- isatty() -- read(), read(size), even readlines() - """ +import io import sys, os from types import GenericAlias @@ -81,7 +75,8 @@ __all__ = ["input", "close", "nextfile", "filename", "lineno", "filelineno", _state = None -def input(files=None, inplace=False, backup="", *, mode="r", openhook=None): +def input(files=None, inplace=False, backup="", *, mode="r", openhook=None, + encoding=None, errors=None): """Return an instance of the FileInput class, which can be iterated. The parameters are passed to the constructor of the FileInput class. @@ -91,7 +86,8 @@ def input(files=None, inplace=False, backup="", *, mode="r", openhook=None): global _state if _state and _state._file: raise RuntimeError("input() already active") - _state = FileInput(files, inplace, backup, mode=mode, openhook=openhook) + _state = FileInput(files, inplace, backup, mode=mode, openhook=openhook, + encoding=encoding, errors=errors) return _state def close(): @@ -186,7 +182,7 @@ class FileInput: """ def __init__(self, files=None, inplace=False, backup="", *, - mode="r", openhook=None): + mode="r", openhook=None, encoding=None, errors=None): if isinstance(files, str): files = (files,) elif isinstance(files, os.PathLike): @@ -209,6 +205,17 @@ class FileInput: self._file = None self._isstdin = False self._backupfilename = None + self._encoding = encoding + self._errors = errors + + # We can not use io.text_encoding() here because old openhook doesn't + # take encoding parameter. + if (sys.flags.warn_default_encoding and + "b" not in mode and encoding is None and openhook is None): + import warnings + warnings.warn("'encoding' argument not specified.", + EncodingWarning, 2) + # restrict mode argument to reading modes if mode not in ('r', 'rU', 'U', 'rb'): raise ValueError("FileInput opening mode must be one of " @@ -324,6 +331,13 @@ class FileInput: self._file = None self._isstdin = False self._backupfilename = 0 + + # EncodingWarning is emitted in __init__() already + if "b" not in self._mode: + encoding = self._encoding or "locale" + else: + encoding = None + if self._filename == '-': self._filename = '' if 'b' in self._mode: @@ -341,18 +355,18 @@ class FileInput: pass # The next few lines may raise OSError os.rename(self._filename, self._backupfilename) - self._file = open(self._backupfilename, self._mode) + self._file = open(self._backupfilename, self._mode, encoding=encoding) try: perm = os.fstat(self._file.fileno()).st_mode except OSError: - self._output = open(self._filename, self._write_mode) + self._output = open(self._filename, self._write_mode, encoding=encoding) else: mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC if hasattr(os, 'O_BINARY'): mode |= os.O_BINARY fd = os.open(self._filename, mode, perm) - self._output = os.fdopen(fd, self._write_mode) + self._output = os.fdopen(fd, self._write_mode, encoding=encoding) try: os.chmod(self._filename, perm) except OSError: @@ -362,9 +376,15 @@ class FileInput: else: # This may raise OSError if self._openhook: - self._file = self._openhook(self._filename, self._mode) + # Custom hooks made previous to Python 3.10 didn't have + # encoding argument + if self._encoding is None: + self._file = self._openhook(self._filename, self._mode) + else: + self._file = self._openhook( + self._filename, self._mode, encoding=self._encoding, errors=self._errors) else: - self._file = open(self._filename, self._mode) + self._file = open(self._filename, self._mode, encoding=encoding, errors=self._errors) self._readline = self._file.readline # hide FileInput._readline return self._readline() @@ -395,16 +415,23 @@ class FileInput: __class_getitem__ = classmethod(GenericAlias) -def hook_compressed(filename, mode): +def hook_compressed(filename, mode, *, encoding=None, errors=None): + if encoding is None: # EncodingWarning is emitted in FileInput() already. + encoding = "locale" ext = os.path.splitext(filename)[1] if ext == '.gz': import gzip - return gzip.open(filename, mode) + stream = gzip.open(filename, mode) elif ext == '.bz2': import bz2 - return bz2.BZ2File(filename, mode) + stream = bz2.BZ2File(filename, mode) else: - return open(filename, mode) + return open(filename, mode, encoding=encoding, errors=errors) + + # gzip and bz2 are binary mode by default. + if "b" not in mode: + stream = io.TextIOWrapper(stream, encoding=encoding, errors=errors) + return stream def hook_encoded(encoding, errors=None): diff --git a/contrib/tools/python3/src/Lib/formatter.py b/contrib/tools/python3/src/Lib/formatter.py deleted file mode 100644 index e2394de8c29..00000000000 --- a/contrib/tools/python3/src/Lib/formatter.py +++ /dev/null @@ -1,452 +0,0 @@ -"""Generic output formatting. - -Formatter objects transform an abstract flow of formatting events into -specific output events on writer objects. Formatters manage several stack -structures to allow various properties of a writer object to be changed and -restored; writers need not be able to handle relative changes nor any sort -of ``change back'' operation. Specific writer properties which may be -controlled via formatter objects are horizontal alignment, font, and left -margin indentations. A mechanism is provided which supports providing -arbitrary, non-exclusive style settings to a writer as well. Additional -interfaces facilitate formatting events which are not reversible, such as -paragraph separation. - -Writer objects encapsulate device interfaces. Abstract devices, such as -file formats, are supported as well as physical devices. The provided -implementations all work with abstract devices. The interface makes -available mechanisms for setting the properties which formatter objects -manage and inserting data into the output. -""" - -import sys -import warnings -warnings.warn('the formatter module is deprecated', DeprecationWarning, - stacklevel=2) - - -AS_IS = None - - -class NullFormatter: - """A formatter which does nothing. - - If the writer parameter is omitted, a NullWriter instance is created. - No methods of the writer are called by NullFormatter instances. - - Implementations should inherit from this class if implementing a writer - interface but don't need to inherit any implementation. - - """ - - def __init__(self, writer=None): - if writer is None: - writer = NullWriter() - self.writer = writer - def end_paragraph(self, blankline): pass - def add_line_break(self): pass - def add_hor_rule(self, *args, **kw): pass - def add_label_data(self, format, counter, blankline=None): pass - def add_flowing_data(self, data): pass - def add_literal_data(self, data): pass - def flush_softspace(self): pass - def push_alignment(self, align): pass - def pop_alignment(self): pass - def push_font(self, x): pass - def pop_font(self): pass - def push_margin(self, margin): pass - def pop_margin(self): pass - def set_spacing(self, spacing): pass - def push_style(self, *styles): pass - def pop_style(self, n=1): pass - def assert_line_data(self, flag=1): pass - - -class AbstractFormatter: - """The standard formatter. - - This implementation has demonstrated wide applicability to many writers, - and may be used directly in most circumstances. It has been used to - implement a full-featured World Wide Web browser. - - """ - - # Space handling policy: blank spaces at the boundary between elements - # are handled by the outermost context. "Literal" data is not checked - # to determine context, so spaces in literal data are handled directly - # in all circumstances. - - def __init__(self, writer): - self.writer = writer # Output device - self.align = None # Current alignment - self.align_stack = [] # Alignment stack - self.font_stack = [] # Font state - self.margin_stack = [] # Margin state - self.spacing = None # Vertical spacing state - self.style_stack = [] # Other state, e.g. color - self.nospace = 1 # Should leading space be suppressed - self.softspace = 0 # Should a space be inserted - self.para_end = 1 # Just ended a paragraph - self.parskip = 0 # Skipped space between paragraphs? - self.hard_break = 1 # Have a hard break - self.have_label = 0 - - def end_paragraph(self, blankline): - if not self.hard_break: - self.writer.send_line_break() - self.have_label = 0 - if self.parskip < blankline and not self.have_label: - self.writer.send_paragraph(blankline - self.parskip) - self.parskip = blankline - self.have_label = 0 - self.hard_break = self.nospace = self.para_end = 1 - self.softspace = 0 - - def add_line_break(self): - if not (self.hard_break or self.para_end): - self.writer.send_line_break() - self.have_label = self.parskip = 0 - self.hard_break = self.nospace = 1 - self.softspace = 0 - - def add_hor_rule(self, *args, **kw): - if not self.hard_break: - self.writer.send_line_break() - self.writer.send_hor_rule(*args, **kw) - self.hard_break = self.nospace = 1 - self.have_label = self.para_end = self.softspace = self.parskip = 0 - - def add_label_data(self, format, counter, blankline = None): - if self.have_label or not self.hard_break: - self.writer.send_line_break() - if not self.para_end: - self.writer.send_paragraph((blankline and 1) or 0) - if isinstance(format, str): - self.writer.send_label_data(self.format_counter(format, counter)) - else: - self.writer.send_label_data(format) - self.nospace = self.have_label = self.hard_break = self.para_end = 1 - self.softspace = self.parskip = 0 - - def format_counter(self, format, counter): - label = '' - for c in format: - if c == '1': - label = label + ('%d' % counter) - elif c in 'aA': - if counter > 0: - label = label + self.format_letter(c, counter) - elif c in 'iI': - if counter > 0: - label = label + self.format_roman(c, counter) - else: - label = label + c - return label - - def format_letter(self, case, counter): - label = '' - while counter > 0: - counter, x = divmod(counter-1, 26) - # This makes a strong assumption that lowercase letters - # and uppercase letters form two contiguous blocks, with - # letters in order! - s = chr(ord(case) + x) - label = s + label - return label - - def format_roman(self, case, counter): - ones = ['i', 'x', 'c', 'm'] - fives = ['v', 'l', 'd'] - label, index = '', 0 - # This will die of IndexError when counter is too big - while counter > 0: - counter, x = divmod(counter, 10) - if x == 9: - label = ones[index] + ones[index+1] + label - elif x == 4: - label = ones[index] + fives[index] + label - else: - if x >= 5: - s = fives[index] - x = x-5 - else: - s = '' - s = s + ones[index]*x - label = s + label - index = index + 1 - if case == 'I': - return label.upper() - return label - - def add_flowing_data(self, data): - if not data: return - prespace = data[:1].isspace() - postspace = data[-1:].isspace() - data = " ".join(data.split()) - if self.nospace and not data: - return - elif prespace or self.softspace: - if not data: - if not self.nospace: - self.softspace = 1 - self.parskip = 0 - return - if not self.nospace: - data = ' ' + data - self.hard_break = self.nospace = self.para_end = \ - self.parskip = self.have_label = 0 - self.softspace = postspace - self.writer.send_flowing_data(data) - - def add_literal_data(self, data): - if not data: return - if self.softspace: - self.writer.send_flowing_data(" ") - self.hard_break = data[-1:] == '\n' - self.nospace = self.para_end = self.softspace = \ - self.parskip = self.have_label = 0 - self.writer.send_literal_data(data) - - def flush_softspace(self): - if self.softspace: - self.hard_break = self.para_end = self.parskip = \ - self.have_label = self.softspace = 0 - self.nospace = 1 - self.writer.send_flowing_data(' ') - - def push_alignment(self, align): - if align and align != self.align: - self.writer.new_alignment(align) - self.align = align - self.align_stack.append(align) - else: - self.align_stack.append(self.align) - - def pop_alignment(self): - if self.align_stack: - del self.align_stack[-1] - if self.align_stack: - self.align = align = self.align_stack[-1] - self.writer.new_alignment(align) - else: - self.align = None - self.writer.new_alignment(None) - - def push_font(self, font): - size, i, b, tt = font - if self.softspace: - self.hard_break = self.para_end = self.softspace = 0 - self.nospace = 1 - self.writer.send_flowing_data(' ') - if self.font_stack: - csize, ci, cb, ctt = self.font_stack[-1] - if size is AS_IS: size = csize - if i is AS_IS: i = ci - if b is AS_IS: b = cb - if tt is AS_IS: tt = ctt - font = (size, i, b, tt) - self.font_stack.append(font) - self.writer.new_font(font) - - def pop_font(self): - if self.font_stack: - del self.font_stack[-1] - if self.font_stack: - font = self.font_stack[-1] - else: - font = None - self.writer.new_font(font) - - def push_margin(self, margin): - self.margin_stack.append(margin) - fstack = [m for m in self.margin_stack if m] - if not margin and fstack: - margin = fstack[-1] - self.writer.new_margin(margin, len(fstack)) - - def pop_margin(self): - if self.margin_stack: - del self.margin_stack[-1] - fstack = [m for m in self.margin_stack if m] - if fstack: - margin = fstack[-1] - else: - margin = None - self.writer.new_margin(margin, len(fstack)) - - def set_spacing(self, spacing): - self.spacing = spacing - self.writer.new_spacing(spacing) - - def push_style(self, *styles): - if self.softspace: - self.hard_break = self.para_end = self.softspace = 0 - self.nospace = 1 - self.writer.send_flowing_data(' ') - for style in styles: - self.style_stack.append(style) - self.writer.new_styles(tuple(self.style_stack)) - - def pop_style(self, n=1): - del self.style_stack[-n:] - self.writer.new_styles(tuple(self.style_stack)) - - def assert_line_data(self, flag=1): - self.nospace = self.hard_break = not flag - self.para_end = self.parskip = self.have_label = 0 - - -class NullWriter: - """Minimal writer interface to use in testing & inheritance. - - A writer which only provides the interface definition; no actions are - taken on any methods. This should be the base class for all writers - which do not need to inherit any implementation methods. - - """ - def __init__(self): pass - def flush(self): pass - def new_alignment(self, align): pass - def new_font(self, font): pass - def new_margin(self, margin, level): pass - def new_spacing(self, spacing): pass - def new_styles(self, styles): pass - def send_paragraph(self, blankline): pass - def send_line_break(self): pass - def send_hor_rule(self, *args, **kw): pass - def send_label_data(self, data): pass - def send_flowing_data(self, data): pass - def send_literal_data(self, data): pass - - -class AbstractWriter(NullWriter): - """A writer which can be used in debugging formatters, but not much else. - - Each method simply announces itself by printing its name and - arguments on standard output. - - """ - - def new_alignment(self, align): - print("new_alignment(%r)" % (align,)) - - def new_font(self, font): - print("new_font(%r)" % (font,)) - - def new_margin(self, margin, level): - print("new_margin(%r, %d)" % (margin, level)) - - def new_spacing(self, spacing): - print("new_spacing(%r)" % (spacing,)) - - def new_styles(self, styles): - print("new_styles(%r)" % (styles,)) - - def send_paragraph(self, blankline): - print("send_paragraph(%r)" % (blankline,)) - - def send_line_break(self): - print("send_line_break()") - - def send_hor_rule(self, *args, **kw): - print("send_hor_rule()") - - def send_label_data(self, data): - print("send_label_data(%r)" % (data,)) - - def send_flowing_data(self, data): - print("send_flowing_data(%r)" % (data,)) - - def send_literal_data(self, data): - print("send_literal_data(%r)" % (data,)) - - -class DumbWriter(NullWriter): - """Simple writer class which writes output on the file object passed in - as the file parameter or, if file is omitted, on standard output. The - output is simply word-wrapped to the number of columns specified by - the maxcol parameter. This class is suitable for reflowing a sequence - of paragraphs. - - """ - - def __init__(self, file=None, maxcol=72): - self.file = file or sys.stdout - self.maxcol = maxcol - NullWriter.__init__(self) - self.reset() - - def reset(self): - self.col = 0 - self.atbreak = 0 - - def send_paragraph(self, blankline): - self.file.write('\n'*blankline) - self.col = 0 - self.atbreak = 0 - - def send_line_break(self): - self.file.write('\n') - self.col = 0 - self.atbreak = 0 - - def send_hor_rule(self, *args, **kw): - self.file.write('\n') - self.file.write('-'*self.maxcol) - self.file.write('\n') - self.col = 0 - self.atbreak = 0 - - def send_literal_data(self, data): - self.file.write(data) - i = data.rfind('\n') - if i >= 0: - self.col = 0 - data = data[i+1:] - data = data.expandtabs() - self.col = self.col + len(data) - self.atbreak = 0 - - def send_flowing_data(self, data): - if not data: return - atbreak = self.atbreak or data[0].isspace() - col = self.col - maxcol = self.maxcol - write = self.file.write - for word in data.split(): - if atbreak: - if col + len(word) >= maxcol: - write('\n') - col = 0 - else: - write(' ') - col = col + 1 - write(word) - col = col + len(word) - atbreak = 1 - self.col = col - self.atbreak = data[-1].isspace() - - -def test(file = None): - w = DumbWriter() - f = AbstractFormatter(w) - if file is not None: - fp = open(file) - elif sys.argv[1:]: - fp = open(sys.argv[1]) - else: - fp = sys.stdin - try: - for line in fp: - if line == '\n': - f.end_paragraph(1) - else: - f.add_flowing_data(line) - finally: - if fp is not sys.stdin: - fp.close() - f.end_paragraph(0) - - -if __name__ == '__main__': - test() diff --git a/contrib/tools/python3/src/Lib/fractions.py b/contrib/tools/python3/src/Lib/fractions.py index de3e23b7592..96047beb454 100644 --- a/contrib/tools/python3/src/Lib/fractions.py +++ b/contrib/tools/python3/src/Lib/fractions.py @@ -380,32 +380,139 @@ class Fraction(numbers.Rational): return forward, reverse + # Rational arithmetic algorithms: Knuth, TAOCP, Volume 2, 4.5.1. + # + # Assume input fractions a and b are normalized. + # + # 1) Consider addition/subtraction. + # + # Let g = gcd(da, db). Then + # + # na nb na*db ± nb*da + # a ± b == -- ± -- == ------------- == + # da db da*db + # + # na*(db//g) ± nb*(da//g) t + # == ----------------------- == - + # (da*db)//g d + # + # Now, if g > 1, we're working with smaller integers. + # + # Note, that t, (da//g) and (db//g) are pairwise coprime. + # + # Indeed, (da//g) and (db//g) share no common factors (they were + # removed) and da is coprime with na (since input fractions are + # normalized), hence (da//g) and na are coprime. By symmetry, + # (db//g) and nb are coprime too. Then, + # + # gcd(t, da//g) == gcd(na*(db//g), da//g) == 1 + # gcd(t, db//g) == gcd(nb*(da//g), db//g) == 1 + # + # Above allows us optimize reduction of the result to lowest + # terms. Indeed, + # + # g2 = gcd(t, d) == gcd(t, (da//g)*(db//g)*g) == gcd(t, g) + # + # t//g2 t//g2 + # a ± b == ----------------------- == ---------------- + # (da//g)*(db//g)*(g//g2) (da//g)*(db//g2) + # + # is a normalized fraction. This is useful because the unnormalized + # denominator d could be much larger than g. + # + # We should special-case g == 1 (and g2 == 1), since 60.8% of + # randomly-chosen integers are coprime: + # https://en.wikipedia.org/wiki/Coprime_integers#Probability_of_coprimality + # Note, that g2 == 1 always for fractions, obtained from floats: here + # g is a power of 2 and the unnormalized numerator t is an odd integer. + # + # 2) Consider multiplication + # + # Let g1 = gcd(na, db) and g2 = gcd(nb, da), then + # + # na*nb na*nb (na//g1)*(nb//g2) + # a*b == ----- == ----- == ----------------- + # da*db db*da (db//g1)*(da//g2) + # + # Note, that after divisions we're multiplying smaller integers. + # + # Also, the resulting fraction is normalized, because each of + # two factors in the numerator is coprime to each of the two factors + # in the denominator. + # + # Indeed, pick (na//g1). It's coprime with (da//g2), because input + # fractions are normalized. It's also coprime with (db//g1), because + # common factors are removed by g1 == gcd(na, db). + # + # As for addition/subtraction, we should special-case g1 == 1 + # and g2 == 1 for same reason. That happens also for multiplying + # rationals, obtained from floats. + def _add(a, b): """a + b""" - da, db = a.denominator, b.denominator - return Fraction(a.numerator * db + b.numerator * da, - da * db) + 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) + 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) __add__, __radd__ = _operator_fallbacks(_add, operator.add) def _sub(a, b): """a - b""" - da, db = a.denominator, b.denominator - return Fraction(a.numerator * db - b.numerator * da, - da * db) + 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) + 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) __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) def _mul(a, b): """a * b""" - return Fraction(a.numerator * b.numerator, a.denominator * b.denominator) + na, da = a.numerator, a.denominator + nb, db = b.numerator, b.denominator + g1 = math.gcd(na, db) + if g1 > 1: + na //= g1 + db //= g1 + g2 = math.gcd(nb, da) + if g2 > 1: + nb //= g2 + da //= g2 + return Fraction(na * nb, db * da, _normalize=False) __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul) def _div(a, b): """a / b""" - return Fraction(a.numerator * b.denominator, - a.denominator * b.numerator) + # Same as _mul(), with inversed b. + na, da = a.numerator, a.denominator + nb, db = b.numerator, b.denominator + g1 = math.gcd(na, nb) + if g1 > 1: + na //= g1 + nb //= g1 + g2 = math.gcd(db, da) + if g2 > 1: + da //= g2 + db //= g2 + n, d = na * db, nb * da + if d < 0: + n, d = -n, -d + return Fraction(n, d, _normalize=False) __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) diff --git a/contrib/tools/python3/src/Lib/functools.py b/contrib/tools/python3/src/Lib/functools.py index 77e5035ebcc..305ceb450a7 100644 --- a/contrib/tools/python3/src/Lib/functools.py +++ b/contrib/tools/python3/src/Lib/functools.py @@ -236,14 +236,14 @@ _initial_missing = object() def reduce(function, sequence, initial=_initial_missing): """ - reduce(function, sequence[, initial]) -> value + reduce(function, iterable[, initial]) -> value - Apply a function of two arguments cumulatively to the items of a sequence, - from left to right, so as to reduce the sequence to a single value. - For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates + Apply a function of two arguments cumulatively to the items of a sequence + or iterable, from left to right, so as to reduce the iterable to a single + value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items - of the sequence in the calculation, and serves as a default when the - sequence is empty. + of the iterable in the calculation, and serves as a default when the + iterable is empty. """ it = iter(sequence) @@ -252,7 +252,8 @@ def reduce(function, sequence, initial=_initial_missing): try: value = next(it) except StopIteration: - raise TypeError("reduce() of empty sequence with no initial value") from None + raise TypeError( + "reduce() of empty iterable with no initial value") from None else: value = initial @@ -912,24 +913,11 @@ class singledispatchmethod: self.dispatcher = singledispatch(func) self.func = func - # bpo-45678: special-casing for classmethod/staticmethod in Python <=3.9, - # as functools.update_wrapper doesn't work properly in singledispatchmethod.__get__ - # if it is applied to an unbound classmethod/staticmethod - if isinstance(func, (staticmethod, classmethod)): - self._wrapped_func = func.__func__ - else: - self._wrapped_func = func def register(self, cls, method=None): """generic_method.register(cls, func) -> func Registers a new implementation for the given *cls* on a *generic_method*. """ - # bpo-39679: in Python <= 3.9, classmethods and staticmethods don't - # inherit __annotations__ of the wrapped function (fixed in 3.10+ as - # a side-effect of bpo-43682) but we need that for annotation-derived - # singledispatches. So we add that just-in-time here. - if isinstance(cls, (staticmethod, classmethod)): - cls.__annotations__ = getattr(cls.__func__, '__annotations__', {}) return self.dispatcher.register(cls, func=method) def __get__(self, obj, cls=None): @@ -939,7 +927,7 @@ class singledispatchmethod: _method.__isabstractmethod__ = self.__isabstractmethod__ _method.register = self.register - update_wrapper(_method, self._wrapped_func) + update_wrapper(_method, self.func) return _method @property diff --git a/contrib/tools/python3/src/Lib/glob.py b/contrib/tools/python3/src/Lib/glob.py index 12370611309..9fc08f45df1 100644 --- a/contrib/tools/python3/src/Lib/glob.py +++ b/contrib/tools/python3/src/Lib/glob.py @@ -4,11 +4,13 @@ import contextlib import os import re import fnmatch +import itertools +import stat import sys __all__ = ["glob", "iglob", "escape"] -def glob(pathname, *, recursive=False): +def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False): """Return a list of paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la @@ -19,9 +21,9 @@ def glob(pathname, *, recursive=False): If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ - return list(iglob(pathname, recursive=recursive)) + return list(iglob(pathname, root_dir=root_dir, dir_fd=dir_fd, recursive=recursive)) -def iglob(pathname, *, recursive=False): +def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False): """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la @@ -33,35 +35,44 @@ def iglob(pathname, *, recursive=False): zero or more directories and subdirectories. """ sys.audit("glob.glob", pathname, recursive) - it = _iglob(pathname, recursive, False) - if recursive and _isrecursive(pathname): - s = next(it) # skip empty string - assert not s + sys.audit("glob.glob/2", pathname, recursive, root_dir, dir_fd) + if root_dir is not None: + root_dir = os.fspath(root_dir) + else: + root_dir = pathname[:0] + it = _iglob(pathname, root_dir, dir_fd, recursive, False) + if not pathname or recursive and _isrecursive(pathname[:2]): + try: + s = next(it) # skip empty string + if s: + it = itertools.chain((s,), it) + except StopIteration: + pass return it -def _iglob(pathname, recursive, dironly): +def _iglob(pathname, root_dir, dir_fd, recursive, dironly): dirname, basename = os.path.split(pathname) if not has_magic(pathname): assert not dironly if basename: - if os.path.lexists(pathname): + if _lexists(_join(root_dir, pathname), dir_fd): yield pathname else: # Patterns ending with a slash should match only directories - if os.path.isdir(dirname): + if _isdir(_join(root_dir, dirname), dir_fd): yield pathname return if not dirname: if recursive and _isrecursive(basename): - yield from _glob2(dirname, basename, dironly) + yield from _glob2(root_dir, basename, dir_fd, dironly) else: - yield from _glob1(dirname, basename, dironly) + yield from _glob1(root_dir, basename, dir_fd, dironly) return # `os.path.split()` returns the argument itself as a dirname if it is a # drive or UNC path. Prevent an infinite recursion if a drive or UNC path # contains magic characters (i.e. r'\\?\C:'). if dirname != pathname and has_magic(dirname): - dirs = _iglob(dirname, recursive, True) + dirs = _iglob(dirname, root_dir, dir_fd, recursive, True) else: dirs = [dirname] if has_magic(basename): @@ -72,80 +83,125 @@ def _iglob(pathname, recursive, dironly): else: glob_in_dir = _glob0 for dirname in dirs: - for name in glob_in_dir(dirname, basename, dironly): + for name in glob_in_dir(_join(root_dir, dirname), basename, dir_fd, dironly): yield os.path.join(dirname, name) # These 2 helper functions non-recursively glob inside a literal directory. # They return a list of basenames. _glob1 accepts a pattern while _glob0 # takes a literal basename (so it only has to check for its existence). -def _glob1(dirname, pattern, dironly): - names = _listdir(dirname, dironly) +def _glob1(dirname, pattern, dir_fd, dironly): + names = _listdir(dirname, dir_fd, dironly) if not _ishidden(pattern): names = (x for x in names if not _ishidden(x)) return fnmatch.filter(names, pattern) -def _glob0(dirname, basename, dironly): - if not basename: - # `os.path.split()` returns an empty basename for paths ending with a - # directory separator. 'q*x/' should match only directories. - if os.path.isdir(dirname): +def _glob0(dirname, basename, dir_fd, dironly): + if basename: + if _lexists(_join(dirname, basename), dir_fd): return [basename] else: - if os.path.lexists(os.path.join(dirname, basename)): + # `os.path.split()` returns an empty basename for paths ending with a + # directory separator. 'q*x/' should match only directories. + if _isdir(dirname, dir_fd): return [basename] return [] # Following functions are not public but can be used by third-party code. def glob0(dirname, pattern): - return _glob0(dirname, pattern, False) + return _glob0(dirname, pattern, None, False) def glob1(dirname, pattern): - return _glob1(dirname, pattern, False) + return _glob1(dirname, pattern, None, False) # This helper function recursively yields relative pathnames inside a literal # directory. -def _glob2(dirname, pattern, dironly): +def _glob2(dirname, pattern, dir_fd, dironly): assert _isrecursive(pattern) yield pattern[:0] - yield from _rlistdir(dirname, dironly) + yield from _rlistdir(dirname, dir_fd, dironly) # If dironly is false, yields all file names inside a directory. # If dironly is true, yields only directory names. -def _iterdir(dirname, dironly): - if not dirname: - if isinstance(dirname, bytes): - dirname = bytes(os.curdir, 'ASCII') - else: - dirname = os.curdir +def _iterdir(dirname, dir_fd, dironly): try: - with os.scandir(dirname) as it: - for entry in it: - try: - if not dironly or entry.is_dir(): - yield entry.name - except OSError: - pass + fd = None + fsencode = None + if dir_fd is not None: + if dirname: + fd = arg = os.open(dirname, _dir_open_flags, dir_fd=dir_fd) + else: + arg = dir_fd + if isinstance(dirname, bytes): + fsencode = os.fsencode + elif dirname: + arg = dirname + elif isinstance(dirname, bytes): + arg = bytes(os.curdir, 'ASCII') + else: + arg = os.curdir + try: + with os.scandir(arg) as it: + for entry in it: + try: + if not dironly or entry.is_dir(): + if fsencode is not None: + yield fsencode(entry.name) + else: + yield entry.name + except OSError: + pass + finally: + if fd is not None: + os.close(fd) except OSError: return -def _listdir(dirname, dironly): - with contextlib.closing(_iterdir(dirname, dironly)) as it: +def _listdir(dirname, dir_fd, dironly): + with contextlib.closing(_iterdir(dirname, dir_fd, dironly)) as it: return list(it) # Recursively yields relative pathnames inside a literal directory. -def _rlistdir(dirname, dironly): - names = _listdir(dirname, dironly) +def _rlistdir(dirname, dir_fd, dironly): + names = _listdir(dirname, dir_fd, dironly) for x in names: if not _ishidden(x): yield x - path = os.path.join(dirname, x) if dirname else x - for y in _rlistdir(path, dironly): - yield os.path.join(x, y) + path = _join(dirname, x) if dirname else x + for y in _rlistdir(path, dir_fd, dironly): + yield _join(x, y) +def _lexists(pathname, dir_fd): + # Same as os.path.lexists(), but with dir_fd + if dir_fd is None: + return os.path.lexists(pathname) + try: + os.lstat(pathname, dir_fd=dir_fd) + except (OSError, ValueError): + return False + else: + return True + +def _isdir(pathname, dir_fd): + # Same as os.path.isdir(), but with dir_fd + if dir_fd is None: + return os.path.isdir(pathname) + try: + st = os.stat(pathname, dir_fd=dir_fd) + except (OSError, ValueError): + return False + else: + return stat.S_ISDIR(st.st_mode) + +def _join(dirname, basename): + # It is common if dirname or basename is empty + if not dirname or not basename: + return dirname or basename + return os.path.join(dirname, basename) + magic_check = re.compile('([*?[])') magic_check_bytes = re.compile(b'([*?[])') @@ -176,3 +232,6 @@ def escape(pathname): else: pathname = magic_check.sub(r'[\1]', pathname) return drive + pathname + + +_dir_open_flags = os.O_RDONLY | getattr(os, 'O_DIRECTORY', 0) diff --git a/contrib/tools/python3/src/Lib/gzip.py b/contrib/tools/python3/src/Lib/gzip.py index 11a5f41d566..475ec326c0c 100644 --- a/contrib/tools/python3/src/Lib/gzip.py +++ b/contrib/tools/python3/src/Lib/gzip.py @@ -62,6 +62,7 @@ def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST, raise TypeError("filename must be a str or bytes object, or a file") if "t" in mode: + encoding = io.text_encoding(encoding) return io.TextIOWrapper(binary_file, encoding, errors, newline) else: return binary_file @@ -277,7 +278,7 @@ class GzipFile(_compression.BaseStream): if self.fileobj is None: raise ValueError("write() on closed GzipFile object") - if isinstance(data, bytes): + if isinstance(data, (bytes, bytearray)): length = len(data) else: # accept any data that supports the buffer protocol @@ -595,7 +596,7 @@ def main(): f = builtins.open(arg, "rb") g = open(arg + ".gz", "wb") while True: - chunk = f.read(1024) + chunk = f.read(io.DEFAULT_BUFFER_SIZE) if not chunk: break g.write(chunk) diff --git a/contrib/tools/python3/src/Lib/hashlib.py b/contrib/tools/python3/src/Lib/hashlib.py index 58c340d56e3..21a73f3bf6c 100644 --- a/contrib/tools/python3/src/Lib/hashlib.py +++ b/contrib/tools/python3/src/Lib/hashlib.py @@ -173,6 +173,7 @@ try: algorithms_available = algorithms_available.union( _hashlib.openssl_md_meth_names) except ImportError: + _hashlib = None new = __py_new __get_hash = __get_builtin_constructor @@ -180,6 +181,7 @@ try: # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA from _hashlib import 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)) @@ -190,6 +192,11 @@ except ImportError: 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) diff --git a/contrib/tools/python3/src/Lib/hmac.py b/contrib/tools/python3/src/Lib/hmac.py index 180bc378b52..8b4f920db95 100644 --- a/contrib/tools/python3/src/Lib/hmac.py +++ b/contrib/tools/python3/src/Lib/hmac.py @@ -8,11 +8,12 @@ try: import _hashlib as _hashopenssl except ImportError: _hashopenssl = None - _openssl_md_meths = None + _functype = None from _operator import _compare_digest as compare_digest else: - _openssl_md_meths = frozenset(_hashopenssl.openssl_md_meth_names) compare_digest = _hashopenssl.compare_digest + _functype = type(_hashopenssl.openssl_sha256) # builtin type + import hashlib as _hashlib trans_5C = bytes((x ^ 0x5C) for x in range(256)) @@ -23,7 +24,6 @@ trans_36 = bytes((x ^ 0x36) for x in range(256)) digest_size = None - class HMAC: """RFC 2104 HMAC class. Also complies with RFC 4231. @@ -32,7 +32,7 @@ class HMAC: blocksize = 64 # 512-bit HMAC; can be changed in subclasses. __slots__ = ( - "_digest_cons", "_inner", "_outer", "block_size", "digest_size" + "_hmac", "_inner", "_outer", "block_size", "digest_size" ) def __init__(self, key, msg=None, digestmod=''): @@ -55,15 +55,30 @@ class HMAC: if not digestmod: raise TypeError("Missing required parameter 'digestmod'.") + if _hashopenssl and isinstance(digestmod, (str, _functype)): + try: + self._init_hmac(key, msg, digestmod) + except _hashopenssl.UnsupportedDigestmodError: + self._init_old(key, msg, digestmod) + else: + self._init_old(key, msg, digestmod) + + def _init_hmac(self, key, msg, digestmod): + self._hmac = _hashopenssl.hmac_new(key, msg, digestmod=digestmod) + self.digest_size = self._hmac.digest_size + self.block_size = self._hmac.block_size + + def _init_old(self, key, msg, digestmod): if callable(digestmod): - self._digest_cons = digestmod + digest_cons = digestmod elif isinstance(digestmod, str): - self._digest_cons = lambda d=b'': _hashlib.new(digestmod, d) + digest_cons = lambda d=b'': _hashlib.new(digestmod, d) else: - self._digest_cons = lambda d=b'': digestmod.new(d) + digest_cons = lambda d=b'': digestmod.new(d) - self._outer = self._digest_cons() - self._inner = self._digest_cons() + self._hmac = None + self._outer = digest_cons() + self._inner = digest_cons() self.digest_size = self._inner.digest_size if hasattr(self._inner, 'block_size'): @@ -79,13 +94,13 @@ class HMAC: RuntimeWarning, 2) blocksize = self.blocksize + if len(key) > blocksize: + key = digest_cons(key).digest() + # self.blocksize is the default blocksize. self.block_size is # effective block size as well as the public API attribute. self.block_size = blocksize - if len(key) > blocksize: - key = self._digest_cons(key).digest() - key = key.ljust(blocksize, b'\0') self._outer.update(key.translate(trans_5C)) self._inner.update(key.translate(trans_36)) @@ -94,23 +109,15 @@ class HMAC: @property def name(self): - return "hmac-" + self._inner.name - - @property - def digest_cons(self): - return self._digest_cons - - @property - def inner(self): - return self._inner - - @property - def outer(self): - return self._outer + if self._hmac: + return self._hmac.name + else: + return f"hmac-{self._inner.name}" def update(self, msg): """Feed data from msg into this hashing object.""" - self._inner.update(msg) + inst = self._hmac or self._inner + inst.update(msg) def copy(self): """Return a separate copy of this hashing object. @@ -119,10 +126,14 @@ class HMAC: """ # Call __new__ directly to avoid the expensive __init__. other = self.__class__.__new__(self.__class__) - other._digest_cons = self._digest_cons other.digest_size = self.digest_size - other._inner = self._inner.copy() - other._outer = self._outer.copy() + if self._hmac: + other._hmac = self._hmac.copy() + other._inner = other._outer = None + else: + other._hmac = None + other._inner = self._inner.copy() + other._outer = self._outer.copy() return other def _current(self): @@ -130,9 +141,12 @@ class HMAC: To be used only internally with digest() and hexdigest(). """ - h = self._outer.copy() - h.update(self._inner.digest()) - return h + if self._hmac: + return self._hmac + else: + h = self._outer.copy() + h.update(self._inner.digest()) + return h def digest(self): """Return the hash value of this hashing object. @@ -179,9 +193,11 @@ def digest(key, msg, digest): A hashlib constructor returning a new hash object. *OR* A module supporting PEP 247. """ - if (_hashopenssl is not None and - isinstance(digest, str) and digest in _openssl_md_meths): - return _hashopenssl.hmac_digest(key, msg, digest) + if _hashopenssl is not None and isinstance(digest, (str, _functype)): + try: + return _hashopenssl.hmac_digest(key, msg, digest) + except _hashopenssl.UnsupportedDigestmodError: + pass if callable(digest): digest_cons = digest diff --git a/contrib/tools/python3/src/Lib/http/__init__.py b/contrib/tools/python3/src/Lib/http/__init__.py index 37be765349e..bf8d7d68868 100644 --- a/contrib/tools/python3/src/Lib/http/__init__.py +++ b/contrib/tools/python3/src/Lib/http/__init__.py @@ -2,6 +2,7 @@ from enum import IntEnum __all__ = ['HTTPStatus'] + class HTTPStatus(IntEnum): """HTTP status codes and reason phrases diff --git a/contrib/tools/python3/src/Lib/http/client.py b/contrib/tools/python3/src/Lib/http/client.py index a98432e5685..a6ab135b2c3 100644 --- a/contrib/tools/python3/src/Lib/http/client.py +++ b/contrib/tools/python3/src/Lib/http/client.py @@ -75,6 +75,7 @@ import http import io import re import socket +import sys import collections.abc from urllib.parse import urlsplit @@ -106,9 +107,6 @@ globals().update(http.HTTPStatus.__members__) # Mapping status codes to official W3C names responses = {v: v.phrase for v in http.HTTPStatus.__members__.values()} -# maximal amount of data to read at one time in _safe_read -MAXAMOUNT = 1048576 - # maximal line length when calling readline(). _MAXLINE = 65536 _MAXHEADERS = 100 @@ -457,18 +455,25 @@ class HTTPResponse(io.BufferedIOBase): self._close_conn() return b"" + if self.chunked: + return self._read_chunked(amt) + if amt is not None: - # Amount is given, implement using readinto - b = bytearray(amt) - n = self.readinto(b) - return memoryview(b)[:n].tobytes() + if self.length is not None and amt > self.length: + # clip the read to the "end of response" + amt = self.length + s = self.fp.read(amt) + if not s and amt: + # Ideally, we would raise IncompleteRead if the content-length + # wasn't satisfied, but it might break compatibility. + self._close_conn() + elif self.length is not None: + self.length -= len(s) + if not self.length: + self._close_conn() + return s else: # Amount is not given (unbounded read) so we must check self.length - # and self.chunked - - if self.chunked: - return self._readall_chunked() - if self.length is None: s = self.fp.read() else: @@ -569,7 +574,7 @@ class HTTPResponse(io.BufferedIOBase): self.chunk_left = chunk_left return chunk_left - def _readall_chunked(self): + def _read_chunked(self, amt=None): assert self.chunked != _UNKNOWN value = [] try: @@ -577,7 +582,15 @@ class HTTPResponse(io.BufferedIOBase): chunk_left = self._get_chunk_left() if chunk_left is None: break + + if amt is not None and amt <= chunk_left: + value.append(self._safe_read(amt)) + self.chunk_left = chunk_left - amt + break + value.append(self._safe_read(chunk_left)) + if amt is not None: + amt -= chunk_left self.chunk_left = 0 return b''.join(value) except IncompleteRead: @@ -608,43 +621,24 @@ class HTTPResponse(io.BufferedIOBase): raise IncompleteRead(bytes(b[0:total_bytes])) def _safe_read(self, amt): - """Read the number of bytes requested, compensating for partial reads. - - Normally, we have a blocking socket, but a read() can be interrupted - by a signal (resulting in a partial read). - - Note that we cannot distinguish between EOF and an interrupt when zero - bytes have been read. IncompleteRead() will be raised in this - situation. + """Read the number of bytes requested. This function should be used when bytes "should" be present for reading. If the bytes are truly not available (due to EOF), then the IncompleteRead exception can be used to detect the problem. """ - s = [] - while amt > 0: - chunk = self.fp.read(min(amt, MAXAMOUNT)) - if not chunk: - raise IncompleteRead(b''.join(s), amt) - s.append(chunk) - amt -= len(chunk) - return b"".join(s) + data = self.fp.read(amt) + if len(data) < amt: + raise IncompleteRead(data, amt-len(data)) + return data def _safe_readinto(self, b): """Same as _safe_read, but for reading into a buffer.""" - total_bytes = 0 - mvb = memoryview(b) - while total_bytes < len(b): - if MAXAMOUNT < len(mvb): - temp_mvb = mvb[0:MAXAMOUNT] - n = self.fp.readinto(temp_mvb) - else: - n = self.fp.readinto(mvb) - if not n: - raise IncompleteRead(bytes(mvb[0:total_bytes]), len(b)) - mvb = mvb[n:] - total_bytes += n - return total_bytes + amt = len(b) + n = self.fp.readinto(b) + if n < amt: + raise IncompleteRead(bytes(b[:n]), amt-n) + return n def read1(self, n=-1): """Read with at most one underlying system call. If at least one @@ -943,6 +937,7 @@ class HTTPConnection: def connect(self): """Connect to the host and port specified in __init__.""" + sys.audit("http.client.connect", self, self.host, self.port) self.sock = self._create_connection( (self.host,self.port), self.timeout, self.source_address) # Might fail in OSs that don't implement TCP_NODELAY @@ -995,8 +990,10 @@ class HTTPConnection: break if encode: datablock = datablock.encode("iso-8859-1") + sys.audit("http.client.send", self, datablock) self.sock.sendall(datablock) return + sys.audit("http.client.send", self, data) try: self.sock.sendall(data) except TypeError: @@ -1422,6 +1419,9 @@ else: 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 diff --git a/contrib/tools/python3/src/Lib/http/cookiejar.py b/contrib/tools/python3/src/Lib/http/cookiejar.py index 47ed5c3d64a..eaa76c26b9c 100644 --- a/contrib/tools/python3/src/Lib/http/cookiejar.py +++ b/contrib/tools/python3/src/Lib/http/cookiejar.py @@ -50,10 +50,18 @@ def _debug(*args): logger = logging.getLogger("http.cookiejar") return logger.debug(*args) - +HTTPONLY_ATTR = "HTTPOnly" +HTTPONLY_PREFIX = "#HttpOnly_" DEFAULT_HTTP_PORT = str(http.client.HTTP_PORT) +NETSCAPE_MAGIC_RGX = re.compile("#( Netscape)? HTTP Cookie File") MISSING_FILENAME_TEXT = ("a filename was not supplied (nor was the CookieJar " "instance initialised with one)") +NETSCAPE_HEADER_TEXT = """\ +# Netscape HTTP Cookie File +# http://curl.haxx.se/rfc/cookie_spec.html +# This is a generated file! Do not edit. + +""" def _warn_unhandled_exception(): # There are a few catch-all except: statements in this module, for @@ -2004,19 +2012,11 @@ class MozillaCookieJar(FileCookieJar): header by default (Mozilla can cope with that). """ - magic_re = re.compile("#( Netscape)? HTTP Cookie File") - header = """\ -# Netscape HTTP Cookie File -# http://curl.haxx.se/rfc/cookie_spec.html -# This is a generated file! Do not edit. - -""" def _really_load(self, f, filename, ignore_discard, ignore_expires): now = time.time() - magic = f.readline() - if not self.magic_re.search(magic): + if not NETSCAPE_MAGIC_RGX.match(f.readline()): raise LoadError( "%r does not look like a Netscape format cookies file" % filename) @@ -2024,8 +2024,17 @@ class MozillaCookieJar(FileCookieJar): try: while 1: 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_" + if line.startswith(HTTPONLY_PREFIX): + rest[HTTPONLY_ATTR] = "" + line = line[len(HTTPONLY_PREFIX):] + # last field may be absent, so keep any trailing tab if line.endswith("\n"): line = line[:-1] @@ -2063,7 +2072,7 @@ class MozillaCookieJar(FileCookieJar): discard, None, None, - {}) + rest) if not ignore_discard and c.discard: continue if not ignore_expires and c.is_expired(now): @@ -2083,16 +2092,17 @@ class MozillaCookieJar(FileCookieJar): else: raise ValueError(MISSING_FILENAME_TEXT) with open(filename, "w") as f: - f.write(self.header) + f.write(NETSCAPE_HEADER_TEXT) now = time.time() for cookie in self: + domain = cookie.domain if not ignore_discard and cookie.discard: continue if not ignore_expires and cookie.is_expired(now): continue if cookie.secure: secure = "TRUE" else: secure = "FALSE" - if cookie.domain.startswith("."): initial_dot = "TRUE" + if domain.startswith("."): initial_dot = "TRUE" else: initial_dot = "FALSE" if cookie.expires is not None: expires = str(cookie.expires) @@ -2107,7 +2117,9 @@ class MozillaCookieJar(FileCookieJar): else: name = cookie.name value = cookie.value + if cookie.has_nonstandard_attr(HTTPONLY_ATTR): + domain = HTTPONLY_PREFIX + domain f.write( - "\t".join([cookie.domain, initial_dot, cookie.path, + "\t".join([domain, initial_dot, cookie.path, secure, expires, name, value])+ "\n") diff --git a/contrib/tools/python3/src/Lib/http/server.py b/contrib/tools/python3/src/Lib/http/server.py index 2d2300c2aea..58abadf7377 100644 --- a/contrib/tools/python3/src/Lib/http/server.py +++ b/contrib/tools/python3/src/Lib/http/server.py @@ -412,7 +412,7 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): method = getattr(self, mname) method() self.wfile.flush() #actually send the response if not already done. - except socket.timeout as e: + except TimeoutError as e: #a read or a write timed out. Discard this connection self.log_error("Request timed out: %r", e) self.close_connection = True @@ -1091,8 +1091,7 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler): env['PATH_INFO'] = uqrest env['PATH_TRANSLATED'] = self.translate_path(uqrest) env['SCRIPT_NAME'] = scriptname - if query: - env['QUERY_STRING'] = query + env['QUERY_STRING'] = query env['REMOTE_ADDR'] = self.client_address[0] authorization = self.headers.get("authorization") if authorization: diff --git a/contrib/tools/python3/src/Lib/imaplib.py b/contrib/tools/python3/src/Lib/imaplib.py index d9720f20c39..73184396d89 100644 --- a/contrib/tools/python3/src/Lib/imaplib.py +++ b/contrib/tools/python3/src/Lib/imaplib.py @@ -1251,13 +1251,12 @@ class IMAP4: sys.stderr.write(' %s.%02d %s\n' % (tm, (secs*100)%100, s)) sys.stderr.flush() - def _dump_ur(self, dict): - # Dump untagged responses (in `dict'). - l = dict.items() - if not l: return - t = '\n\t\t' - l = map(lambda x:'%s: "%s"' % (x[0], x[1][0] and '" "'.join(x[1]) or ''), l) - self._mesg('untagged responses dump:%s%s' % (t, t.join(l))) + def _dump_ur(self, untagged_resp_dict): + if not untagged_resp_dict: + return + items = (f'{key}: {value!r}' + for key, value in untagged_resp_dict.items()) + self._mesg('untagged responses dump:' + '\n\t\t'.join(items)) def _log(self, line): # Keep log of last `_cmd_log_len' interactions for debugging. diff --git a/contrib/tools/python3/src/Lib/imp.py b/contrib/tools/python3/src/Lib/imp.py index 31f8c766381..e02aaef344c 100644 --- a/contrib/tools/python3/src/Lib/imp.py +++ b/contrib/tools/python3/src/Lib/imp.py @@ -28,7 +28,8 @@ import tokenize import types import warnings -warnings.warn("the imp module is deprecated in favour of importlib; " +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) diff --git a/contrib/tools/python3/src/Lib/importlib/__init__.py b/contrib/tools/python3/src/Lib/importlib/__init__.py index 0c73c505f98..ce61883288a 100644 --- a/contrib/tools/python3/src/Lib/importlib/__init__.py +++ b/contrib/tools/python3/src/Lib/importlib/__init__.py @@ -34,7 +34,7 @@ try: import _frozen_importlib_external as _bootstrap_external except ImportError: from . import _bootstrap_external - _bootstrap_external._setup(_bootstrap) + _bootstrap_external._set_bootstrap_module(_bootstrap) _bootstrap._bootstrap_external = _bootstrap_external else: _bootstrap_external.__name__ = 'importlib._bootstrap_external' @@ -54,7 +54,6 @@ _unpack_uint32 = _bootstrap_external._unpack_uint32 # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) -import types import warnings @@ -79,8 +78,8 @@ def find_loader(name, path=None): This function is deprecated in favor of importlib.util.find_spec(). """ - warnings.warn('Deprecated since Python 3.4. ' - 'Use importlib.util.find_spec() instead.', + 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__ @@ -136,12 +135,13 @@ def reload(module): The module must have been successfully imported before. """ - if not module or not isinstance(module, types.ModuleType): - raise TypeError("reload() argument must be a module") try: name = module.__spec__.name except AttributeError: - name = module.__name__ + try: + name = module.__name__ + except AttributeError: + raise TypeError("reload() argument must be a module") if sys.modules.get(name) is not module: msg = "module {} not in sys.modules" diff --git a/contrib/tools/python3/src/Lib/importlib/_abc.py b/contrib/tools/python3/src/Lib/importlib/_abc.py new file mode 100644 index 00000000000..f80348fc7ff --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/_abc.py @@ -0,0 +1,54 @@ +"""Subset of importlib.abc used to reduce importlib.util imports.""" +from . import _bootstrap +import abc +import warnings + + +class Loader(metaclass=abc.ABCMeta): + + """Abstract base class for import loaders.""" + + def create_module(self, spec): + """Return a module to initialize and into which to load. + + This method should raise ImportError if anything prevents it + from creating a new module. It may return None to indicate + that the spec should create the new module. + """ + # By default, defer to default semantics for the new module. + return None + + # We don't define exec_module() here since that would break + # hasattr checks we do to support backward compatibility. + + def load_module(self, fullname): + """Return the loaded module. + + The module must be added to sys.modules and have import-related + attributes set properly. The fullname is a str. + + ImportError is raised on failure. + + This method is deprecated in favor of loader.exec_module(). If + exec_module() exists then it is used to provide a backwards-compatible + functionality for this method. + + """ + if not hasattr(self, 'exec_module'): + 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/contrib/tools/python3/src/Lib/importlib/_adapters.py b/contrib/tools/python3/src/Lib/importlib/_adapters.py new file mode 100644 index 00000000000..e72edd10705 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/_adapters.py @@ -0,0 +1,83 @@ +from contextlib import suppress + +from . import abc + + +class SpecLoaderAdapter: + """ + Adapt a package spec to adapt the underlying loader. + """ + + def __init__(self, spec, adapter=lambda spec: spec.loader): + self.spec = spec + self.loader = adapter(spec) + + def __getattr__(self, name): + return getattr(self.spec, name) + + +class TraversableResourcesLoader: + """ + Adapt a loader to provide TraversableResources. + """ + + def __init__(self, spec): + self.spec = spec + + def get_resource_reader(self, name): + return DegenerateFiles(self.spec)._native() + + +class DegenerateFiles: + """ + Adapter for an existing or non-existant resource reader + to provide a degenerate .files(). + """ + + class Path(abc.Traversable): + def iterdir(self): + return iter(()) + + def is_dir(self): + return False + + is_file = exists = is_dir # type: ignore + + def joinpath(self, other): + return DegenerateFiles.Path() + + @property + def name(self): + return '' + + def open(self, mode='rb', *args, **kwargs): + raise ValueError() + + def __init__(self, spec): + self.spec = spec + + @property + def _reader(self): + with suppress(AttributeError): + return self.spec.loader.get_resource_reader(self.spec.name) + + def _native(self): + """ + Return the native reader if it supports files(). + """ + reader = self._reader + return reader if hasattr(reader, 'files') else self + + def __getattr__(self, attr): + return getattr(self._reader, attr) + + def files(self): + return DegenerateFiles.Path() + + +def wrap_spec(package): + """ + Construct a package spec with traversable compatibility + on the spec/loader/reader. + """ + return SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) diff --git a/contrib/tools/python3/src/Lib/importlib/_bootstrap.py b/contrib/tools/python3/src/Lib/importlib/_bootstrap.py index e00b27ece26..527bc9c63c9 100644 --- a/contrib/tools/python3/src/Lib/importlib/_bootstrap.py +++ b/contrib/tools/python3/src/Lib/importlib/_bootstrap.py @@ -20,10 +20,23 @@ work. One should use importlib as the public-facing version of this module. # reference any injected objects! This includes not only global code but also # anything specified at the class level. +def _object_name(obj): + try: + return obj.__qualname__ + except AttributeError: + return type(obj).__qualname__ + # Bootstrap-related code ###################################################### +# Modules injected manually by _setup() +_thread = None +_warnings = None +_weakref = None + +# Import done by _install_external_importers() _bootstrap_external = None + def _wrap(new, old): """Simple substitute for functools.update_wrapper.""" for replace in ['__module__', '__name__', '__qualname__', '__doc__']: @@ -262,9 +275,12 @@ def _requires_frozen(fxn): def _load_module_shim(self, fullname): """Load the specified module into sys.modules and return it. - This method is deprecated. Use loader.exec_module instead. + This method is deprecated. Use loader.exec_module() instead. """ + msg = ("the load_module() method is deprecated and slated for removal in " + "Python 3.12; use exec_module() instead") + _warnings.warn(msg, DeprecationWarning) spec = spec_from_loader(fullname, self) if fullname in sys.modules: module = sys.modules[fullname] @@ -276,26 +292,16 @@ def _load_module_shim(self, fullname): # Module specifications ####################################################### def _module_repr(module): - # The implementation of ModuleType.__repr__(). + """The implementation of ModuleType.__repr__().""" loader = getattr(module, '__loader__', None) - if hasattr(loader, 'module_repr'): - # As soon as BuiltinImporter, FrozenImporter, and NamespaceLoader - # drop their implementations for module_repr. we can add a - # deprecation warning here. + 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 - try: - spec = module.__spec__ - except AttributeError: - pass - else: - if spec is not None: - return _module_repr_from_spec(spec) - - # We could use module.__class__.__name__ instead of 'module' in the - # various repr permutations. + # Fall through to a catch-all which always succeeds. try: name = module.__name__ except AttributeError: @@ -605,9 +611,9 @@ def _exec(spec, module): else: _init_module_attrs(spec, module, override=True) if not hasattr(spec.loader, 'exec_module'): - # (issue19713) Once BuiltinImporter and ExtensionFileLoader - # have exec_module() implemented, we can add a deprecation - # warning here. + msg = (f"{_object_name(spec.loader)}.exec_module() not found; " + "falling back to load_module()") + _warnings.warn(msg, ImportWarning) spec.loader.load_module(name) else: spec.loader.exec_module(module) @@ -620,9 +626,8 @@ def _exec(spec, module): def _load_backward_compatible(spec): - # (issue19713) Once BuiltinImporter and ExtensionFileLoader - # have exec_module() implemented, we can add a deprecation - # warning here. + # It is assumed that all callers have been warned about using load_module() + # appropriately before calling this function. try: spec.loader.load_module(spec.name) except: @@ -661,6 +666,9 @@ def _load_unlocked(spec): if spec.loader is not None: # Not a namespace package. if not hasattr(spec.loader, 'exec_module'): + msg = (f"{_object_name(spec.loader)}.exec_module() not found; " + "falling back to load_module()") + _warnings.warn(msg, ImportWarning) return _load_backward_compatible(spec) module = module_from_spec(spec) @@ -731,6 +739,8 @@ class BuiltinImporter: 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'' @classmethod @@ -751,19 +761,22 @@ class BuiltinImporter: 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 - @classmethod - def create_module(self, spec): + @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), name=spec.name) return _call_with_frames_removed(_imp.create_builtin, spec) - @classmethod - def exec_module(self, module): + @staticmethod + def exec_module(module): """Exec a built-in module""" _call_with_frames_removed(_imp.exec_builtin, module) @@ -806,6 +819,8 @@ class FrozenImporter: 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 ''.format(m.__name__, FrozenImporter._ORIGIN) @classmethod @@ -822,10 +837,13 @@ class FrozenImporter: 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 - @classmethod - def create_module(cls, spec): + @staticmethod + def create_module(spec): """Use default semantics for module creation.""" @staticmethod @@ -844,6 +862,7 @@ class FrozenImporter: This method is deprecated. Use exec_module() instead. """ + # Warning about deprecation implemented in _load_module_shim(). return _load_module_shim(cls, fullname) @classmethod @@ -890,8 +909,9 @@ def _resolve_name(name, package, level): def _find_spec_legacy(finder, name, path): - # This would be a good place for a DeprecationWarning if - # we ended up going that route. + 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 diff --git a/contrib/tools/python3/src/Lib/importlib/_bootstrap_external.py b/contrib/tools/python3/src/Lib/importlib/_bootstrap_external.py index f3828b10e1c..49bcaea78d7 100644 --- a/contrib/tools/python3/src/Lib/importlib/_bootstrap_external.py +++ b/contrib/tools/python3/src/Lib/importlib/_bootstrap_external.py @@ -19,6 +19,9 @@ work. One should use importlib as the public-facing version of this module. # reference any injected objects! This includes not only global code but also # anything specified at the class level. +# Module injected manually by _set_bootstrap_module() +_bootstrap = None + # Import builtin modules import _imp import _io @@ -70,6 +73,8 @@ def _make_relax_case(): return False return _relax_case +_relax_case = _make_relax_case() + def _pack_uint32(x): """Convert a 32-bit integer to little-endian.""" @@ -337,6 +342,16 @@ _code_type = type(_write_atomic.__code__) # Python 3.9a2 3423 (add IS_OP, CONTAINS_OP and JUMP_IF_NOT_EXC_MATCH bytecodes #39156) # Python 3.9a2 3424 (simplify bytecodes for *value unpacking) # Python 3.9a2 3425 (simplify bytecodes for **value unpacking) +# Python 3.10a1 3430 (Make 'annotations' future by default) +# Python 3.10a1 3431 (New line number table format -- PEP 626) +# Python 3.10a2 3432 (Function annotation for MAKE_FUNCTION is changed from dict to tuple bpo-42202) +# Python 3.10a2 3433 (RERAISE restores f_lasti if oparg != 0) +# Python 3.10a6 3434 (PEP 634: Structural Pattern Matching) +# Python 3.10a7 3435 Use instruction offsets (as opposed to byte offsets). +# Python 3.10b1 3436 (Add GEN_START bytecode #43683) +# Python 3.10b1 3437 (Undo making 'annotations' future by default - We like to dance among core devs!) +# Python 3.10b1 3438 Safer line number table handling. +# Python 3.10b1 3439 (Add ROT_N) # # MAGIC must change whenever the bytecode emitted by the compiler may no @@ -346,13 +361,17 @@ _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 = (3425).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3439).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' _OPT = 'opt-' -SOURCE_SUFFIXES = ['.py'] # _setup() adds .pyw as needed. +SOURCE_SUFFIXES = ['.py'] +if _MS_WINDOWS: + SOURCE_SUFFIXES.append('.pyw') + +EXTENSION_SUFFIXES = _imp.extension_suffixes() BYTECODE_SUFFIXES = ['.pyc'] # Deprecated. @@ -527,15 +546,18 @@ def _check_name(method): raise ImportError('loader for %s cannot handle %s' % (self.name, name), name=name) return method(self, name, *args, **kwargs) - try: + + # FIXME: @_check_name is used to define class methods before the + # _bootstrap module is set by _set_bootstrap_module(). + if _bootstrap is not None: _wrap = _bootstrap._wrap - except NameError: - # XXX yuck + else: def _wrap(new, old): for replace in ['__module__', '__name__', '__qualname__', '__doc__']: if hasattr(old, replace): setattr(new, replace, getattr(old, replace)) new.__dict__.update(old.__dict__) + _wrap(_check_name_wrapper, method) return _check_name_wrapper @@ -547,6 +569,9 @@ def _find_module_shim(self, fullname): 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. @@ -718,6 +743,11 @@ 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 # If the location is on the filesystem, but doesn't actually exist, # we could return None here, indicating that the location is not @@ -771,10 +801,10 @@ class WindowsRegistryFinder: REGISTRY_KEY_DEBUG = ( 'Software\\Python\\PythonCore\\{sys_version}' '\\Modules\\{fullname}\\Debug') - DEBUG_BUILD = False # Changed in _setup() + DEBUG_BUILD = (_MS_WINDOWS and '_d.pyd' in EXTENSION_SUFFIXES) - @classmethod - def _open_registry(cls, key): + @staticmethod + def _open_registry(key): try: return winreg.OpenKey(winreg.HKEY_CURRENT_USER, key) except OSError: @@ -815,9 +845,12 @@ class WindowsRegistryFinder: def find_module(cls, fullname, path=None): """Find module named in the registry. - This method is deprecated. Use exec_module() instead. + 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 @@ -850,7 +883,8 @@ class _LoaderBasics: _bootstrap._call_with_frames_removed(exec, code, module.__dict__) def load_module(self, fullname): - """This module is deprecated.""" + """This method is deprecated.""" + # Warning implemented in _load_module_shim(). return _bootstrap._load_module_shim(self, fullname) @@ -1025,7 +1059,7 @@ class FileLoader: """ # The only reason for this method is for the name check. # Issue #14857: Avoid the zero-argument form of super so the implementation - # of that form can be updated without breaking the frozen module + # of that form can be updated without breaking the frozen module. return super(FileLoader, self).load_module(fullname) @_check_name @@ -1042,32 +1076,10 @@ class FileLoader: with _io.FileIO(path, 'r') as file: return file.read() - # ResourceReader ABC API. - @_check_name def get_resource_reader(self, module): - if self.is_package(module): - return self - return None - - def open_resource(self, resource): - path = _path_join(_path_split(self.path)[0], resource) - return _io.FileIO(path, 'r') - - def resource_path(self, resource): - if not self.is_resource(resource): - raise FileNotFoundError - path = _path_join(_path_split(self.path)[0], resource) - return path - - def is_resource(self, name): - if path_sep in name: - return False - path = _path_join(_path_split(self.path)[0], name) - return _path_isfile(path) - - def contents(self): - return iter(_os.listdir(_path_split(self.path)[0])) + from importlib.readers import FileReader + return FileReader(self) class SourceFileLoader(FileLoader, SourceLoader): @@ -1140,10 +1152,6 @@ class SourcelessFileLoader(FileLoader, _LoaderBasics): return None -# Filled in by _setup(). -EXTENSION_SUFFIXES = [] - - class ExtensionFileLoader(FileLoader, _LoaderBasics): """Loader for extension modules. @@ -1154,11 +1162,6 @@ class ExtensionFileLoader(FileLoader, _LoaderBasics): def __init__(self, name, path): self.name = name - if not _path_isabs(path): - try: - path = _path_join(_os.getcwd(), path) - except OSError: - pass self.path = path def __eq__(self, other): @@ -1275,13 +1278,15 @@ class _NamespaceLoader: def __init__(self, name, path, path_finder): self._path = _NamespacePath(name, path, path_finder) - @classmethod - def module_repr(cls, module): + @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 ''.format(module.__name__) def is_package(self, fullname): @@ -1308,8 +1313,13 @@ class _NamespaceLoader: # The import system never calls this method. _bootstrap._verbose_message('namespace module loaded with path {!r}', self._path) + # Warning implemented in _load_module_shim(). return _bootstrap._load_module_shim(self, fullname) + def get_resource_reader(self, module): + from importlib.readers import NamespaceReader + return NamespaceReader(self._path) + # Finders ##################################################################### @@ -1317,8 +1327,8 @@ class PathFinder: """Meta path finder for sys.path and package __path__ attributes.""" - @classmethod - def invalidate_caches(cls): + @staticmethod + def invalidate_caches(): """Call the invalidate_caches() method on all path entry finders stored in sys.path_importer_caches (where implemented).""" for name, finder in list(sys.path_importer_cache.items()): @@ -1330,8 +1340,8 @@ class PathFinder: # https://bugs.python.org/issue45703 _NamespacePath._epoch += 1 - @classmethod - def _path_hooks(cls, path): + @staticmethod + def _path_hooks(path): """Search sys.path_hooks for a finder for 'path'.""" if sys.path_hooks is not None and not sys.path_hooks: _warnings.warn('sys.path_hooks is empty', ImportWarning) @@ -1370,8 +1380,14 @@ class PathFinder: # 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: @@ -1444,13 +1460,16 @@ class PathFinder: 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 - @classmethod - def find_distributions(cls, *args, **kwargs): + @staticmethod + def find_distributions(*args, **kwargs): """ Find distributions. @@ -1501,6 +1520,9 @@ class FileFinder: 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, [] @@ -1651,66 +1673,14 @@ def _get_supported_file_loaders(): return [extensions, source, bytecode] -def _setup(_bootstrap_module): - """Setup the path-based importers for importlib by importing needed - built-in modules and injecting them into the global namespace. - - Other components are extracted from the core bootstrap module. - - """ - global sys, _imp, _bootstrap +def _set_bootstrap_module(_bootstrap_module): + global _bootstrap _bootstrap = _bootstrap_module - sys = _bootstrap.sys - _imp = _bootstrap._imp - - self_module = sys.modules[__name__] - - # Directly load the os module (needed during bootstrap). - os_details = ('posix', ['/']), ('nt', ['\\', '/']) - for builtin_os, path_separators in os_details: - # Assumption made in _path_join() - assert all(len(sep) == 1 for sep in path_separators) - path_sep = path_separators[0] - if builtin_os in sys.modules: - os_module = sys.modules[builtin_os] - break - else: - try: - os_module = _bootstrap._builtin_from_name(builtin_os) - break - except ImportError: - continue - else: - raise ImportError('importlib requires posix or nt') - - setattr(self_module, '_os', os_module) - setattr(self_module, 'path_sep', path_sep) - setattr(self_module, 'path_separators', ''.join(path_separators)) - setattr(self_module, '_pathseps_with_colon', {f':{s}' for s in path_separators}) - - # Directly load built-in modules needed during bootstrap. - builtin_names = ['_io', '_warnings', 'marshal'] - if builtin_os == 'nt': - builtin_names.append('winreg') - for builtin_name in builtin_names: - if builtin_name not in sys.modules: - builtin_module = _bootstrap._builtin_from_name(builtin_name) - else: - builtin_module = sys.modules[builtin_name] - setattr(self_module, builtin_name, builtin_module) - - # Constants - setattr(self_module, '_relax_case', _make_relax_case()) - EXTENSION_SUFFIXES.extend(_imp.extension_suffixes()) - if builtin_os == 'nt': - SOURCE_SUFFIXES.append('.pyw') - if '_d.pyd' in EXTENSION_SUFFIXES: - WindowsRegistryFinder.DEBUG_BUILD = True def _install(_bootstrap_module): """Install the path-based import components.""" - _setup(_bootstrap_module) + _set_bootstrap_module(_bootstrap_module) supported_loaders = _get_supported_file_loaders() sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) sys.meta_path.append(PathFinder) diff --git a/contrib/tools/python3/src/Lib/importlib/_common.py b/contrib/tools/python3/src/Lib/importlib/_common.py index c1204f0b8f9..549fee379a4 100644 --- a/contrib/tools/python3/src/Lib/importlib/_common.py +++ b/contrib/tools/python3/src/Lib/importlib/_common.py @@ -1,28 +1,82 @@ import os import pathlib -import zipfile import tempfile import functools import contextlib +import types +import importlib +from typing import Union, Any, Optional +from .abc import ResourceReader, Traversable -def from_package(package): +from ._adapters import wrap_spec + +Package = Union[types.ModuleType, str] + + +def files(package): + # type: (Package) -> Traversable """ - Return a Traversable object for the given package. + Get a Traversable resource from a package + """ + return from_package(get_package(package)) + +def normalize_path(path): + # type: (Any) -> str + """Normalize a path by ensuring it is a string. + + If the resulting string contains path separators, an exception is raised. """ - return fallback_resources(package.__spec__) + str_path = str(path) + parent, file_name = os.path.split(str_path) + if parent: + raise ValueError(f'{path!r} must be only a file name') + return file_name -def fallback_resources(spec): - package_directory = pathlib.Path(spec.origin).parent - try: - archive_path = spec.loader.archive - rel_path = package_directory.relative_to(archive_path) - return zipfile.Path(archive_path, str(rel_path) + '/') - except Exception: - pass - return package_directory +def get_resource_reader(package): + # type: (types.ModuleType) -> Optional[ResourceReader] + """ + Return the package's loader if it's a ResourceReader. + """ + # We can't use + # a issubclass() check here because apparently abc.'s __subclasscheck__() + # hook wants to create a weak reference to the object, but + # zipimport.zipimporter does not support weak references, resulting in a + # TypeError. That seems terrible. + spec = package.__spec__ + reader = getattr(spec.loader, 'get_resource_reader', None) # type: ignore + if reader is None: + return None + 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) + + +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. + """ + resolved = resolve(package) + if wrap_spec(resolved).submodule_search_locations is None: + raise TypeError(f'{package!r} is not a package') + return resolved + + +def from_package(package): + """ + Return a Traversable object for the given package. + + """ + spec = wrap_spec(package) + reader = spec.loader.get_resource_reader(spec.name) + return reader.files() @contextlib.contextmanager @@ -34,6 +88,7 @@ def _tempfile(reader, suffix=''): try: os.write(fd, reader()) os.close(fd) + del reader yield pathlib.Path(raw_path) finally: try: @@ -43,14 +98,12 @@ def _tempfile(reader, suffix=''): @functools.singledispatch -@contextlib.contextmanager def as_file(path): """ Given a Traversable object, return that object as a path on the local file system in a context manager. """ - with _tempfile(path.read_bytes, suffix=path.name) as local: - yield local + return _tempfile(path.read_bytes, suffix=path.name) @as_file.register(pathlib.Path) diff --git a/contrib/tools/python3/src/Lib/importlib/abc.py b/contrib/tools/python3/src/Lib/importlib/abc.py index b8a9bb1a21e..0b4a3f80717 100644 --- a/contrib/tools/python3/src/Lib/importlib/abc.py +++ b/contrib/tools/python3/src/Lib/importlib/abc.py @@ -1,5 +1,4 @@ """Abstract base classes related to import.""" -from . import _bootstrap from . import _bootstrap_external from . import machinery try: @@ -12,8 +11,10 @@ try: import _frozen_importlib_external except ImportError: _frozen_importlib_external = _bootstrap_external +from ._abc import Loader import abc import warnings +from typing import BinaryIO, Iterable, Text from typing import Protocol, runtime_checkable @@ -40,15 +41,27 @@ class Finder(metaclass=abc.ABCMeta): 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(Finder): +class MetaPathFinder(metaclass=abc.ABCMeta): """Abstract base class for import finders on sys.meta_path.""" @@ -67,8 +80,8 @@ class MetaPathFinder(Finder): """ warnings.warn("MetaPathFinder.find_module() is deprecated since Python " - "3.4 in favor of MetaPathFinder.find_spec() " - "(available since 3.4)", + "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'): @@ -85,7 +98,7 @@ _register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter, machinery.PathFinder, machinery.WindowsRegistryFinder) -class PathEntryFinder(Finder): +class PathEntryFinder(metaclass=abc.ABCMeta): """Abstract base class for path entry finders used by PathFinder.""" @@ -134,53 +147,6 @@ class PathEntryFinder(Finder): _register(PathEntryFinder, machinery.FileFinder) -class Loader(metaclass=abc.ABCMeta): - - """Abstract base class for import loaders.""" - - def create_module(self, spec): - """Return a module to initialize and into which to load. - - This method should raise ImportError if anything prevents it - from creating a new module. It may return None to indicate - that the spec should create the new module. - """ - # By default, defer to default semantics for the new module. - return None - - # We don't define exec_module() here since that would break - # hasattr checks we do to support backward compatibility. - - def load_module(self, fullname): - """Return the loaded module. - - The module must be added to sys.modules and have import-related - attributes set properly. The fullname is a str. - - ImportError is raised on failure. - - This method is deprecated in favor of loader.exec_module(). If - exec_module() exists then it is used to provide a backwards-compatible - functionality for this method. - - """ - if not hasattr(self, 'exec_module'): - raise ImportError - 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. - - """ - # The exception will cause ModuleType.__repr__ to ignore this method. - raise NotImplementedError - - class ResourceLoader(Loader): """Abstract base class for loaders which can return data from their @@ -344,49 +310,45 @@ _register(SourceLoader, machinery.SourceFileLoader) class ResourceReader(metaclass=abc.ABCMeta): - - """Abstract base class to provide resource-reading support. - - Loaders that support resource reading are expected to implement - the ``get_resource_reader(fullname)`` method and have it either return None - or an object compatible with this ABC. - """ + """Abstract base class for loaders to provide resource reading support.""" @abc.abstractmethod - def open_resource(self, resource): + def open_resource(self, resource: Text) -> BinaryIO: """Return an opened, file-like object for binary reading. - The 'resource' argument is expected to represent only a file name - and thus not contain any subdirectory components. - + The 'resource' argument is expected to represent only a file name. If the resource cannot be found, FileNotFoundError is raised. """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. raise FileNotFoundError @abc.abstractmethod - def resource_path(self, resource): + def resource_path(self, resource: Text) -> Text: """Return the file system path to the specified resource. - The 'resource' argument is expected to represent only a file name - and thus not contain any subdirectory components. - + The 'resource' argument is expected to represent only a file name. If the resource does not exist on the file system, raise FileNotFoundError. """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. raise FileNotFoundError @abc.abstractmethod - def is_resource(self, name): - """Return True if the named 'name' is consider a resource.""" + def is_resource(self, path: Text) -> bool: + """Return True if the named 'path' is a resource. + + Files are resources, directories are not. + """ raise FileNotFoundError @abc.abstractmethod - def contents(self): - """Return an iterable of strings over the contents of the package.""" - return [] - - -_register(ResourceReader, machinery.SourceFileLoader) + def contents(self) -> Iterable[str]: + """Return an iterable of entries in `package`.""" + raise FileNotFoundError @runtime_checkable @@ -402,26 +364,28 @@ class Traversable(Protocol): Yield Traversable objects in self """ - @abc.abstractmethod def read_bytes(self): """ Read contents of self as bytes """ + with self.open('rb') as strm: + return strm.read() - @abc.abstractmethod def read_text(self, encoding=None): """ - Read contents of self as bytes + Read contents of self as text """ + with self.open(encoding=encoding) as strm: + return strm.read() @abc.abstractmethod - def is_dir(self): + def is_dir(self) -> bool: """ Return True if self is a dir """ @abc.abstractmethod - def is_file(self): + def is_file(self) -> bool: """ Return True if self is a file """ @@ -432,11 +396,11 @@ class Traversable(Protocol): Return Traversable child in self """ - @abc.abstractmethod def __truediv__(self, child): """ Return Traversable child in self """ + return self.joinpath(child) @abc.abstractmethod def open(self, mode='r', *args, **kwargs): @@ -449,14 +413,18 @@ class Traversable(Protocol): """ @abc.abstractproperty - def name(self): - # type: () -> str + def name(self) -> str: """ The base name of this object without any parent references. """ class TraversableResources(ResourceReader): + """ + The required interface for providing traversable + resources. + """ + @abc.abstractmethod def files(self): """Return a Traversable object for the loaded package.""" @@ -468,7 +436,7 @@ class TraversableResources(ResourceReader): raise FileNotFoundError(resource) def is_resource(self, path): - return self.files().joinpath(path).isfile() + return self.files().joinpath(path).is_file() def contents(self): return (item.name for item in self.files().iterdir()) diff --git a/contrib/tools/python3/src/Lib/importlib/machinery.py b/contrib/tools/python3/src/Lib/importlib/machinery.py index 1b2b5c9b4f3..9a7757fb6e4 100644 --- a/contrib/tools/python3/src/Lib/importlib/machinery.py +++ b/contrib/tools/python3/src/Lib/importlib/machinery.py @@ -1,7 +1,5 @@ """The machinery of importlib: finders, loaders, hooks, etc.""" -import _imp - from ._bootstrap import ModuleSpec from ._bootstrap import BuiltinImporter from ._bootstrap import FrozenImporter diff --git a/contrib/tools/python3/src/Lib/importlib/metadata.py b/contrib/tools/python3/src/Lib/importlib/metadata.py deleted file mode 100644 index 647fd3e4dbf..00000000000 --- a/contrib/tools/python3/src/Lib/importlib/metadata.py +++ /dev/null @@ -1,604 +0,0 @@ -import io -import os -import re -import abc -import csv -import sys -import email -import pathlib -import zipfile -import operator -import functools -import itertools -import posixpath -import collections - -from configparser import ConfigParser -from contextlib import suppress -from importlib import import_module -from importlib.abc import MetaPathFinder -from itertools import starmap - - -__all__ = [ - 'Distribution', - 'DistributionFinder', - 'PackageNotFoundError', - 'distribution', - 'distributions', - 'entry_points', - 'files', - 'metadata', - 'requires', - 'version', - ] - - -class PackageNotFoundError(ModuleNotFoundError): - """The package was not found.""" - - -class EntryPoint( - collections.namedtuple('EntryPointBase', 'name value group')): - """An entry point as defined by Python packaging conventions. - - See `the packaging docs on entry points - `_ - for more information. - - >>> ep = EntryPoint( - ... name=None, group=None, value='package.module:attr [extra1, extra2]') - >>> ep.module - 'package.module' - >>> ep.attr - 'attr' - >>> ep.extras - ['extra1', 'extra2'] - """ - - pattern = re.compile( - r'(?P[\w.]+)\s*' - r'(:\s*(?P[\w.]+)\s*)?' - r'((?P\[.*\])\s*)?$' - ) - """ - A regular expression describing the syntax for an entry point, - which might look like: - - - module - - package.module - - package.module:attribute - - package.module:object.attribute - - package.module:attr [extra1, extra2] - - Other combinations are possible as well. - - The expression is lenient about whitespace around the ':', - following the attr, and following any extras. - """ - - def load(self): - """Load the entry point from its definition. If only a module - is indicated by the value, return that module. Otherwise, - return the named object. - """ - match = self.pattern.match(self.value) - module = import_module(match.group('module')) - attrs = filter(None, (match.group('attr') or '').split('.')) - return functools.reduce(getattr, attrs, module) - - @property - def module(self): - match = self.pattern.match(self.value) - return match.group('module') - - @property - def attr(self): - match = self.pattern.match(self.value) - return match.group('attr') - - @property - def extras(self): - match = self.pattern.match(self.value) - return re.findall(r'\w+', match.group('extras') or '') - - @classmethod - def _from_config(cls, config): - return [ - cls(name, value, group) - for group in config.sections() - for name, value in config.items(group) - ] - - @classmethod - def _from_text(cls, text): - config = ConfigParser(delimiters='=') - # case sensitive: https://stackoverflow.com/q/1611799/812183 - config.optionxform = str - try: - config.read_string(text) - except AttributeError: # pragma: nocover - # Python 2 has no read_string - config.readfp(io.StringIO(text)) - return EntryPoint._from_config(config) - - def __iter__(self): - """ - Supply iter so one may construct dicts of EntryPoints easily. - """ - return iter((self.name, self)) - - def __reduce__(self): - return ( - self.__class__, - (self.name, self.value, self.group), - ) - - -class PackagePath(pathlib.PurePosixPath): - """A reference to a path in a package""" - - def read_text(self, encoding='utf-8'): - with self.locate().open(encoding=encoding) as stream: - return stream.read() - - def read_binary(self): - with self.locate().open('rb') as stream: - return stream.read() - - def locate(self): - """Return a path-like object for this path""" - return self.dist.locate_file(self) - - -class FileHash: - def __init__(self, spec): - self.mode, _, self.value = spec.partition('=') - - def __repr__(self): - return ''.format(self.mode, self.value) - - -class Distribution: - """A Python distribution package.""" - - @abc.abstractmethod - def read_text(self, filename): - """Attempt to load metadata file given by the name. - - :param filename: The name of the file in the distribution info. - :return: The text if found, otherwise None. - """ - - @abc.abstractmethod - def locate_file(self, path): - """ - Given a path to a file in this distribution, return a path - to it. - """ - - @classmethod - def from_name(cls, name): - """Return the Distribution for the given package name. - - :param name: The name of the distribution package to search for. - :return: The Distribution instance (or subclass thereof) for the named - package, if found. - :raises PackageNotFoundError: When the named package's distribution - metadata cannot be found. - """ - for resolver in cls._discover_resolvers(): - dists = resolver(DistributionFinder.Context(name=name)) - dist = next(iter(dists), None) - if dist is not None: - return dist - else: - raise PackageNotFoundError(name) - - @classmethod - def discover(cls, **kwargs): - """Return an iterable of Distribution objects for all packages. - - Pass a ``context`` or pass keyword arguments for constructing - a context. - - :context: A ``DistributionFinder.Context`` object. - :return: Iterable of Distribution objects for all packages. - """ - context = kwargs.pop('context', None) - if context and kwargs: - raise ValueError("cannot accept context and kwargs") - context = context or DistributionFinder.Context(**kwargs) - return itertools.chain.from_iterable( - resolver(context) - for resolver in cls._discover_resolvers() - ) - - @staticmethod - def at(path): - """Return a Distribution for the indicated metadata path - - :param path: a string or path-like object - :return: a concrete Distribution instance for the path - """ - return PathDistribution(pathlib.Path(path)) - - @staticmethod - def _discover_resolvers(): - """Search the meta_path for resolvers.""" - declared = ( - getattr(finder, 'find_distributions', None) - for finder in sys.meta_path - ) - return filter(None, declared) - - @classmethod - def _local(cls, root='.'): - from pep517 import build, meta - system = build.compat_system(root) - builder = functools.partial( - meta.build, - source_dir=root, - system=system, - ) - return PathDistribution(zipfile.Path(meta.build_as_zip(builder))) - - @property - def metadata(self): - """Return the parsed metadata for this Distribution. - - The returned object will have keys that name the various bits of - metadata. See PEP 566 for details. - """ - text = ( - self.read_text('METADATA') - or self.read_text('PKG-INFO') - # This last clause is here to support old egg-info files. Its - # effect is to just end up using the PathDistribution's self._path - # (which points to the egg-info file) attribute unchanged. - or self.read_text('') - ) - return email.message_from_string(text) - - @property - def version(self): - """Return the 'Version' metadata for the distribution package.""" - return self.metadata['Version'] - - @property - def entry_points(self): - return EntryPoint._from_text(self.read_text('entry_points.txt')) - - @property - def files(self): - """Files in this 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. - Result may be empty if the metadata exists but is empty. - """ - file_lines = self._read_files_distinfo() or self._read_files_egginfo() - - def make_file(name, hash=None, size_str=None): - result = PackagePath(name) - result.hash = FileHash(hash) if hash else None - result.size = int(size_str) if size_str else None - result.dist = self - return result - - return file_lines and list(starmap(make_file, csv.reader(file_lines))) - - def _read_files_distinfo(self): - """ - Read the lines of RECORD - """ - text = self.read_text('RECORD') - return text and text.splitlines() - - def _read_files_egginfo(self): - """ - SOURCES.txt might contain literal commas, so wrap each line - in quotes. - """ - text = self.read_text('SOURCES.txt') - return text and map('"{}"'.format, text.splitlines()) - - @property - def requires(self): - """Generated requirements specified for this Distribution""" - reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() - return reqs and list(reqs) - - def _read_dist_info_reqs(self): - return self.metadata.get_all('Requires-Dist') - - def _read_egg_info_reqs(self): - source = self.read_text('requires.txt') - return None if source is None else self._deps_from_requires_text(source) - - @classmethod - def _deps_from_requires_text(cls, source): - section_pairs = cls._read_sections(source.splitlines()) - sections = { - section: list(map(operator.itemgetter('line'), results)) - for section, results in - itertools.groupby(section_pairs, operator.itemgetter('section')) - } - return cls._convert_egg_info_reqs_to_simple_reqs(sections) - - @staticmethod - def _read_sections(lines): - section = None - for line in filter(None, lines): - section_match = re.match(r'\[(.*)\]$', line) - if section_match: - section = section_match.group(1) - continue - yield locals() - - @staticmethod - def _convert_egg_info_reqs_to_simple_reqs(sections): - """ - Historically, setuptools would solicit and store 'extra' - requirements, including those with environment markers, - in separate sections. More modern tools expect each - dependency to be defined separately, with any relevant - extras and environment markers attached directly to that - requirement. This method converts the former to the - latter. See _test_deps_from_requires_text for an example. - """ - def make_condition(name): - return name and 'extra == "{name}"'.format(name=name) - - def quoted_marker(section): - section = section or '' - extra, sep, markers = section.partition(':') - if extra and markers: - markers = f'({markers})' - conditions = list(filter(None, [markers, make_condition(extra)])) - return '; ' + ' and '.join(conditions) if conditions else '' - - def url_req_space(req): - """ - PEP 508 requires a space between the url_spec and the quoted_marker. - Ref python/importlib_metadata#357. - """ - # '@' is uniquely indicative of a url_req. - return ' ' * ('@' in req) - - for section, deps in sections.items(): - for dep in deps: - space = url_req_space(dep) - yield dep + space + quoted_marker(section) - - -class DistributionFinder(MetaPathFinder): - """ - A MetaPathFinder capable of discovering installed distributions. - """ - - class Context: - """ - Keyword arguments presented by the caller to - ``distributions()`` or ``Distribution.discover()`` - to narrow the scope of a search for distributions - in all DistributionFinders. - - Each DistributionFinder may expect any parameters - and should attempt to honor the canonical - parameters defined below when appropriate. - """ - - name = None - """ - Specific name for which a distribution finder should match. - A name of ``None`` matches all distributions. - """ - - def __init__(self, **kwargs): - vars(self).update(kwargs) - - @property - def path(self): - """ - The path that a distribution finder should search. - - Typically refers to Python package paths and defaults - to ``sys.path``. - """ - return vars(self).get('path', sys.path) - - @abc.abstractmethod - def find_distributions(self, context=Context()): - """ - Find distributions. - - Return an iterable of all Distribution instances capable of - loading the metadata for packages matching the ``context``, - a DistributionFinder.Context instance. - """ - - -class FastPath: - """ - Micro-optimized class for searching a path for - children. - """ - - def __init__(self, root): - self.root = root - self.base = os.path.basename(self.root).lower() - - def joinpath(self, child): - return pathlib.Path(self.root, child) - - def children(self): - with suppress(Exception): - return os.listdir(self.root or '.') - with suppress(Exception): - return self.zip_children() - return [] - - def zip_children(self): - zip_path = zipfile.Path(self.root) - names = zip_path.root.namelist() - self.joinpath = zip_path.joinpath - - return dict.fromkeys( - child.split(posixpath.sep, 1)[0] - for child in names - ) - - def is_egg(self, search): - base = self.base - return ( - base == search.versionless_egg_name - or base.startswith(search.prefix) - and base.endswith('.egg')) - - def search(self, name): - for child in self.children(): - n_low = child.lower() - if (n_low in name.exact_matches - or n_low.startswith(name.prefix) - and n_low.endswith(name.suffixes) - # legacy case: - or self.is_egg(name) and n_low == 'egg-info'): - yield self.joinpath(child) - - -class Prepared: - """ - A prepared search for metadata on a possibly-named package. - """ - normalized = '' - prefix = '' - suffixes = '.dist-info', '.egg-info' - exact_matches = [''][:0] - versionless_egg_name = '' - - def __init__(self, name): - self.name = name - if name is None: - return - self.normalized = name.lower().replace('-', '_') - self.prefix = self.normalized + '-' - self.exact_matches = [ - self.normalized + suffix for suffix in self.suffixes] - self.versionless_egg_name = self.normalized + '.egg' - - -class MetadataPathFinder(DistributionFinder): - @classmethod - def find_distributions(cls, context=DistributionFinder.Context()): - """ - Find distributions. - - Return an iterable of all Distribution instances capable of - loading the metadata for packages matching ``context.name`` - (or all names if ``None`` indicated) along the paths in the list - of directories ``context.path``. - """ - found = cls._search_paths(context.name, context.path) - return map(PathDistribution, found) - - @classmethod - def _search_paths(cls, name, paths): - """Find metadata directories in paths heuristically.""" - return itertools.chain.from_iterable( - path.search(Prepared(name)) - for path in map(FastPath, paths) - ) - - -class PathDistribution(Distribution): - def __init__(self, path): - """Construct a distribution from a path to the metadata directory. - - :param path: A pathlib.Path or similar object supporting - .joinpath(), __div__, .parent, and .read_text(). - """ - self._path = path - - def read_text(self, filename): - with suppress(FileNotFoundError, IsADirectoryError, KeyError, - NotADirectoryError, PermissionError): - return self._path.joinpath(filename).read_text(encoding='utf-8') - read_text.__doc__ = Distribution.read_text.__doc__ - - def locate_file(self, path): - return self._path.parent / path - - -def distribution(distribution_name): - """Get the ``Distribution`` instance for the named package. - - :param distribution_name: The name of the distribution package as a string. - :return: A ``Distribution`` instance (or subclass thereof). - """ - return Distribution.from_name(distribution_name) - - -def distributions(**kwargs): - """Get all ``Distribution`` instances in the current environment. - - :return: An iterable of ``Distribution`` instances. - """ - return Distribution.discover(**kwargs) - - -def metadata(distribution_name): - """Get the metadata for the named package. - - :param distribution_name: The name of the distribution package to query. - :return: An email.Message containing the parsed metadata. - """ - return Distribution.from_name(distribution_name).metadata - - -def version(distribution_name): - """Get the version string for the named package. - - :param distribution_name: The name of the distribution package to query. - :return: The version string for the package as defined in the package's - "Version" metadata key. - """ - return distribution(distribution_name).version - - -def entry_points(): - """Return EntryPoint objects for all installed packages. - - :return: EntryPoint objects for all installed packages. - """ - eps = itertools.chain.from_iterable( - dist.entry_points for dist in distributions()) - by_group = operator.attrgetter('group') - ordered = sorted(eps, key=by_group) - grouped = itertools.groupby(ordered, by_group) - return { - group: tuple(eps) - for group, eps in grouped - } - - -def files(distribution_name): - """Return a list of files for the named package. - - :param distribution_name: The name of the distribution package to query. - :return: List of files composing the distribution. - """ - return distribution(distribution_name).files - - -def requires(distribution_name): - """ - Return a list of requirements for the named package. - - :return: An iterator of requirements, suitable for - packaging.requirement.Requirement. - """ - return distribution(distribution_name).requires diff --git a/contrib/tools/python3/src/Lib/importlib/metadata/__init__.py b/contrib/tools/python3/src/Lib/importlib/metadata/__init__.py new file mode 100644 index 00000000000..b3063cd9915 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/metadata/__init__.py @@ -0,0 +1,1045 @@ +import os +import re +import abc +import csv +import sys +import email +import pathlib +import zipfile +import operator +import textwrap +import warnings +import functools +import itertools +import posixpath +import collections + +from . import _adapters, _meta +from ._meta import PackageMetadata +from ._collections import FreezableDefaultDict, Pair +from ._functools import method_cache +from ._itertools import unique_everseen +from ._meta import PackageMetadata, SimplePath + +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 + + +__all__ = [ + 'Distribution', + 'DistributionFinder', + 'PackageMetadata', + 'PackageNotFoundError', + 'distribution', + 'distributions', + 'entry_points', + 'files', + 'metadata', + 'packages_distributions', + 'requires', + 'version', +] + + +class PackageNotFoundError(ModuleNotFoundError): + """The package was not found.""" + + def __str__(self): + return f"No package metadata was found for {self.name}" + + @property + def name(self): + (name,) = self.args + return name + + +class Sectioned: + """ + A simple entry point config parser for performance + + >>> for item in Sectioned.read(Sectioned._sample): + ... print(item) + Pair(name='sec1', value='# comments ignored') + Pair(name='sec1', value='a = 1') + Pair(name='sec1', value='b = 2') + Pair(name='sec2', value='a = 2') + + >>> res = Sectioned.section_pairs(Sectioned._sample) + >>> item = next(res) + >>> item.name + 'sec1' + >>> item.value + Pair(name='a', value='1') + >>> item = next(res) + >>> item.value + Pair(name='b', value='2') + >>> item = next(res) + >>> item.name + 'sec2' + >>> item.value + Pair(name='a', value='2') + >>> list(res) + [] + """ + + _sample = textwrap.dedent( + """ + [sec1] + # comments ignored + a = 1 + b = 2 + + [sec2] + a = 2 + """ + ).lstrip() + + @classmethod + def section_pairs(cls, text): + return ( + section._replace(value=Pair.parse(section.value)) + for section in cls.read(text, filter_=cls.valid) + if section.name is not None + ) + + @staticmethod + def read(text, filter_=None): + lines = filter(filter_, map(str.strip, text.splitlines())) + name = None + for value in lines: + section_match = value.startswith('[') and value.endswith(']') + if section_match: + name = value.strip('[]') + continue + yield Pair(name, value) + + @staticmethod + def valid(line): + return line and not line.startswith('#') + + +class EntryPoint( + collections.namedtuple('EntryPointBase', 'name value group')): + """An entry point as defined by Python packaging conventions. + + See `the packaging docs on entry points + `_ + for more information. + + >>> ep = EntryPoint( + ... name=None, group=None, value='package.module:attr [extra1, extra2]') + >>> ep.module + 'package.module' + >>> ep.attr + 'attr' + >>> ep.extras + ['extra1', 'extra2'] + """ + + pattern = re.compile( + r'(?P[\w.]+)\s*' + r'(:\s*(?P[\w.]+)\s*)?' + r'((?P\[.*\])\s*)?$' + ) + """ + A regular expression describing the syntax for an entry point, + which might look like: + + - module + - package.module + - package.module:attribute + - package.module:object.attribute + - package.module:attr [extra1, extra2] + + Other combinations are possible as well. + + The expression is lenient about whitespace around the ':', + following the attr, and following any extras. + """ + + dist: Optional['Distribution'] = None + + def load(self): + """Load the entry point from its definition. If only a module + is indicated by the value, return that module. Otherwise, + return the named object. + """ + match = self.pattern.match(self.value) + module = import_module(match.group('module')) + attrs = filter(None, (match.group('attr') or '').split('.')) + return functools.reduce(getattr, attrs, module) + + @property + def module(self): + match = self.pattern.match(self.value) + return match.group('module') + + @property + def attr(self): + match = self.pattern.match(self.value) + return match.group('attr') + + @property + def extras(self): + match = self.pattern.match(self.value) + return re.findall(r'\w+', match.group('extras') or '') + + def _for(self, dist): + self.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 __reduce__(self): + return ( + self.__class__, + (self.name, self.value, self.group), + ) + + def matches(self, **params): + """ + EntryPoint matches the given parameters. + + >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') + >>> ep.matches(group='foo') + True + >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') + True + >>> ep.matches(group='foo', name='other') + False + >>> ep.matches() + True + >>> ep.matches(extras=['extra1', 'extra2']) + True + >>> ep.matches(module='bing') + True + >>> ep.matches(attr='bong') + True + """ + attrs = (getattr(self, param) for param in params) + return all(map(operator.eq, params.values(), attrs)) + + +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 __setitem__(self, *args, **kwargs): + self._warn() + return super().__setitem__(*args, **kwargs) + + def __delitem__(self, *args, **kwargs): + self._warn() + return super().__delitem__(*args, **kwargs) + + def append(self, *args, **kwargs): + self._warn() + return super().append(*args, **kwargs) + + def reverse(self, *args, **kwargs): + self._warn() + return super().reverse(*args, **kwargs) + + def extend(self, *args, **kwargs): + self._warn() + return super().extend(*args, **kwargs) + + def pop(self, *args, **kwargs): + self._warn() + return super().pop(*args, **kwargs) + + def remove(self, *args, **kwargs): + self._warn() + return super().remove(*args, **kwargs) + + def __iadd__(self, *args, **kwargs): + self._warn() + return super().__iadd__(*args, **kwargs) + + def __add__(self, other): + if not isinstance(other, tuple): + self._warn() + other = tuple(other) + return self.__class__(tuple(self) + other) + + def insert(self, *args, **kwargs): + self._warn() + return super().insert(*args, **kwargs) + + def sort(self, *args, **kwargs): + self._warn() + return super().sort(*args, **kwargs) + + def __eq__(self, other): + if not isinstance(other, tuple): + self._warn() + other = tuple(other) + + return tuple(self).__eq__(other) + + +class EntryPoints(DeprecatedList): + """ + An immutable collection of selectable EntryPoint objects. + """ + + __slots__ = () + + def __getitem__(self, name): # -> EntryPoint: + """ + 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: + raise KeyError(name) + + def select(self, **params): + """ + Select entry points from self that match the + given parameters (typically group and/or name). + """ + return EntryPoints(ep for ep in self if ep.matches(**params)) + + @property + def names(self): + """ + Return the set of all names of all entry points. + """ + return set(ep.name for ep in self) + + @property + def groups(self): + """ + Return the set of all groups of all entry points. + + For coverage while SelectableGroups is present. + >>> EntryPoints().groups + set() + """ + return set(ep.group for ep in self) + + @classmethod + def _from_text_for(cls, text, dist): + return cls(ep._for(dist) for ep in cls._from_text(text)) + + @classmethod + def _from_text(cls, text): + return itertools.starmap(EntryPoint, cls._parse_groups(text or '')) + + @staticmethod + def _parse_groups(text): + return ( + (item.value.name, item.value.value, item.name) + for item in Sectioned.section_pairs(text) + ) + + +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""" + + def read_text(self, encoding='utf-8'): + with self.locate().open(encoding=encoding) as stream: + return stream.read() + + def read_binary(self): + with self.locate().open('rb') as stream: + return stream.read() + + def locate(self): + """Return a path-like object for this path""" + return self.dist.locate_file(self) + + +class FileHash: + def __init__(self, spec): + self.mode, _, self.value = spec.partition('=') + + def __repr__(self): + return f'' + + +class Distribution: + """A Python distribution package.""" + + @abc.abstractmethod + def read_text(self, filename): + """Attempt to load metadata file given by the name. + + :param filename: The name of the file in the distribution info. + :return: The text if found, otherwise None. + """ + + @abc.abstractmethod + def locate_file(self, path): + """ + Given a path to a file in this distribution, return a path + to it. + """ + + @classmethod + def from_name(cls, name): + """Return the Distribution for the given package name. + + :param name: The name of the distribution package to search for. + :return: The Distribution instance (or subclass thereof) for the named + package, if found. + :raises PackageNotFoundError: When the named package's distribution + metadata cannot be found. + """ + for resolver in cls._discover_resolvers(): + dists = resolver(DistributionFinder.Context(name=name)) + dist = next(iter(dists), None) + if dist is not None: + return dist + else: + raise PackageNotFoundError(name) + + @classmethod + def discover(cls, **kwargs): + """Return an iterable of Distribution objects for all packages. + + Pass a ``context`` or pass keyword arguments for constructing + a context. + + :context: A ``DistributionFinder.Context`` object. + :return: Iterable of Distribution objects for all packages. + """ + context = kwargs.pop('context', None) + if context and kwargs: + raise ValueError("cannot accept context and kwargs") + context = context or DistributionFinder.Context(**kwargs) + return itertools.chain.from_iterable( + resolver(context) for resolver in cls._discover_resolvers() + ) + + @staticmethod + def at(path): + """Return a Distribution for the indicated metadata path + + :param path: a string or path-like object + :return: a concrete Distribution instance for the path + """ + return PathDistribution(pathlib.Path(path)) + + @staticmethod + def _discover_resolvers(): + """Search the meta_path for resolvers.""" + declared = ( + getattr(finder, 'find_distributions', None) for finder in sys.meta_path + ) + return filter(None, declared) + + @classmethod + def _local(cls, root='.'): + from pep517 import build, meta + + system = build.compat_system(root) + builder = functools.partial( + meta.build, + source_dir=root, + system=system, + ) + return PathDistribution(zipfile.Path(meta.build_as_zip(builder))) + + @property + def metadata(self) -> _meta.PackageMetadata: + """Return the parsed metadata for this Distribution. + + The returned object will have keys that name the various bits of + metadata. See PEP 566 for details. + """ + text = ( + self.read_text('METADATA') + or self.read_text('PKG-INFO') + # This last clause is here to support old egg-info files. Its + # effect is to just end up using the PathDistribution's self._path + # (which points to the egg-info file) attribute unchanged. + or self.read_text('') + ) + return _adapters.Message(email.message_from_string(text)) + + @property + def name(self): + """Return the 'Name' metadata for the distribution package.""" + return self.metadata['Name'] + + @property + def _normalized_name(self): + """Return a normalized version of the name.""" + return Prepared.normalize(self.name) + + @property + def version(self): + """Return the 'Version' metadata for the distribution package.""" + return self.metadata['Version'] + + @property + def entry_points(self): + return EntryPoints._from_text_for(self.read_text('entry_points.txt'), self) + + @property + def files(self): + """Files in this 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. + Result may be empty if the metadata exists but is empty. + """ + file_lines = self._read_files_distinfo() or self._read_files_egginfo() + + def make_file(name, hash=None, size_str=None): + result = PackagePath(name) + result.hash = FileHash(hash) if hash else None + result.size = int(size_str) if size_str else None + result.dist = self + return result + + return file_lines and list(starmap(make_file, csv.reader(file_lines))) + + def _read_files_distinfo(self): + """ + Read the lines of RECORD + """ + text = self.read_text('RECORD') + return text and text.splitlines() + + def _read_files_egginfo(self): + """ + SOURCES.txt might contain literal commas, so wrap each line + in quotes. + """ + text = self.read_text('SOURCES.txt') + return text and map('"{}"'.format, text.splitlines()) + + @property + def requires(self): + """Generated requirements specified for this Distribution""" + reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() + return reqs and list(reqs) + + def _read_dist_info_reqs(self): + return self.metadata.get_all('Requires-Dist') + + def _read_egg_info_reqs(self): + source = self.read_text('requires.txt') + return None if source is None else self._deps_from_requires_text(source) + + @classmethod + def _deps_from_requires_text(cls, source): + return cls._convert_egg_info_reqs_to_simple_reqs(Sectioned.read(source)) + + @staticmethod + def _convert_egg_info_reqs_to_simple_reqs(sections): + """ + Historically, setuptools would solicit and store 'extra' + requirements, including those with environment markers, + in separate sections. More modern tools expect each + dependency to be defined separately, with any relevant + extras and environment markers attached directly to that + requirement. This method converts the former to the + latter. See _test_deps_from_requires_text for an example. + """ + + def make_condition(name): + return name and f'extra == "{name}"' + + def quoted_marker(section): + section = section or '' + extra, sep, markers = section.partition(':') + if extra and markers: + markers = f'({markers})' + conditions = list(filter(None, [markers, make_condition(extra)])) + return '; ' + ' and '.join(conditions) if conditions else '' + + def url_req_space(req): + """ + PEP 508 requires a space between the url_spec and the quoted_marker. + Ref python/importlib_metadata#357. + """ + # '@' is uniquely indicative of a url_req. + return ' ' * ('@' in req) + + for section in sections: + space = url_req_space(section.value) + yield section.value + space + quoted_marker(section.name) + + +class DistributionFinder(MetaPathFinder): + """ + A MetaPathFinder capable of discovering installed distributions. + """ + + class Context: + """ + Keyword arguments presented by the caller to + ``distributions()`` or ``Distribution.discover()`` + to narrow the scope of a search for distributions + in all DistributionFinders. + + Each DistributionFinder may expect any parameters + and should attempt to honor the canonical + parameters defined below when appropriate. + """ + + name = None + """ + Specific name for which a distribution finder should match. + A name of ``None`` matches all distributions. + """ + + def __init__(self, **kwargs): + vars(self).update(kwargs) + + @property + def path(self): + """ + The sequence of directory path that a distribution finder + should search. + + Typically refers to Python installed package paths such as + "site-packages" directories and defaults to ``sys.path``. + """ + return vars(self).get('path', sys.path) + + @abc.abstractmethod + def find_distributions(self, context=Context()): + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching the ``context``, + a DistributionFinder.Context instance. + """ + + +class FastPath: + """ + Micro-optimized class for searching a path for + children. + """ + + @functools.lru_cache() # type: ignore + def __new__(cls, root): + return super().__new__(cls) + + def __init__(self, root): + self.root = root + + def joinpath(self, child): + return pathlib.Path(self.root, child) + + def children(self): + with suppress(Exception): + return os.listdir(self.root or '.') + with suppress(Exception): + return self.zip_children() + return [] + + def zip_children(self): + zip_path = zipfile.Path(self.root) + names = zip_path.root.namelist() + self.joinpath = zip_path.joinpath + + return dict.fromkeys(child.split(posixpath.sep, 1)[0] for child in names) + + def search(self, name): + return self.lookup(self.mtime).search(name) + + @property + def mtime(self): + with suppress(OSError): + return os.stat(self.root).st_mtime + self.lookup.cache_clear() + + @method_cache + def lookup(self, mtime): + return Lookup(self) + + +class Lookup: + def __init__(self, path: FastPath): + base = os.path.basename(path.root).lower() + base_is_egg = base.endswith(".egg") + self.infos = FreezableDefaultDict(list) + self.eggs = FreezableDefaultDict(list) + + for child in path.children(): + low = child.lower() + if low.endswith((".dist-info", ".egg-info")): + # rpartition is faster than splitext and suitable for this purpose. + name = low.rpartition(".")[0].partition("-")[0] + normalized = Prepared.normalize(name) + self.infos[normalized].append(path.joinpath(child)) + elif base_is_egg and low == "egg-info": + name = base.rpartition(".")[0].partition("-")[0] + legacy_normalized = Prepared.legacy_normalize(name) + self.eggs[legacy_normalized].append(path.joinpath(child)) + + self.infos.freeze() + self.eggs.freeze() + + def search(self, prepared): + infos = ( + self.infos[prepared.normalized] + if prepared + else itertools.chain.from_iterable(self.infos.values()) + ) + eggs = ( + self.eggs[prepared.legacy_normalized] + if prepared + else itertools.chain.from_iterable(self.eggs.values()) + ) + return itertools.chain(infos, eggs) + + +class Prepared: + """ + A prepared search for metadata on a possibly-named package. + """ + + normalized = None + legacy_normalized = None + + def __init__(self, name): + self.name = name + if name is None: + return + self.normalized = self.normalize(name) + self.legacy_normalized = self.legacy_normalize(name) + + @staticmethod + def normalize(name): + """ + PEP 503 normalization plus dashes as underscores. + """ + return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_') + + @staticmethod + def legacy_normalize(name): + """ + Normalize the package name as found in the convention in + older packaging tools versions and specs. + """ + return name.lower().replace('-', '_') + + def __bool__(self): + return bool(self.name) + + +class MetadataPathFinder(DistributionFinder): + @classmethod + def find_distributions(cls, context=DistributionFinder.Context()): + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching ``context.name`` + (or all names if ``None`` indicated) along the paths in the list + of directories ``context.path``. + """ + found = cls._search_paths(context.name, context.path) + return map(PathDistribution, found) + + @classmethod + def _search_paths(cls, name, paths): + """Find metadata directories in paths heuristically.""" + prepared = Prepared(name) + return itertools.chain.from_iterable( + path.search(prepared) for path in map(FastPath, paths) + ) + + def invalidate_caches(cls): + FastPath.__new__.cache_clear() + + +class PathDistribution(Distribution): + def __init__(self, path: SimplePath): + """Construct a distribution. + + :param path: SimplePath indicating the metadata directory. + """ + self._path = path + + def read_text(self, filename): + with suppress( + FileNotFoundError, + IsADirectoryError, + KeyError, + NotADirectoryError, + PermissionError, + ): + return self._path.joinpath(filename).read_text(encoding='utf-8') + + read_text.__doc__ = Distribution.read_text.__doc__ + + def locate_file(self, path): + return self._path.parent / path + + @property + def _normalized_name(self): + """ + Performance optimization: where possible, resolve the + normalized name from the file system path. + """ + stem = os.path.basename(str(self._path)) + return self._name_from_stem(stem) or super()._normalized_name + + def _name_from_stem(self, stem): + name, ext = os.path.splitext(stem) + if ext not in ('.dist-info', '.egg-info'): + return + name, sep, rest = stem.partition('-') + return name + + +def distribution(distribution_name): + """Get the ``Distribution`` instance for the named package. + + :param distribution_name: The name of the distribution package as a string. + :return: A ``Distribution`` instance (or subclass thereof). + """ + return Distribution.from_name(distribution_name) + + +def distributions(**kwargs): + """Get all ``Distribution`` instances in the current environment. + + :return: An iterable of ``Distribution`` instances. + """ + return Distribution.discover(**kwargs) + + +def metadata(distribution_name) -> _meta.PackageMetadata: + """Get the metadata for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: A PackageMetadata containing the parsed metadata. + """ + return Distribution.from_name(distribution_name).metadata + + +def version(distribution_name): + """Get the version string for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: The version string for the package as defined in the package's + "Version" metadata key. + """ + return distribution(distribution_name).version + + +def entry_points(**params) -> Union[EntryPoints, SelectableGroups]: + """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. + """ + norm_name = operator.attrgetter('_normalized_name') + unique = functools.partial(unique_everseen, key=norm_name) + eps = itertools.chain.from_iterable( + dist.entry_points for dist in unique(distributions()) + ) + return SelectableGroups.load(eps).select(**params) + + +def files(distribution_name): + """Return a list of files for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: List of files composing the distribution. + """ + return distribution(distribution_name).files + + +def requires(distribution_name): + """ + Return a list of requirements for the named package. + + :return: An iterator of requirements, suitable for + packaging.requirement.Requirement. + """ + return distribution(distribution_name).requires + + +def packages_distributions() -> Mapping[str, List[str]]: + """ + Return a mapping of top-level packages to their + distributions. + + >>> import collections.abc + >>> pkgs = packages_distributions() + >>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values()) + True + """ + pkg_to_dist = collections.defaultdict(list) + for dist in distributions(): + for pkg in (dist.read_text('top_level.txt') or '').split(): + pkg_to_dist[pkg].append(dist.metadata['Name']) + return dict(pkg_to_dist) diff --git a/contrib/tools/python3/src/Lib/importlib/metadata/_adapters.py b/contrib/tools/python3/src/Lib/importlib/metadata/_adapters.py new file mode 100644 index 00000000000..aa460d3eda5 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/metadata/_adapters.py @@ -0,0 +1,68 @@ +import re +import textwrap +import email.message + +from ._text import FoldedCase + + +class Message(email.message.Message): + multiple_use_keys = set( + map( + FoldedCase, + [ + 'Classifier', + 'Obsoletes-Dist', + 'Platform', + 'Project-URL', + 'Provides-Dist', + 'Provides-Extra', + 'Requires-Dist', + 'Requires-External', + 'Supported-Platform', + 'Dynamic', + ], + ) + ) + """ + Keys that may be indicated multiple times per PEP 566. + """ + + def __new__(cls, orig: email.message.Message): + res = super().__new__(cls) + vars(res).update(vars(orig)) + return res + + def __init__(self, *args, **kwargs): + self._headers = self._repair_headers() + + # suppress spurious error from mypy + def __iter__(self): + return super().__iter__() + + def _repair_headers(self): + def redent(value): + "Correct for RFC822 indentation" + if not value or '\n' not in value: + return value + return textwrap.dedent(' ' * 8 + value) + + headers = [(key, redent(value)) for key, value in vars(self)['_headers']] + if self._payload: + headers.append(('Description', self.get_payload())) + return headers + + @property + def json(self): + """ + Convert PackageMetadata to a JSON-compatible format + per PEP 0566. + """ + + def transform(key): + value = self.get_all(key) if key in self.multiple_use_keys else self[key] + if key == 'Keywords': + value = re.split(r'\s+', value) + tk = key.lower().replace('-', '_') + return tk, value + + return dict(map(transform, map(FoldedCase, self))) diff --git a/contrib/tools/python3/src/Lib/importlib/metadata/_collections.py b/contrib/tools/python3/src/Lib/importlib/metadata/_collections.py new file mode 100644 index 00000000000..cf0954e1a30 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/metadata/_collections.py @@ -0,0 +1,30 @@ +import collections + + +# from jaraco.collections 3.3 +class FreezableDefaultDict(collections.defaultdict): + """ + Often it is desirable to prevent the mutation of + a default dict after its initial construction, such + as to prevent mutation during iteration. + + >>> dd = FreezableDefaultDict(list) + >>> dd[0].append('1') + >>> dd.freeze() + >>> dd[1] + [] + >>> len(dd) + 1 + """ + + def __missing__(self, key): + return getattr(self, '_frozen', super().__missing__)(key) + + def freeze(self): + self._frozen = lambda key: self.default_factory() + + +class Pair(collections.namedtuple('Pair', 'name value')): + @classmethod + def parse(cls, text): + return cls(*map(str.strip, text.split("=", 1))) diff --git a/contrib/tools/python3/src/Lib/importlib/metadata/_functools.py b/contrib/tools/python3/src/Lib/importlib/metadata/_functools.py new file mode 100644 index 00000000000..73f50d00bc0 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/metadata/_functools.py @@ -0,0 +1,85 @@ +import types +import functools + + +# from jaraco.functools 3.3 +def method_cache(method, cache_wrapper=None): + """ + Wrap lru_cache to support storing the cache data in the object instances. + + Abstracts the common paradigm where the method explicitly saves an + underscore-prefixed protected property on first call and returns that + subsequently. + + >>> class MyClass: + ... calls = 0 + ... + ... @method_cache + ... def method(self, value): + ... self.calls += 1 + ... return value + + >>> a = MyClass() + >>> a.method(3) + 3 + >>> for x in range(75): + ... res = a.method(x) + >>> a.calls + 75 + + Note that the apparent behavior will be exactly like that of lru_cache + except that the cache is stored on each instance, so values in one + instance will not flush values from another, and when an instance is + deleted, so are the cached values for that instance. + + >>> b = MyClass() + >>> for x in range(35): + ... res = b.method(x) + >>> b.calls + 35 + >>> a.method(0) + 0 + >>> a.calls + 75 + + Note that if method had been decorated with ``functools.lru_cache()``, + a.calls would have been 76 (due to the cached value of 0 having been + flushed by the 'b' instance). + + Clear the cache with ``.cache_clear()`` + + >>> a.method.cache_clear() + + Same for a method that hasn't yet been called. + + >>> c = MyClass() + >>> c.method.cache_clear() + + Another cache wrapper may be supplied: + + >>> cache = functools.lru_cache(maxsize=2) + >>> MyClass.method2 = method_cache(lambda self: 3, cache_wrapper=cache) + >>> a = MyClass() + >>> a.method2() + 3 + + Caution - do not subsequently wrap the method with another decorator, such + as ``@property``, which changes the semantics of the function. + + See also + http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ + for another implementation and additional justification. + """ + cache_wrapper = cache_wrapper or functools.lru_cache() + + def wrapper(self, *args, **kwargs): + # it's the first call, replace the method with a cached, bound method + bound_method = types.MethodType(method, self) + cached_method = cache_wrapper(bound_method) + setattr(self, method.__name__, cached_method) + return cached_method(*args, **kwargs) + + # Support cache clear even before cache has been created. + wrapper.cache_clear = lambda: None + + return wrapper diff --git a/contrib/tools/python3/src/Lib/importlib/metadata/_itertools.py b/contrib/tools/python3/src/Lib/importlib/metadata/_itertools.py new file mode 100644 index 00000000000..dd45f2f0966 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/metadata/_itertools.py @@ -0,0 +1,19 @@ +from itertools import filterfalse + + +def unique_everseen(iterable, key=None): + "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() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element diff --git a/contrib/tools/python3/src/Lib/importlib/metadata/_meta.py b/contrib/tools/python3/src/Lib/importlib/metadata/_meta.py new file mode 100644 index 00000000000..1a6edbf957d --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/metadata/_meta.py @@ -0,0 +1,47 @@ +from typing import Any, Dict, Iterator, List, Protocol, TypeVar, Union + + +_T = TypeVar("_T") + + +class PackageMetadata(Protocol): + def __len__(self) -> int: + ... # pragma: no cover + + def __contains__(self, item: str) -> bool: + ... # pragma: no cover + + def __getitem__(self, key: str) -> str: + ... # pragma: no cover + + def __iter__(self) -> Iterator[str]: + ... # pragma: no cover + + def get_all(self, name: str, failobj: _T = ...) -> Union[List[Any], _T]: + """ + Return all values associated with a possibly multi-valued key. + """ + + @property + def json(self) -> Dict[str, Union[str, List[str]]]: + """ + A JSON-compatible form of the metadata. + """ + + +class SimplePath(Protocol): + """ + A minimal subset of pathlib.Path required by PathDistribution. + """ + + def joinpath(self) -> 'SimplePath': + ... # pragma: no cover + + def __div__(self) -> 'SimplePath': + ... # pragma: no cover + + def parent(self) -> 'SimplePath': + ... # pragma: no cover + + def read_text(self) -> str: + ... # pragma: no cover diff --git a/contrib/tools/python3/src/Lib/importlib/metadata/_text.py b/contrib/tools/python3/src/Lib/importlib/metadata/_text.py new file mode 100644 index 00000000000..766979d93c1 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/metadata/_text.py @@ -0,0 +1,99 @@ +import re + +from ._functools import method_cache + + +# from jaraco.text 3.5 +class FoldedCase(str): + """ + A case insensitive string class; behaves just like str + except compares equal when the only variation is case. + + >>> s = FoldedCase('hello world') + + >>> s == 'Hello World' + True + + >>> 'Hello World' == s + True + + >>> s != 'Hello World' + False + + >>> s.index('O') + 4 + + >>> s.split('O') + ['hell', ' w', 'rld'] + + >>> sorted(map(FoldedCase, ['GAMMA', 'alpha', 'Beta'])) + ['alpha', 'Beta', 'GAMMA'] + + Sequence membership is straightforward. + + >>> "Hello World" in [s] + True + >>> s in ["Hello World"] + True + + You may test for set inclusion, but candidate and elements + must both be folded. + + >>> FoldedCase("Hello World") in {s} + True + >>> s in {FoldedCase("Hello World")} + True + + String inclusion works as long as the FoldedCase object + is on the right. + + >>> "hello" in FoldedCase("Hello World") + True + + But not if the FoldedCase object is on the left: + + >>> FoldedCase('hello') in 'Hello World' + False + + In that case, use in_: + + >>> FoldedCase('hello').in_('Hello World') + True + + >>> FoldedCase('hello') > FoldedCase('Hello') + False + """ + + def __lt__(self, other): + return self.lower() < other.lower() + + def __gt__(self, other): + return self.lower() > other.lower() + + def __eq__(self, other): + return self.lower() == other.lower() + + def __ne__(self, other): + return self.lower() != other.lower() + + def __hash__(self): + return hash(self.lower()) + + def __contains__(self, other): + return super(FoldedCase, self).lower().__contains__(other.lower()) + + def in_(self, other): + "Does self appear in other?" + return self in FoldedCase(other) + + # cache lower since it's likely to be called frequently. + @method_cache + def lower(self): + return super(FoldedCase, self).lower() + + def index(self, sub): + return self.lower().index(sub.lower()) + + def split(self, splitter=' ', maxsplit=0): + pattern = re.compile(re.escape(splitter), re.I) + return pattern.split(self, maxsplit) diff --git a/contrib/tools/python3/src/Lib/importlib/readers.py b/contrib/tools/python3/src/Lib/importlib/readers.py new file mode 100644 index 00000000000..41089c071d8 --- /dev/null +++ b/contrib/tools/python3/src/Lib/importlib/readers.py @@ -0,0 +1,123 @@ +import collections +import zipfile +import pathlib +from . import abc + + +def remove_duplicates(items): + return iter(collections.OrderedDict.fromkeys(items)) + + +class FileReader(abc.TraversableResources): + def __init__(self, loader): + self.path = pathlib.Path(loader.path).parent + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path + + +class ZipReader(abc.TraversableResources): + def __init__(self, loader, module): + _, _, name = module.rpartition('.') + self.prefix = loader.prefix.replace('\\', '/') + name + '/' + self.archive = loader.archive + + def open_resource(self, resource): + try: + return super().open_resource(resource) + except KeyError as exc: + raise FileNotFoundError(exc.args[0]) + + def is_resource(self, path): + # workaround for `zipfile.Path.is_file` returning true + # for non-existent paths. + target = self.files().joinpath(path) + return target.is_file() and target.exists() + + def files(self): + return zipfile.Path(self.archive, self.prefix) + + +class MultiplexedPath(abc.Traversable): + """ + Given a series of Traversable objects, implement a merged + version of the interface across all objects. Useful for + namespace packages which may be multihomed at a single + name. + """ + + def __init__(self, *paths): + self._paths = list(map(pathlib.Path, remove_duplicates(paths))) + if not self._paths: + message = 'MultiplexedPath must contain at least one path' + raise FileNotFoundError(message) + if not all(path.is_dir() for path in self._paths): + raise NotADirectoryError('MultiplexedPath only supports directories') + + def iterdir(self): + visited = [] + for path in self._paths: + for file in path.iterdir(): + if file.name in visited: + continue + visited.append(file.name) + yield file + + def read_bytes(self): + raise FileNotFoundError(f'{self} is not a file') + + def read_text(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + def is_dir(self): + return True + + 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 + + __truediv__ = joinpath + + def open(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + @property + def name(self): + return self._paths[0].name + + def __repr__(self): + paths = ', '.join(f"'{path}'" for path in self._paths) + return f'MultiplexedPath({paths})' + + +class NamespaceReader(abc.TraversableResources): + def __init__(self, namespace_path): + if 'NamespacePath' not in str(namespace_path): + raise ValueError('Invalid path') + self.path = MultiplexedPath(*list(namespace_path)) + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path diff --git a/contrib/tools/python3/src/Lib/importlib/resources.py b/contrib/tools/python3/src/Lib/importlib/resources.py index b803a01c91d..8a98663ff8e 100644 --- a/contrib/tools/python3/src/Lib/importlib/resources.py +++ b/contrib/tools/python3/src/Lib/importlib/resources.py @@ -1,22 +1,26 @@ import os +import io -from . import abc as resources_abc from . import _common -from ._common import as_file -from contextlib import contextmanager, suppress -from importlib import import_module +from ._common import as_file, files +from .abc import ResourceReader +from contextlib import suppress from importlib.abc import ResourceLoader +from importlib.machinery import ModuleSpec from io import BytesIO, TextIOWrapper from pathlib import Path from types import ModuleType -from typing import ContextManager, Iterable, Optional, Union +from typing import ContextManager, Iterable, Union from typing import cast from typing.io import BinaryIO, TextIO +from collections.abc import Sequence +from functools import singledispatch __all__ = [ 'Package', 'Resource', + 'ResourceReader', 'as_file', 'contents', 'files', @@ -26,99 +30,57 @@ __all__ = [ 'path', 'read_binary', 'read_text', - ] +] Package = Union[str, ModuleType] Resource = Union[str, os.PathLike] -def _resolve(name) -> ModuleType: - """If name is a string, resolve to a module.""" - if hasattr(name, '__spec__'): - return name - return import_module(name) - - -def _get_package(package) -> ModuleType: - """Take a package name or module object and return the module. - - If a name, the module is imported. If the resolved module - object is not a package, raise an exception. - """ - module = _resolve(package) - if module.__spec__.submodule_search_locations is None: - raise TypeError('{!r} is not a package'.format(package)) - return module - - -def _normalize_path(path) -> str: - """Normalize a path by ensuring it is a string. - - If the resulting string contains path separators, an exception is raised. - """ - parent, file_name = os.path.split(path) - if parent: - raise ValueError('{!r} must be only a file name'.format(path)) - return file_name - - -def _get_resource_reader( - package: ModuleType) -> Optional[resources_abc.ResourceReader]: - # Return the package's loader if it's a ResourceReader. We can't use - # a issubclass() check here because apparently abc.'s __subclasscheck__() - # hook wants to create a weak reference to the object, but - # zipimport.zipimporter does not support weak references, resulting in a - # TypeError. That seems terrible. - spec = package.__spec__ - if hasattr(spec.loader, 'get_resource_reader'): - return cast(resources_abc.ResourceReader, - spec.loader.get_resource_reader(spec.name)) - return None - - -def _check_location(package): - if package.__spec__.origin is None or not package.__spec__.has_location: - raise FileNotFoundError(f'Package has no location {package!r}') - - def open_binary(package: Package, resource: Resource) -> BinaryIO: """Return a file-like object opened for binary reading of the resource.""" - resource = _normalize_path(resource) - package = _get_package(package) - reader = _get_resource_reader(package) + resource = _common.normalize_path(resource) + package = _common.get_package(package) + reader = _common.get_resource_reader(package) if reader is not None: return reader.open_resource(resource) - absolute_package_path = os.path.abspath( - package.__spec__.origin or 'non-existent file') - package_path = os.path.dirname(absolute_package_path) - full_path = os.path.join(package_path, resource) - try: - return open(full_path, mode='rb') - except OSError: - # Just assume the loader is a resource loader; all the relevant - # importlib.machinery loaders are and an AttributeError for - # get_data() will make it clear what is needed from the loader. - loader = cast(ResourceLoader, package.__spec__.loader) - data = None - if hasattr(package.__spec__.loader, 'get_data'): - with suppress(OSError): - data = loader.get_data(full_path) - if data is None: - package_name = package.__spec__.name - message = '{!r} resource not found in {!r}'.format( - resource, package_name) - raise FileNotFoundError(message) - return BytesIO(data) - - -def open_text(package: Package, - resource: Resource, - encoding: str = 'utf-8', - errors: str = 'strict') -> TextIO: + spec = cast(ModuleSpec, package.__spec__) + # Using pathlib doesn't work well here due to the lack of 'strict' + # argument for pathlib.Path.resolve() prior to Python 3.6. + if spec.submodule_search_locations is not None: + paths = spec.submodule_search_locations + elif spec.origin is not None: + paths = [os.path.dirname(os.path.abspath(spec.origin))] + + for package_path in paths: + full_path = os.path.join(package_path, resource) + try: + return open(full_path, mode='rb') + except OSError: + # Just assume the loader is a resource loader; all the relevant + # importlib.machinery loaders are and an AttributeError for + # get_data() will make it clear what is needed from the loader. + loader = cast(ResourceLoader, spec.loader) + data = None + if hasattr(spec.loader, 'get_data'): + with suppress(OSError): + data = loader.get_data(full_path) + if data is not None: + return BytesIO(data) + + raise FileNotFoundError(f'{resource!r} resource not found in {spec.name!r}') + + +def open_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict', +) -> TextIO: """Return a file-like object opened for text reading of the resource.""" return TextIOWrapper( - open_binary(package, resource), encoding=encoding, errors=errors) + open_binary(package, resource), encoding=encoding, errors=errors + ) def read_binary(package: Package, resource: Resource) -> bytes: @@ -127,10 +89,12 @@ def read_binary(package: Package, resource: Resource) -> bytes: return fp.read() -def read_text(package: Package, - resource: Resource, - encoding: str = 'utf-8', - errors: str = 'strict') -> str: +def read_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict', +) -> str: """Return the decoded string of the resource. The decoding-related arguments have the same semantics as those of @@ -140,16 +104,10 @@ def read_text(package: Package, return fp.read() -def files(package: Package) -> resources_abc.Traversable: - """ - Get a Traversable resource from a package - """ - return _common.from_package(_get_package(package)) - - def path( - package: Package, resource: Resource, - ) -> 'ContextManager[Path]': + package: Package, + resource: Resource, +) -> 'ContextManager[Path]': """A context manager providing a file path object to the resource. If the resource does not already exist on its own on the file system, @@ -158,23 +116,30 @@ def path( raised if the file was deleted prior to the context manager exiting). """ - reader = _get_resource_reader(_get_package(package)) + reader = _common.get_resource_reader(_common.get_package(package)) return ( - _path_from_reader(reader, resource) - if reader else - _common.as_file(files(package).joinpath(_normalize_path(resource))) + _path_from_reader(reader, _common.normalize_path(resource)) + if reader + else _common.as_file( + _common.files(package).joinpath(_common.normalize_path(resource)) ) + ) -@contextmanager def _path_from_reader(reader, resource): - norm_resource = _normalize_path(resource) + return _path_from_resource_path(reader, resource) or _path_from_open_resource( + reader, resource + ) + + +def _path_from_resource_path(reader, resource): with suppress(FileNotFoundError): - yield Path(reader.resource_path(norm_resource)) - return - opener_reader = reader.open_resource(norm_resource) - with _common._tempfile(opener_reader.read, suffix=norm_resource) as res: - yield res + return Path(reader.resource_path(resource)) + + +def _path_from_open_resource(reader, resource): + saved = io.BytesIO(reader.open_resource(resource).read()) + return _common._tempfile(saved.read, suffix=resource) def is_resource(package: Package, name: str) -> bool: @@ -182,9 +147,9 @@ def is_resource(package: Package, name: str) -> bool: Directories are *not* resources. """ - package = _get_package(package) - _normalize_path(name) - reader = _get_resource_reader(package) + package = _common.get_package(package) + _common.normalize_path(name) + reader = _common.get_resource_reader(package) if reader is not None: return reader.is_resource(name) package_contents = set(contents(package)) @@ -200,16 +165,21 @@ def contents(package: Package) -> Iterable[str]: not considered resources. Use `is_resource()` on each entry returned here to check if it is a resource or not. """ - package = _get_package(package) - reader = _get_resource_reader(package) + package = _common.get_package(package) + reader = _common.get_resource_reader(package) if reader is not None: - return reader.contents() - # Is the package a namespace package? By definition, namespace packages - # cannot have resources. - namespace = ( - package.__spec__.origin is None or - package.__spec__.origin == 'namespace' - ) - if namespace or not package.__spec__.has_location: - return () - return list(item.name for item in _common.from_package(package).iterdir()) + return _ensure_sequence(reader.contents()) + transversable = _common.from_package(package) + if transversable.is_dir(): + return list(item.name for item in transversable.iterdir()) + return [] + + +@singledispatch +def _ensure_sequence(iterable): + return list(iterable) + + +@_ensure_sequence.register(Sequence) +def _(iterable): + return iterable diff --git a/contrib/tools/python3/src/Lib/importlib/util.py b/contrib/tools/python3/src/Lib/importlib/util.py index 269a6fa930a..8623c89840c 100644 --- a/contrib/tools/python3/src/Lib/importlib/util.py +++ b/contrib/tools/python3/src/Lib/importlib/util.py @@ -1,5 +1,5 @@ """Utility code for constructing importers, etc.""" -from . import abc +from ._abc import Loader from ._bootstrap import module_from_spec from ._bootstrap import _resolve_name from ._bootstrap import spec_from_loader @@ -149,7 +149,8 @@ def set_package(fxn): """ @functools.wraps(fxn) def set_package_wrapper(*args, **kwargs): - warnings.warn('The import system now takes care of this automatically.', + 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: @@ -168,7 +169,8 @@ def set_loader(fxn): """ @functools.wraps(fxn) def set_loader_wrapper(self, *args, **kwargs): - warnings.warn('The import system now takes care of this automatically.', + 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: @@ -195,7 +197,8 @@ def module_for_loader(fxn): the second argument. """ - warnings.warn('The import system now takes care of this automatically.', + 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): @@ -232,7 +235,6 @@ class _LazyModule(types.ModuleType): # Figure out exactly what attributes were mutated between the creation # of the module and now. attrs_then = self.__spec__.loader_state['__dict__'] - original_type = self.__spec__.loader_state['__class__'] attrs_now = self.__dict__ attrs_updated = {} for key, value in attrs_now.items(): @@ -263,7 +265,7 @@ class _LazyModule(types.ModuleType): delattr(self, attr) -class LazyLoader(abc.Loader): +class LazyLoader(Loader): """A loader that creates a module which defers loading until attribute access.""" diff --git a/contrib/tools/python3/src/Lib/inspect.py b/contrib/tools/python3/src/Lib/inspect.py index 6f91435541b..c5881cc808d 100644 --- a/contrib/tools/python3/src/Lib/inspect.py +++ b/contrib/tools/python3/src/Lib/inspect.py @@ -24,6 +24,8 @@ Here are some of the useful functions provided by this module: stack(), trace() - get info about frames on the stack or in a traceback signature() - get a Signature object for the callable + + get_annotations() - safely compute an object's annotations """ # This module is in the public domain. No warranties. @@ -60,6 +62,122 @@ for k, v in dis.COMPILER_FLAG_NAMES.items(): # See Include/object.h TPFLAGS_IS_ABSTRACT = 1 << 20 + +def get_annotations(obj, *, globals=None, locals=None, eval_str=False): + """Compute the annotations dict for an object. + + obj may be a callable, class, or module. + Passing in an object of any other type raises TypeError. + + Returns a dict. get_annotations() returns a new dict every time + it's called; calling it twice on the same object will return two + different but equivalent dicts. + + This function handles several details for you: + + * If eval_str is true, values of type str will + be un-stringized using eval(). This is intended + for use with stringized annotations + ("from __future__ import annotations"). + * If obj doesn't have an annotations dict, returns an + empty dict. (Functions and methods always have an + annotations dict; classes, modules, and other types of + callables may not.) + * Ignores inherited annotations on classes. If a class + doesn't have its own annotations dict, returns an empty dict. + * All accesses to object members and dict values are done + using getattr() and dict.get() for safety. + * Always, always, always returns a freshly-created dict. + + eval_str controls whether or not values of type str are replaced + with the result of calling eval() on those values: + + * If eval_str is true, eval() is called on values of type str. + * If eval_str is false (the default), values of type str are unchanged. + + globals and locals are passed in to eval(); see the documentation + for eval() for more information. If either globals or locals is + None, this function may replace that value with a context-specific + default, contingent on type(obj): + + * If obj is a module, globals defaults to obj.__dict__. + * If obj is a class, globals defaults to + sys.modules[obj.__module__].__dict__ and locals + defaults to the obj class namespace. + * If obj is a callable, globals defaults to obj.__globals__, + although if obj is a wrapped function (using + functools.update_wrapper()) it is first unwrapped. + """ + if isinstance(obj, type): + # class + obj_dict = getattr(obj, '__dict__', None) + if obj_dict and hasattr(obj_dict, 'get'): + ann = obj_dict.get('__annotations__', None) + if isinstance(ann, types.GetSetDescriptorType): + ann = None + else: + ann = None + + obj_globals = None + module_name = getattr(obj, '__module__', None) + if module_name: + module = sys.modules.get(module_name, None) + if module: + obj_globals = getattr(module, '__dict__', None) + obj_locals = dict(vars(obj)) + unwrap = obj + elif isinstance(obj, types.ModuleType): + # module + ann = getattr(obj, '__annotations__', None) + obj_globals = getattr(obj, '__dict__') + obj_locals = None + unwrap = None + elif callable(obj): + # this includes types.Function, types.BuiltinFunctionType, + # types.BuiltinMethodType, functools.partial, functools.singledispatch, + # "class funclike" from Lib/test/test_inspect... on and on it goes. + ann = getattr(obj, '__annotations__', None) + obj_globals = getattr(obj, '__globals__', None) + obj_locals = None + unwrap = obj + else: + raise TypeError(f"{obj!r} is not a module, class, or callable.") + + if ann is None: + return {} + + if not isinstance(ann, dict): + raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None") + + if not ann: + return {} + + if not eval_str: + return dict(ann) + + if unwrap is not None: + while True: + if hasattr(unwrap, '__wrapped__'): + unwrap = unwrap.__wrapped__ + continue + if isinstance(unwrap, functools.partial): + unwrap = unwrap.func + continue + break + if hasattr(unwrap, "__globals__"): + obj_globals = unwrap.__globals__ + + if globals is None: + globals = obj_globals + if locals is None: + locals = obj_locals + + return_value = {key: + value if not isinstance(value, str) else eval(value, globals, locals) + for key, value in ann.items() } + return return_value + + # ----------------------------------------------------------- type-checking def ismodule(object): """Return true if the object is a module. @@ -407,7 +525,7 @@ def classify_class_attrs(cls): # attribute with the same name as a DynamicClassAttribute exists. for base in mro: for k, v in base.__dict__.items(): - if isinstance(v, types.DynamicClassAttribute): + if isinstance(v, types.DynamicClassAttribute) and v.fget is not None: names.append(k) result = [] processed = set() @@ -663,6 +781,8 @@ def getfile(object): module = sys.modules.get(object.__module__) if getattr(module, '__file__', None): return module.__file__ + if object.__module__ == '__main__': + raise OSError('source code not available') raise TypeError('{!r} is a built-in class'.format(object)) if ismethod(object): object = object.__func__ @@ -706,10 +826,13 @@ def getsourcefile(object): if os.path.exists(filename): return filename # only return a non-existent filename if the module has a PEP 302 loader - if getattr(getmodule(object, filename), '__loader__', None) is not None: + module = getmodule(object, filename) + if getattr(module, '__loader__', None) is not None: + return filename + elif getattr(getattr(module, "__spec__", None), "loader", None) is not None: return filename # or it is in the linecache - if filename in linecache.cache: + elif filename in linecache.cache: return filename def getabsfile(object, _filename=None): @@ -1162,7 +1285,8 @@ def getfullargspec(func): sig = _signature_from_callable(func, follow_wrapper_chains=False, skip_bound_arg=False, - sigcls=Signature) + sigcls=Signature, + eval_str=False) except Exception as ex: # Most of the times 'signature' will raise ValueError. # But, it can also raise AttributeError, and, maybe something @@ -1897,7 +2021,7 @@ def _signature_is_functionlike(obj): isinstance(name, str) and (defaults is None or isinstance(defaults, tuple)) and (kwdefaults is None or isinstance(kwdefaults, dict)) and - isinstance(annotations, dict)) + (isinstance(annotations, (dict)) or annotations is None) ) def _signature_get_bound_param(spec): @@ -2149,7 +2273,8 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True): return _signature_fromstr(cls, func, s, skip_bound_arg) -def _signature_from_function(cls, func, skip_bound_arg=True): +def _signature_from_function(cls, func, skip_bound_arg=True, + globals=None, locals=None, eval_str=False): """Private helper: constructs Signature for the given python function.""" is_duck_function = False @@ -2175,7 +2300,7 @@ def _signature_from_function(cls, func, skip_bound_arg=True): positional = arg_names[:pos_count] keyword_only_count = func_code.co_kwonlyargcount keyword_only = arg_names[pos_count:pos_count + keyword_only_count] - annotations = func.__annotations__ + annotations = get_annotations(func, globals=globals, locals=locals, eval_str=eval_str) defaults = func.__defaults__ kwdefaults = func.__kwdefaults__ @@ -2246,6 +2371,9 @@ def _signature_from_function(cls, func, skip_bound_arg=True): def _signature_from_callable(obj, *, follow_wrapper_chains=True, skip_bound_arg=True, + globals=None, + locals=None, + eval_str=False, sigcls): """Private helper function to get signature for arbitrary @@ -2255,7 +2383,10 @@ def _signature_from_callable(obj, *, _get_signature_of = functools.partial(_signature_from_callable, follow_wrapper_chains=follow_wrapper_chains, skip_bound_arg=skip_bound_arg, - sigcls=sigcls) + globals=globals, + locals=locals, + sigcls=sigcls, + eval_str=eval_str) if not callable(obj): raise TypeError('{!r} is not a callable object'.format(obj)) @@ -2323,7 +2454,8 @@ def _signature_from_callable(obj, *, # If it's a pure Python function, or an object that is duck type # of a Python function (Cython functions, for instance), then: return _signature_from_function(sigcls, obj, - skip_bound_arg=skip_bound_arg) + skip_bound_arg=skip_bound_arg, + globals=globals, locals=locals, eval_str=eval_str) if _signature_is_builtin(obj): return _signature_from_builtin(sigcls, obj, @@ -2857,10 +2989,12 @@ class Signature: return _signature_from_builtin(cls, func) @classmethod - def from_callable(cls, obj, *, follow_wrapped=True): + def from_callable(cls, obj, *, + follow_wrapped=True, globals=None, locals=None, eval_str=False): """Constructs Signature for the given callable object.""" return _signature_from_callable(obj, sigcls=cls, - follow_wrapper_chains=follow_wrapped) + follow_wrapper_chains=follow_wrapped, + globals=globals, locals=locals, eval_str=eval_str) @property def parameters(self): @@ -3108,9 +3242,10 @@ class Signature: return rendered -def signature(obj, *, follow_wrapped=True): +def signature(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False): """Get a signature object for the passed callable.""" - return Signature.from_callable(obj, follow_wrapped=follow_wrapped) + return Signature.from_callable(obj, follow_wrapped=follow_wrapped, + globals=globals, locals=locals, eval_str=eval_str) def _main(): diff --git a/contrib/tools/python3/src/Lib/io.py b/contrib/tools/python3/src/Lib/io.py index fbce6efc010..2a6140c3dd5 100644 --- a/contrib/tools/python3/src/Lib/io.py +++ b/contrib/tools/python3/src/Lib/io.py @@ -54,9 +54,24 @@ import abc from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, open, open_code, FileIO, BytesIO, StringIO, BufferedReader, BufferedWriter, BufferedRWPair, BufferedRandom, - IncrementalNewlineDecoder, TextIOWrapper) + 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(name) -OpenWrapper = _io.open # for compatibility with _pyio # Pretend this exception was created here. UnsupportedOperation.__module__ = "io" diff --git a/contrib/tools/python3/src/Lib/ipaddress.py b/contrib/tools/python3/src/Lib/ipaddress.py index 6cb92ed5520..4a6496a5da3 100644 --- a/contrib/tools/python3/src/Lib/ipaddress.py +++ b/contrib/tools/python3/src/Lib/ipaddress.py @@ -16,6 +16,7 @@ import functools IPV4LENGTH = 32 IPV6LENGTH = 128 + class AddressValueError(ValueError): """A Value Error related to the address.""" @@ -1214,7 +1215,7 @@ class _BaseV4: """ if not octet_str: raise ValueError("Empty octet not permitted") - # Whitelist the characters, since int() allows a lot of bizarre stuff. + # Reject non-ASCII digits. if not (octet_str.isascii() and octet_str.isdigit()): msg = "Only decimal digits permitted in %r" raise ValueError(msg % octet_str) @@ -1724,7 +1725,7 @@ class _BaseV6: [0..FFFF]. """ - # Whitelist the characters, since int() allows a lot of bizarre stuff. + # Reject non-ASCII digits. if not cls._HEX_DIGITS.issuperset(hextet_str): raise ValueError("Only hex digits permitted in %r" % hextet_str) # We do the length check second, since the invalid character error @@ -2002,9 +2003,13 @@ class IPv6Address(_BaseV6, _BaseAddress): Returns: A boolean, True if the address is reserved per - iana-ipv6-special-registry. + iana-ipv6-special-registry, or is ipv4_mapped and is + reserved in the iana-ipv4-special-registry. """ + ipv4_mapped = self.ipv4_mapped + if ipv4_mapped is not None: + return ipv4_mapped.is_private return any(self in net for net in self._constants._private_networks) @property diff --git a/contrib/tools/python3/src/Lib/keyword.py b/contrib/tools/python3/src/Lib/keyword.py index 59fcfb0f0d1..cc2b46b7229 100644 --- a/contrib/tools/python3/src/Lib/keyword.py +++ b/contrib/tools/python3/src/Lib/keyword.py @@ -6,7 +6,7 @@ To update the symbols in this file, 'cd' to the top directory of the python source tree and run: PYTHONPATH=Tools/peg_generator python3 -m pegen.keywordgen \ - Grammar/Grammar \ + Grammar/python.gram \ Grammar/Tokens \ Lib/keyword.py @@ -19,7 +19,6 @@ kwlist = [ 'False', 'None', 'True', - '__peg_parser__', 'and', 'as', 'assert', @@ -55,7 +54,9 @@ kwlist = [ ] softkwlist = [ - + '_', + 'case', + 'match' ] iskeyword = frozenset(kwlist).__contains__ diff --git a/contrib/tools/python3/src/Lib/lib2to3/pgen2/pgen.py b/contrib/tools/python3/src/Lib/lib2to3/pgen2/pgen.py index b0cbd16c4da..7abd5cef1c3 100644 --- a/contrib/tools/python3/src/Lib/lib2to3/pgen2/pgen.py +++ b/contrib/tools/python3/src/Lib/lib2to3/pgen2/pgen.py @@ -12,7 +12,7 @@ class ParserGenerator(object): def __init__(self, filename, stream=None): close_stream = None if stream is None: - stream = open(filename) + stream = open(filename, encoding="utf-8") close_stream = stream.close self.filename = filename self.stream = stream diff --git a/contrib/tools/python3/src/Lib/linecache.py b/contrib/tools/python3/src/Lib/linecache.py index 6adce80e8f8..c28c33f7fd8 100644 --- a/contrib/tools/python3/src/Lib/linecache.py +++ b/contrib/tools/python3/src/Lib/linecache.py @@ -177,9 +177,14 @@ def lazycache(filename, module_globals): if not filename or (filename.startswith('<') and filename.endswith('>')): return False # Try for a __loader__, if available - if module_globals and '__loader__' in module_globals: - name = module_globals.get('__name__') - loader = module_globals['__loader__'] + if module_globals and '__name__' in module_globals: + name = module_globals['__name__'] + if (loader := module_globals.get('__loader__')) is None: + if spec := module_globals.get('__spec__'): + try: + loader = spec.loader + except AttributeError: + pass get_source = getattr(loader, 'get_source', None) if name and get_source: diff --git a/contrib/tools/python3/src/Lib/locale.py b/contrib/tools/python3/src/Lib/locale.py index 1a4e9f694f3..6d4f5192992 100644 --- a/contrib/tools/python3/src/Lib/locale.py +++ b/contrib/tools/python3/src/Lib/locale.py @@ -185,8 +185,14 @@ def _format(percent, value, grouping=False, monetary=False, *additional): formatted = percent % ((value,) + additional) else: formatted = percent % value + if percent[-1] in 'eEfFgGdiu': + formatted = _localize(formatted, grouping, monetary) + return formatted + +# Transform formatted as locale number according to the locale settings +def _localize(formatted, grouping=False, monetary=False): # floats and decimal ints need special action! - if percent[-1] in 'eEfFgG': + if '.' in formatted: seps = 0 parts = formatted.split('.') if grouping: @@ -196,7 +202,7 @@ def _format(percent, value, grouping=False, monetary=False, *additional): formatted = decimal_point.join(parts) if seps: formatted = _strip_padding(formatted, seps) - elif percent[-1] in 'diu': + else: seps = 0 if grouping: formatted, seps = _group(formatted, monetary=monetary) @@ -267,7 +273,7 @@ def currency(val, symbol=True, grouping=False, international=False): raise ValueError("Currency formatting is not possible using " "the 'C' locale.") - s = _format('%%.%if' % digits, abs(val), grouping, monetary=True) + s = _localize(f'{abs(val):.{digits}f}', grouping, monetary=True) # '<' and '>' are markers if the sign must be inserted between symbol and value s = '<' + s + '>' @@ -323,6 +329,10 @@ def delocalize(string): string = string.replace(dd, '.') return string +def localize(string, grouping=False, monetary=False): + """Parses a string as locale number according to the locale settings.""" + return _localize(string, grouping, monetary) + def atof(string, func=float): "Parses a string as a float according to the locale settings." return func(delocalize(string)) @@ -619,53 +629,49 @@ def resetlocale(category=LC_ALL): """ _setlocale(category, _build_localename(getdefaultlocale())) -if sys.platform.startswith("win"): - # On Win32, this will return the ANSI code page - def getpreferredencoding(do_setlocale = True): - """Return the charset that the user is likely using.""" + +try: + from _locale import _get_locale_encoding +except ImportError: + def _get_locale_encoding(): + if hasattr(sys, 'getandroidapilevel'): + # On Android langinfo.h and CODESET are missing, and UTF-8 is + # always used in mbstowcs() and wcstombs(). + return 'UTF-8' if sys.flags.utf8_mode: return 'UTF-8' - import _bootlocale - return _bootlocale.getpreferredencoding(False) + encoding = getdefaultlocale()[1] + if encoding is None: + # LANG not set, default conservatively to ASCII + encoding = 'ascii' + return encoding + +try: + CODESET +except NameError: + def getpreferredencoding(do_setlocale=True): + """Return the charset that the user is likely using.""" + return _get_locale_encoding() else: # On Unix, if CODESET is available, use that. - try: - CODESET - except NameError: - if hasattr(sys, 'getandroidapilevel'): - # On Android langinfo.h and CODESET are missing, and UTF-8 is - # always used in mbstowcs() and wcstombs(). - def getpreferredencoding(do_setlocale = True): - return 'UTF-8' - else: - # Fall back to parsing environment variables :-( - def getpreferredencoding(do_setlocale = True): - """Return the charset that the user is likely using, - by looking at environment variables.""" - if sys.flags.utf8_mode: - return 'UTF-8' - res = getdefaultlocale()[1] - if res is None: - # LANG not set, default conservatively to ASCII - res = 'ascii' - return res - else: - def getpreferredencoding(do_setlocale = True): - """Return the charset that the user is likely using, - according to the system configuration.""" - if sys.flags.utf8_mode: - return 'UTF-8' - import _bootlocale - if do_setlocale: - oldloc = setlocale(LC_CTYPE) - try: - setlocale(LC_CTYPE, "") - except Error: - pass - result = _bootlocale.getpreferredencoding(False) - if do_setlocale: - setlocale(LC_CTYPE, oldloc) - return result + def getpreferredencoding(do_setlocale=True): + """Return the charset that the user is likely using, + according to the system configuration.""" + if sys.flags.utf8_mode: + return 'UTF-8' + + if not do_setlocale: + return _get_locale_encoding() + + old_loc = setlocale(LC_CTYPE) + try: + try: + setlocale(LC_CTYPE, "") + except Error: + pass + return _get_locale_encoding() + finally: + setlocale(LC_CTYPE, old_loc) ### Database diff --git a/contrib/tools/python3/src/Lib/logging/__init__.py b/contrib/tools/python3/src/Lib/logging/__init__.py index 1ab35a8c21a..19bd2bc20b2 100644 --- a/contrib/tools/python3/src/Lib/logging/__init__.py +++ b/contrib/tools/python3/src/Lib/logging/__init__.py @@ -198,7 +198,8 @@ def _checkLevel(level): raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: - raise TypeError("Level not an integer or a valid string: %r" % level) + raise TypeError("Level not an integer or a valid string: %r" + % (level,)) return rv #--------------------------------------------------------------------------- @@ -415,8 +416,9 @@ class PercentStyle(object): asctime_search = '%(asctime)' validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I) - def __init__(self, fmt): + def __init__(self, fmt, *, defaults=None): self._fmt = fmt or self.default_format + self._defaults = defaults def usesTime(self): return self._fmt.find(self.asctime_search) >= 0 @@ -427,7 +429,11 @@ class PercentStyle(object): raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0])) def _format(self, record): - return self._fmt % record.__dict__ + if defaults := self._defaults: + values = defaults | record.__dict__ + else: + values = record.__dict__ + return self._fmt % values def format(self, record): try: @@ -445,7 +451,11 @@ class StrFormatStyle(PercentStyle): field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$') def _format(self, record): - return self._fmt.format(**record.__dict__) + if defaults := self._defaults: + values = defaults | record.__dict__ + else: + values = record.__dict__ + return self._fmt.format(**values) def validate(self): """Validate the input format, ensure it is the correct string formatting style""" @@ -471,8 +481,8 @@ class StringTemplateStyle(PercentStyle): asctime_format = '${asctime}' asctime_search = '${asctime}' - def __init__(self, fmt): - self._fmt = fmt or self.default_format + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) self._tpl = Template(self._fmt) def usesTime(self): @@ -494,7 +504,11 @@ class StringTemplateStyle(PercentStyle): raise ValueError('invalid format: no fields') def _format(self, record): - return self._tpl.substitute(**record.__dict__) + if defaults := self._defaults: + values = defaults | record.__dict__ + else: + values = record.__dict__ + return self._tpl.substitute(**values) BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" @@ -550,7 +564,8 @@ class Formatter(object): converter = time.localtime - def __init__(self, fmt=None, datefmt=None, style='%', validate=True): + def __init__(self, fmt=None, datefmt=None, style='%', validate=True, *, + defaults=None): """ Initialize the formatter with specified format strings. @@ -569,7 +584,7 @@ class Formatter(object): if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) - self._style = _STYLES[style][0](fmt) + self._style = _STYLES[style][0](fmt, defaults=defaults) if validate: self._style.validate() @@ -863,6 +878,7 @@ class Handler(Filterer): self._name = None self.level = _checkLevel(level) self.formatter = None + self._closed = False # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() @@ -981,6 +997,7 @@ class Handler(Filterer): #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... + self._closed = True if self._name and self._name in _handlers: del _handlers[self._name] finally: @@ -1135,8 +1152,14 @@ class FileHandler(StreamHandler): self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding + if "b" not in mode: + self.encoding = io.text_encoding(encoding) self.errors = errors self.delay = delay + # bpo-26789: FileHandler keeps a reference to the builtin open() + # function to be able to open or reopen the file during Python + # finalization. + self._builtin_open = open if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. @@ -1163,6 +1186,8 @@ class FileHandler(StreamHandler): finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set + # Also see Issue #42378: we also rely on + # self._closed being set to True there StreamHandler.close(self) finally: self.release() @@ -1172,8 +1197,9 @@ class FileHandler(StreamHandler): Open the current base file with the (original) mode and encoding. Return the resulting stream. """ - return open(self.baseFilename, self.mode, encoding=self.encoding, - errors=self.errors) + open_func = self._builtin_open + return open_func(self.baseFilename, self.mode, + encoding=self.encoding, errors=self.errors) def emit(self, record): """ @@ -1181,10 +1207,15 @@ class FileHandler(StreamHandler): If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. + + If stream is not open, current mode is 'w' and `_closed=True`, record + will not be emitted (see Issue #42378). """ if self.stream is None: - self.stream = self._open() - StreamHandler.emit(self, record) + if self.mode != 'w' or not self._closed: + self.stream = self._open() + if self.stream: + StreamHandler.emit(self, record) def __repr__(self): level = getLevelName(self.level) @@ -1492,7 +1523,11 @@ class Logger(Filterer): if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) - fatal = critical + def fatal(self, msg, *args, **kwargs): + """ + Don't use this method, use critical() instead. + """ + self.critical(msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ @@ -1763,7 +1798,7 @@ class LoggerAdapter(object): information in logging output. """ - def __init__(self, logger, extra): + def __init__(self, logger, extra=None): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows @@ -1998,8 +2033,10 @@ def basicConfig(**kwargs): filename = kwargs.pop("filename", None) mode = kwargs.pop("filemode", 'a') if filename: - if 'b'in mode: + if 'b' in mode: errors = None + else: + encoding = io.text_encoding(encoding) h = FileHandler(filename, mode, encoding=encoding, errors=errors) else: @@ -2051,7 +2088,11 @@ def critical(msg, *args, **kwargs): basicConfig() root.critical(msg, *args, **kwargs) -fatal = critical +def fatal(msg, *args, **kwargs): + """ + Don't use this function, use critical() instead. + """ + critical(msg, *args, **kwargs) def error(msg, *args, **kwargs): """ diff --git a/contrib/tools/python3/src/Lib/logging/config.py b/contrib/tools/python3/src/Lib/logging/config.py index fd3aded7608..3bc63b78621 100644 --- a/contrib/tools/python3/src/Lib/logging/config.py +++ b/contrib/tools/python3/src/Lib/logging/config.py @@ -48,7 +48,7 @@ RESET_ERROR = errno.ECONNRESET # _listener holds the server object doing the listening _listener = None -def fileConfig(fname, defaults=None, disable_existing_loggers=True): +def fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=None): """ Read the logging configuration from a ConfigParser-format file. @@ -66,7 +66,8 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=True): if hasattr(fname, 'readline'): cp.read_file(fname) else: - cp.read(fname) + encoding = io.text_encoding(encoding) + cp.read(fname, encoding=encoding) formatters = _create_formatters(cp) diff --git a/contrib/tools/python3/src/Lib/logging/handlers.py b/contrib/tools/python3/src/Lib/logging/handlers.py index 572e370110a..61a39958c0a 100644 --- a/contrib/tools/python3/src/Lib/logging/handlers.py +++ b/contrib/tools/python3/src/Lib/logging/handlers.py @@ -23,7 +23,7 @@ Copyright (C) 2001-2021 Vinay Sajip. All Rights Reserved. To use, simply 'import logging.handlers' and log away! """ -import logging, socket, os, pickle, struct, time, re +import io, logging, socket, os, pickle, struct, time, re from stat import ST_DEV, ST_INO, ST_MTIME import queue import threading @@ -150,6 +150,8 @@ class RotatingFileHandler(BaseRotatingHandler): # on each run. if maxBytes > 0: mode = 'a' + if "b" not in mode: + encoding = io.text_encoding(encoding) BaseRotatingHandler.__init__(self, filename, mode, encoding=encoding, delay=delay, errors=errors) self.maxBytes = maxBytes @@ -208,6 +210,7 @@ class TimedRotatingFileHandler(BaseRotatingHandler): def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None, errors=None): + encoding = io.text_encoding(encoding) BaseRotatingHandler.__init__(self, filename, 'a', encoding=encoding, delay=delay, errors=errors) self.when = when.upper() @@ -467,6 +470,8 @@ class WatchedFileHandler(logging.FileHandler): """ def __init__(self, filename, mode='a', encoding=None, delay=False, errors=None): + if "b" not in mode: + encoding = io.text_encoding(encoding) logging.FileHandler.__init__(self, filename, mode=mode, encoding=encoding, delay=delay, errors=errors) @@ -1167,7 +1172,7 @@ class NTEventLogHandler(logging.Handler): class HTTPHandler(logging.Handler): """ - A class which sends records to a Web server, using either GET or + A class which sends records to a web server, using either GET or POST semantics. """ def __init__(self, host, url, method="GET", secure=False, credentials=None, @@ -1216,7 +1221,7 @@ class HTTPHandler(logging.Handler): """ Emit a record. - Send the record to the Web server as a percent-encoded dictionary + Send the record to the web server as a percent-encoded dictionary """ try: import urllib.parse diff --git a/contrib/tools/python3/src/Lib/lzma.py b/contrib/tools/python3/src/Lib/lzma.py index 0aa30fe87f8..800f52198fb 100644 --- a/contrib/tools/python3/src/Lib/lzma.py +++ b/contrib/tools/python3/src/Lib/lzma.py @@ -310,6 +310,7 @@ def open(filename, mode="rb", *, preset=preset, filters=filters) if "t" in mode: + encoding = io.text_encoding(encoding) return io.TextIOWrapper(binary_file, encoding, errors, newline) else: return binary_file diff --git a/contrib/tools/python3/src/Lib/mimetypes.py b/contrib/tools/python3/src/Lib/mimetypes.py index 58ace01b41a..b72ce083a69 100644 --- a/contrib/tools/python3/src/Lib/mimetypes.py +++ b/contrib/tools/python3/src/Lib/mimetypes.py @@ -27,6 +27,12 @@ import os import sys import posixpath import urllib.parse + +try: + from _winapi import _mimetypes_read_windows_registry +except ImportError: + _mimetypes_read_windows_registry = None + try: import winreg as _winreg except ImportError: @@ -235,10 +241,21 @@ class MimeTypes: types. """ - # Windows only - if not _winreg: + if not _mimetypes_read_windows_registry and not _winreg: return + add_type = self.add_type + if strict: + add_type = lambda type, ext: self.add_type(type, ext, True) + + # Accelerated function if it is available + if _mimetypes_read_windows_registry: + _mimetypes_read_windows_registry(add_type) + elif _winreg: + self._read_windows_registry(add_type) + + @classmethod + def _read_windows_registry(cls, add_type): def enum_types(mimedb): i = 0 while True: @@ -263,7 +280,7 @@ class MimeTypes: subkey, 'Content Type') if datatype != _winreg.REG_SZ: continue - self.add_type(mimetype, subkeyname, strict) + add_type(mimetype, subkeyname) except OSError: continue @@ -347,8 +364,8 @@ def init(files=None): if files is None or _db is None: db = MimeTypes() - if _winreg: - db.read_windows_registry() + # Quick return if not supported + db.read_windows_registry() if files is None: files = knownfiles @@ -446,6 +463,7 @@ def _default_mime_types(): '.dvi' : 'application/x-dvi', '.gtar' : 'application/x-gtar', '.hdf' : 'application/x-hdf', + '.h5' : 'application/x-hdf5', '.latex' : 'application/x-latex', '.mif' : 'application/x-mif', '.cdf' : 'application/x-netcdf', @@ -478,10 +496,19 @@ def _default_mime_types(): '.wsdl' : 'application/xml', '.xpdl' : 'application/xml', '.zip' : 'application/zip', + '.3gp' : 'audio/3gpp', + '.3gpp' : 'audio/3gpp', + '.3g2' : 'audio/3gpp2', + '.3gpp2' : 'audio/3gpp2', + '.aac' : 'audio/aac', + '.adts' : 'audio/aac', + '.loas' : 'audio/aac', + '.ass' : 'audio/aac', '.au' : 'audio/basic', '.snd' : 'audio/basic', '.mp3' : 'audio/mpeg', '.mp2' : 'audio/mpeg', + '.opus' : 'audio/opus', '.aif' : 'audio/x-aiff', '.aifc' : 'audio/x-aiff', '.aiff' : 'audio/x-aiff', @@ -493,6 +520,8 @@ def _default_mime_types(): '.jpg' : 'image/jpeg', '.jpe' : 'image/jpeg', '.jpeg' : 'image/jpeg', + '.heic' : 'image/heic', + '.heif' : 'image/heif', '.png' : 'image/png', '.svg' : 'image/svg+xml', '.tiff' : 'image/tiff', diff --git a/contrib/tools/python3/src/Lib/multiprocessing/managers.py b/contrib/tools/python3/src/Lib/multiprocessing/managers.py index dfa566c6fc3..b6b4cdd9ac1 100644 --- a/contrib/tools/python3/src/Lib/multiprocessing/managers.py +++ b/contrib/tools/python3/src/Lib/multiprocessing/managers.py @@ -193,11 +193,8 @@ class Server(object): t.daemon = True t.start() - def handle_request(self, c): - ''' - Handle a new connection - ''' - funcname = result = request = None + def _handle_request(self, c): + request = None try: connection.deliver_challenge(c, self.authkey) connection.answer_challenge(c, self.authkey) @@ -214,6 +211,7 @@ class Server(object): msg = ('#TRACEBACK', format_exc()) else: msg = ('#RETURN', result) + try: c.send(msg) except Exception as e: @@ -225,7 +223,17 @@ class Server(object): util.info(' ... request was %r', request) util.info(' ... exception was %r', e) - c.close() + def handle_request(self, conn): + ''' + Handle a new connection + ''' + try: + self._handle_request(conn) + except SystemExit: + # Server.serve_client() calls sys.exit(0) on EOF + pass + finally: + conn.close() def serve_client(self, conn): ''' diff --git a/contrib/tools/python3/src/Lib/multiprocessing/resource_tracker.py b/contrib/tools/python3/src/Lib/multiprocessing/resource_tracker.py index c9bfa9b82b6..cc42dbdda05 100644 --- a/contrib/tools/python3/src/Lib/multiprocessing/resource_tracker.py +++ b/contrib/tools/python3/src/Lib/multiprocessing/resource_tracker.py @@ -37,8 +37,16 @@ if os.name == 'posix': import _multiprocessing import _posixshmem + # Use sem_unlink() to clean up named semaphores. + # + # sem_unlink() may be missing if the Python build process detected the + # absence of POSIX named semaphores. In that case, no named semaphores were + # ever opened, so no cleanup would be necessary. + if hasattr(_multiprocessing, 'sem_unlink'): + _CLEANUP_FUNCS.update({ + 'semaphore': _multiprocessing.sem_unlink, + }) _CLEANUP_FUNCS.update({ - 'semaphore': _multiprocessing.sem_unlink, 'shared_memory': _posixshmem.shm_unlink, }) diff --git a/contrib/tools/python3/src/Lib/multiprocessing/util.py b/contrib/tools/python3/src/Lib/multiprocessing/util.py index e94466be8ed..230ffd11e64 100644 --- a/contrib/tools/python3/src/Lib/multiprocessing/util.py +++ b/contrib/tools/python3/src/Lib/multiprocessing/util.py @@ -422,7 +422,7 @@ def _close_stdin(): try: fd = os.open(os.devnull, os.O_RDONLY) try: - sys.stdin = open(fd, closefd=False) + sys.stdin = open(fd, encoding="utf-8", closefd=False) except: os.close(fd) raise diff --git a/contrib/tools/python3/src/Lib/netrc.py b/contrib/tools/python3/src/Lib/netrc.py index f0ae48cfed9..734d94c8a62 100644 --- a/contrib/tools/python3/src/Lib/netrc.py +++ b/contrib/tools/python3/src/Lib/netrc.py @@ -26,8 +26,12 @@ class netrc: file = os.path.join(os.path.expanduser("~"), ".netrc") self.hosts = {} self.macros = {} - with open(file) as fp: - self._parse(file, fp, default_netrc) + try: + with open(file, encoding="utf-8") as fp: + self._parse(file, fp, default_netrc) + except UnicodeDecodeError: + with open(file, encoding="locale") as fp: + self._parse(file, fp, default_netrc) def _parse(self, file, fp, default_netrc): lexer = shlex.shlex(fp) diff --git a/contrib/tools/python3/src/Lib/ntpath.py b/contrib/tools/python3/src/Lib/ntpath.py index 6f771773a7d..527c7ae1938 100644 --- a/contrib/tools/python3/src/Lib/ntpath.py +++ b/contrib/tools/python3/src/Lib/ntpath.py @@ -312,12 +312,25 @@ def expanduser(path): drive = '' userhome = join(drive, os.environ['HOMEPATH']) + if i != 1: #~user + target_user = path[1:i] + if isinstance(target_user, bytes): + target_user = os.fsdecode(target_user) + current_user = os.environ.get('USERNAME') + + if target_user != current_user: + # Try to guess user home directory. By default all user + # profile directories are located in the same place and are + # named by corresponding usernames. If userhome isn't a + # normal profile directory, this guess is likely wrong, + # so we bail out. + if current_user != basename(userhome): + return path + userhome = join(dirname(userhome), target_user) + if isinstance(path, bytes): userhome = os.fsencode(userhome) - if i != 1: #~user - userhome = join(dirname(userhome), path[1:i]) - return userhome + path[i:] @@ -622,7 +635,7 @@ else: tail = join(name, tail) if tail else name return tail - def realpath(path): + def realpath(path, *, strict=False): path = normpath(path) if isinstance(path, bytes): prefix = b'\\\\?\\' @@ -647,6 +660,8 @@ else: path = _getfinalpathname(path) initial_winerror = 0 except OSError as ex: + if strict: + raise initial_winerror = ex.winerror path = _getfinalpathname_nonstrict(path) # The path returned by _getfinalpathname will always start with \\?\ - diff --git a/contrib/tools/python3/src/Lib/opcode.py b/contrib/tools/python3/src/Lib/opcode.py index ac1aa535f66..37e88e92df7 100644 --- a/contrib/tools/python3/src/Lib/opcode.py +++ b/contrib/tools/python3/src/Lib/opcode.py @@ -67,7 +67,6 @@ def_op('UNARY_NEGATIVE', 11) def_op('UNARY_NOT', 12) def_op('UNARY_INVERT', 15) - def_op('BINARY_MATRIX_MULTIPLY', 16) def_op('INPLACE_MATRIX_MULTIPLY', 17) @@ -82,8 +81,12 @@ def_op('BINARY_FLOOR_DIVIDE', 26) def_op('BINARY_TRUE_DIVIDE', 27) def_op('INPLACE_FLOOR_DIVIDE', 28) def_op('INPLACE_TRUE_DIVIDE', 29) +def_op('GET_LEN', 30) +def_op('MATCH_MAPPING', 31) +def_op('MATCH_SEQUENCE', 32) +def_op('MATCH_KEYS', 33) +def_op('COPY_DICT_WITHOUT_KEYS', 34) -def_op('RERAISE', 48) def_op('WITH_EXCEPT_START', 49) def_op('GET_AITER', 50) def_op('GET_ANEXT', 51) @@ -105,7 +108,6 @@ def_op('BINARY_OR', 66) def_op('INPLACE_POWER', 67) 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('YIELD_FROM', 72) @@ -137,6 +139,7 @@ name_op('STORE_ATTR', 95) # Index in name list name_op('DELETE_ATTR', 96) # "" name_op('STORE_GLOBAL', 97) # "" name_op('DELETE_GLOBAL', 98) # "" +def_op('ROT_N', 99) def_op('LOAD_CONST', 100) # Index in const list hasconst.append(100) name_op('LOAD_NAME', 101) # Index in name list @@ -149,18 +152,16 @@ def_op('COMPARE_OP', 107) # Comparison operator 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 bytes to skip jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code jabs_op('JUMP_IF_TRUE_OR_POP', 112) # "" jabs_op('JUMP_ABSOLUTE', 113) # "" jabs_op('POP_JUMP_IF_FALSE', 114) # "" jabs_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) jabs_op('JUMP_IF_NOT_EXC_MATCH', 121) jrel_op('SETUP_FINALLY', 122) # Distance to target address @@ -172,10 +173,12 @@ haslocal.append(125) def_op('DELETE_FAST', 126) # Local variable number haslocal.append(126) +def_op('GEN_START', 129) # Kind of generator/coroutine def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) def_op('CALL_FUNCTION', 131) # #args def_op('MAKE_FUNCTION', 132) # Flags def_op('BUILD_SLICE', 133) # Number of items + def_op('LOAD_CLOSURE', 135) hasfree.append(135) def_op('LOAD_DEREF', 136) @@ -187,28 +190,24 @@ hasfree.append(138) def_op('CALL_FUNCTION_KW', 141) # #args + #kwargs def_op('CALL_FUNCTION_EX', 142) # Flags - jrel_op('SETUP_WITH', 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('EXTENDED_ARG', 144) -EXTENDED_ARG = 144 +def_op('MATCH_CLASS', 152) jrel_op('SETUP_ASYNC_WITH', 154) - def_op('FORMAT_VALUE', 155) def_op('BUILD_CONST_KEY_MAP', 156) def_op('BUILD_STRING', 157) name_op('LOAD_METHOD', 160) def_op('CALL_METHOD', 161) - def_op('LIST_EXTEND', 162) def_op('SET_UPDATE', 163) def_op('DICT_MERGE', 164) diff --git a/contrib/tools/python3/src/Lib/os.py b/contrib/tools/python3/src/Lib/os.py index b794159f86c..d26cfc99939 100644 --- a/contrib/tools/python3/src/Lib/os.py +++ b/contrib/tools/python3/src/Lib/os.py @@ -36,7 +36,7 @@ _names = sys.builtin_module_names __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR", "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen", - "popen", "extsep"] + "extsep"] def _exists(name): return name in globals() @@ -969,58 +969,64 @@ otherwise return -SIG, where SIG is the signal that killed it. """ __all__.extend(["spawnlp", "spawnlpe"]) - -# Supply os.popen() -def popen(cmd, mode="r", buffering=-1): - if not isinstance(cmd, str): - raise TypeError("invalid cmd type (%s, expected string)" % type(cmd)) - if mode not in ("r", "w"): - raise ValueError("invalid mode %r" % mode) - if buffering == 0 or buffering is None: - raise ValueError("popen() does not support unbuffered streams") - import subprocess, io - if mode == "r": - proc = subprocess.Popen(cmd, - shell=True, - stdout=subprocess.PIPE, - bufsize=buffering) - return _wrap_close(io.TextIOWrapper(proc.stdout), proc) - else: - proc = subprocess.Popen(cmd, - shell=True, - stdin=subprocess.PIPE, - bufsize=buffering) - return _wrap_close(io.TextIOWrapper(proc.stdin), proc) - -# Helper for popen() -- a proxy for a file whose close waits for the process -class _wrap_close: - def __init__(self, stream, proc): - self._stream = stream - self._proc = proc - def close(self): - self._stream.close() - returncode = self._proc.wait() - if returncode == 0: - return None - if name == 'nt': - return returncode +# VxWorks has no user space shell provided. As a result, running +# command in a shell can't be supported. +if sys.platform != 'vxworks': + # Supply os.popen() + def popen(cmd, mode="r", buffering=-1): + if not isinstance(cmd, str): + raise TypeError("invalid cmd type (%s, expected string)" % type(cmd)) + if mode not in ("r", "w"): + raise ValueError("invalid mode %r" % mode) + if buffering == 0 or buffering is None: + raise ValueError("popen() does not support unbuffered streams") + import subprocess, io + if mode == "r": + proc = subprocess.Popen(cmd, + shell=True, text=True, + stdout=subprocess.PIPE, + bufsize=buffering) + return _wrap_close(proc.stdout, proc) else: - return returncode << 8 # Shift left to match old behavior - def __enter__(self): - return self - def __exit__(self, *args): - self.close() - def __getattr__(self, name): - return getattr(self._stream, name) - def __iter__(self): - return iter(self._stream) + proc = subprocess.Popen(cmd, + shell=True, text=True, + stdin=subprocess.PIPE, + bufsize=buffering) + return _wrap_close(proc.stdin, proc) + + # Helper for popen() -- a proxy for a file whose close waits for the process + class _wrap_close: + def __init__(self, stream, proc): + self._stream = stream + self._proc = proc + def close(self): + self._stream.close() + returncode = self._proc.wait() + if returncode == 0: + return None + if name == 'nt': + return returncode + else: + return returncode << 8 # Shift left to match old behavior + def __enter__(self): + return self + def __exit__(self, *args): + self.close() + def __getattr__(self, name): + return getattr(self._stream, name) + def __iter__(self): + return iter(self._stream) + + __all__.append("popen") # Supply os.fdopen() -def fdopen(fd, *args, **kwargs): +def fdopen(fd, mode="r", buffering=-1, encoding=None, *args, **kwargs): if not isinstance(fd, int): raise TypeError("invalid fd type (%s, expected integer)" % type(fd)) import io - return io.open(fd, *args, **kwargs) + if "b" not in mode: + encoding = io.text_encoding(encoding) + return io.open(fd, mode, buffering, encoding, *args, **kwargs) # For testing purposes, make sure the function is available when the C diff --git a/contrib/tools/python3/src/Lib/pathlib.py b/contrib/tools/python3/src/Lib/pathlib.py index 7aeda14a141..621fba0e75c 100644 --- a/contrib/tools/python3/src/Lib/pathlib.py +++ b/contrib/tools/python3/src/Lib/pathlib.py @@ -6,6 +6,7 @@ import os import posixpath import re import sys +import warnings from _collections_abc import Sequence from errno import EINVAL, ENOENT, ENOTDIR, EBADF, ELOOP from operator import attrgetter @@ -13,18 +14,6 @@ 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 -supports_symlinks = True -if os.name == 'nt': - import nt - if sys.getwindowsversion()[:2] >= (6, 0): - from nt import _getfinalpathname - else: - supports_symlinks = False - _getfinalpathname = None -else: - nt = None - - __all__ = [ "PurePath", "PurePosixPath", "PureWindowsPath", "Path", "PosixPath", "WindowsPath", @@ -34,14 +23,17 @@ __all__ = [ # Internals # +_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 + # EBADF - guard against macOS `stat` throwing EBADF _IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF, ELOOP) _IGNORED_WINERRORS = ( - 21, # ERROR_NOT_READY - drive exists but is not accessible - 123, # ERROR_INVALID_NAME - fix for bpo-35306 - 1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself -) + _WINERROR_NOT_READY, + _WINERROR_INVALID_NAME, + _WINERROR_CANT_RESOLVE_FILENAME) def _ignore_error(exception): return (getattr(exception, 'errno', None) in _IGNORED_ERROS or @@ -200,30 +192,6 @@ class _WindowsFlavour(_Flavour): def compile_pattern(self, pattern): return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch - def resolve(self, path, strict=False): - s = str(path) - if not s: - return os.getcwd() - previous_s = None - if _getfinalpathname is not None: - if strict: - return self._ext_to_normal(_getfinalpathname(s)) - else: - tail_parts = [] # End of the path after the first one not found - while True: - try: - s = self._ext_to_normal(_getfinalpathname(s)) - except FileNotFoundError: - previous_s = s - s, tail = os.path.split(s) - tail_parts.append(tail) - if previous_s == s: - return path - else: - return os.path.join(s, *reversed(tail_parts)) - # Means fallback on absolute - return None - def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix): prefix = '' if s.startswith(ext_prefix): @@ -234,10 +202,6 @@ class _WindowsFlavour(_Flavour): s = '\\' + s[3:] return prefix, s - def _ext_to_normal(self, s): - # Turn back an extended path into a normal DOS-like path - return self._split_extended_path(s)[1] - 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 @@ -263,34 +227,6 @@ class _WindowsFlavour(_Flavour): # It's a path on a network drive => 'file://host/share/a/b' return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8')) - def gethomedir(self, username): - if 'USERPROFILE' in os.environ: - userhome = os.environ['USERPROFILE'] - elif 'HOMEPATH' in os.environ: - try: - drv = os.environ['HOMEDRIVE'] - except KeyError: - drv = '' - userhome = drv + os.environ['HOMEPATH'] - else: - raise RuntimeError("Can't determine home directory") - - if username: - # Try to guess user home directory. By default all users - # directories are located in the same place and are named by - # corresponding usernames. If current user home directory points - # to nonstandard place, this guess is likely wrong. - if os.environ['USERNAME'] != username: - drv, root, parts = self.parse_parts((userhome,)) - if parts[-1] != os.environ['USERNAME']: - raise RuntimeError("Can't determine home directory " - "for %r" % username) - parts[-1] = username - if drv or root: - userhome = drv + root + self.join(parts[1:]) - else: - userhome = self.join(parts) - return userhome class _PosixFlavour(_Flavour): sep = '/' @@ -324,54 +260,6 @@ class _PosixFlavour(_Flavour): def compile_pattern(self, pattern): return re.compile(fnmatch.translate(pattern)).fullmatch - def resolve(self, path, strict=False): - sep = self.sep - accessor = path._accessor - seen = {} - def _resolve(path, rest): - if rest.startswith(sep): - path = '' - - for name in rest.split(sep): - if not name or name == '.': - # current dir - continue - if name == '..': - # parent dir - path, _, _ = path.rpartition(sep) - continue - if path.endswith(sep): - newpath = path + name - else: - newpath = path + sep + name - if newpath in seen: - # Already seen this path - path = seen[newpath] - if path is not None: - # use cached value - continue - # The symlink is not resolved, so we must have a symlink loop. - raise RuntimeError("Symlink loop from %r" % newpath) - # Resolve the symbolic link - try: - target = accessor.readlink(newpath) - except OSError as e: - if e.errno != EINVAL and strict: - raise - # Not a symlink, or non-strict mode. We just leave the path - # untouched. - path = newpath - else: - seen[newpath] = None # not resolved symlink - path = _resolve(path, target) - seen[newpath] = path # resolved symlink - - return path - # NOTE: according to POSIX, getcwd() cannot contain path components - # which are symlinks. - base = '' if path.is_absolute() else os.getcwd() - return _resolve(base, str(path)) or sep - def is_reserved(self, parts): return False @@ -381,21 +269,6 @@ class _PosixFlavour(_Flavour): bpath = bytes(path) return 'file://' + urlquote_from_bytes(bpath) - def gethomedir(self, username): - if not username: - try: - return os.environ['HOME'] - except KeyError: - import pwd - return pwd.getpwuid(os.getuid()).pw_dir - else: - import pwd - try: - return pwd.getpwnam(username).pw_dir - except KeyError: - raise RuntimeError("Can't determine home directory " - "for %r" % username) - _windows_flavour = _WindowsFlavour() _posix_flavour = _PosixFlavour() @@ -410,9 +283,7 @@ class _NormalAccessor(_Accessor): stat = os.stat - lstat = os.lstat - - open = os.open + open = io.open listdir = os.listdir @@ -420,21 +291,14 @@ class _NormalAccessor(_Accessor): chmod = os.chmod - if hasattr(os, "lchmod"): - lchmod = os.lchmod - else: - def lchmod(self, pathobj, mode): - raise NotImplementedError("lchmod() not available on this system") - mkdir = os.mkdir unlink = os.unlink if hasattr(os, "link"): - link_to = os.link + link = os.link else: - @staticmethod - def link_to(self, target): + def link(self, src, dst): raise NotImplementedError("os.link() not available on this system") rmdir = os.rmdir @@ -443,23 +307,35 @@ class _NormalAccessor(_Accessor): replace = os.replace - if nt: - if supports_symlinks: - symlink = os.symlink - else: - def symlink(a, b, target_is_directory): - raise NotImplementedError("symlink() not available on this system") + if hasattr(os, "symlink"): + symlink = os.symlink else: - # Under POSIX, os.symlink() takes two args - @staticmethod - def symlink(a, b, target_is_directory): - return os.symlink(a, b) + def symlink(self, src, dst, target_is_directory=False): + raise NotImplementedError("os.symlink() not available on this system") - utime = os.utime + def touch(self, path, mode=0o666, exist_ok=True): + if exist_ok: + # First try to bump modification time + # Implementation note: GNU touch uses the UTIME_NOW option of + # the utimensat() / futimens() functions. + try: + os.utime(path, None) + except OSError: + # Avoid exception chaining + pass + else: + return + flags = os.O_CREAT | os.O_WRONLY + if not exist_ok: + flags |= os.O_EXCL + fd = os.open(path, flags, mode) + os.close(fd) - # Helper for resolve() - def readlink(self, path): - return os.readlink(path) + if hasattr(os, "readlink"): + readlink = os.readlink + else: + def readlink(self, path): + raise NotImplementedError("os.readlink() not available on this system") def owner(self, path): try: @@ -475,6 +351,12 @@ class _NormalAccessor(_Accessor): except ImportError: raise NotImplementedError("Path.group() is unsupported on this system") + getcwd = os.getcwd + + expanduser = staticmethod(os.path.expanduser) + + realpath = staticmethod(os.path.realpath) + _normal_accessor = _NormalAccessor() @@ -641,7 +523,10 @@ class _PathParents(Sequence): return len(self._parts) def __getitem__(self, idx): - if idx < 0 or idx >= len(self): + if isinstance(idx, slice): + return tuple(self[i] for i in range(*idx.indices(len(self)))) + + if idx >= len(self) or idx < -len(self): raise IndexError(idx) return self._pathcls._from_parsed_parts(self._drv, self._root, self._parts[:-idx - 1]) @@ -700,7 +585,7 @@ class PurePath(object): return cls._flavour.parse_parts(parts) @classmethod - def _from_parts(cls, args, init=True): + 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) @@ -708,18 +593,14 @@ class PurePath(object): self._drv = drv self._root = root self._parts = parts - if init: - self._init() return self @classmethod - def _from_parsed_parts(cls, drv, root, parts, init=True): + def _from_parsed_parts(cls, drv, root, parts): self = object.__new__(cls) self._drv = drv self._root = root self._parts = parts - if init: - self._init() return self @classmethod @@ -729,10 +610,6 @@ class PurePath(object): else: return cls._flavour.join(parts) - def _init(self): - # Overridden in concrete Path - pass - def _make_child(self, args): drv, root, parts = self._parse_args(args) drv, root, parts = self._flavour.join_parsed_parts( @@ -1072,29 +949,18 @@ class Path(PurePath): object. You can also instantiate a PosixPath or WindowsPath directly, but cannot instantiate a WindowsPath on a POSIX system or vice versa. """ - __slots__ = ( - '_accessor', - ) + _accessor = _normal_accessor + __slots__ = () def __new__(cls, *args, **kwargs): if cls is Path: cls = WindowsPath if os.name == 'nt' else PosixPath - self = cls._from_parts(args, init=False) + self = cls._from_parts(args) if not self._flavour.is_supported: raise NotImplementedError("cannot instantiate %r on your system" % (cls.__name__,)) - self._init() return self - def _init(self, - # Private non-constructor arguments - template=None, - ): - if template is not None: - self._accessor = template._accessor - else: - self._accessor = _normal_accessor - def _make_child_relpath(self, part): # This is an optimization used for dir walking. `part` must be # a single part relative to this path. @@ -1115,17 +981,6 @@ class Path(PurePath): # removed in the future. pass - def _opener(self, name, flags, mode=0o666): - # A stub for the opener argument to built-in open() - return self._accessor.open(self, flags, mode) - - def _raw_open(self, flags, mode=0o777): - """ - Open the file pointed by this path and return a file descriptor, - as os.open() does. - """ - return self._accessor.open(self, flags, mode) - # Public API @classmethod @@ -1133,14 +988,14 @@ class Path(PurePath): """Return a new path pointing to the current working directory (as returned by os.getcwd()). """ - return cls(os.getcwd()) + return cls(cls._accessor.getcwd()) @classmethod def home(cls): """Return a new path pointing to the user's home directory (as returned by os.path.expanduser('~')). """ - return cls(cls()._flavour.gethomedir(None)) + return cls("~").expanduser() def samefile(self, other_path): """Return whether other_path is the same or not as this file @@ -1202,9 +1057,7 @@ class Path(PurePath): return self # FIXME this must defer to the specific flavour (and, under Windows, # use nt._getfullpathname()) - obj = self._from_parts([os.getcwd()] + self._parts, init=False) - obj._init(template=self) - return obj + return self._from_parts([self._accessor.getcwd()] + self._parts) def resolve(self, strict=False): """ @@ -1212,24 +1065,34 @@ class Path(PurePath): normalizing it (for example turning slashes into backslashes under Windows). """ - s = self._flavour.resolve(self, strict=strict) - if s is None: - # No symlink resolution => for consistency, raise an error if - # the path doesn't exist or is forbidden - self.stat() - s = str(self.absolute()) - # Now we have no symlinks in the path, it's safe to normalize it. - normed = self._flavour.pathmod.normpath(s) - obj = self._from_parts((normed,), init=False) - obj._init(template=self) - return obj - def stat(self): + 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._accessor.realpath(self, strict=strict) + except OSError as e: + check_eloop(e) + raise + p = self._from_parts((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 stat(self, *, follow_symlinks=True): """ Return the result of the stat() system call on this path, like os.stat() does. """ - return self._accessor.stat(self) + return self._accessor.stat(self, follow_symlinks=follow_symlinks) def owner(self): """ @@ -1249,8 +1112,10 @@ class Path(PurePath): Open the file pointed by this path and return a file object, as the built-in open() function does. """ - return io.open(self, mode, buffering, encoding, errors, newline, - opener=self._opener) + if "b" not in mode: + encoding = io.text_encoding(encoding) + return self._accessor.open(self, mode, buffering, encoding, errors, + newline) def read_bytes(self): """ @@ -1263,6 +1128,7 @@ class Path(PurePath): """ Open the file in text mode, read it, and close the file. """ + encoding = io.text_encoding(encoding) with self.open(mode='r', encoding=encoding, errors=errors) as f: return f.read() @@ -1275,14 +1141,15 @@ class Path(PurePath): with self.open(mode='wb') as f: return f.write(view) - def write_text(self, data, encoding=None, errors=None): + def write_text(self, data, encoding=None, errors=None, newline=None): """ Open the file in text mode, write to it, and close the file. """ if not isinstance(data, str): raise TypeError('data must be str, not %s' % data.__class__.__name__) - with self.open(mode='w', encoding=encoding, errors=errors) as f: + encoding = io.text_encoding(encoding) + with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f: return f.write(data) def readlink(self): @@ -1290,30 +1157,13 @@ class Path(PurePath): Return the path to which the symbolic link points. """ path = self._accessor.readlink(self) - obj = self._from_parts((path,), init=False) - obj._init(template=self) - return obj + return self._from_parts((path,)) def touch(self, mode=0o666, exist_ok=True): """ Create this file with the given access mode, if it doesn't exist. """ - if exist_ok: - # First try to bump modification time - # Implementation note: GNU touch uses the UTIME_NOW option of - # the utimensat() / futimens() functions. - try: - self._accessor.utime(self, None) - except OSError: - # Avoid exception chaining - pass - else: - return - flags = os.O_CREAT | os.O_WRONLY - if not exist_ok: - flags |= os.O_EXCL - fd = self._raw_open(flags, mode) - os.close(fd) + self._accessor.touch(self, mode, exist_ok) def mkdir(self, mode=0o777, parents=False, exist_ok=False): """ @@ -1332,18 +1182,18 @@ class Path(PurePath): if not exist_ok or not self.is_dir(): raise - def chmod(self, mode): + def chmod(self, mode, *, follow_symlinks=True): """ Change the permissions of the path, like os.chmod(). """ - self._accessor.chmod(self, mode) + self._accessor.chmod(self, mode, follow_symlinks=follow_symlinks) def lchmod(self, mode): """ Like chmod(), except if the path points to a symlink, the symlink's permissions are changed, rather than its target's. """ - self._accessor.lchmod(self, mode) + self.chmod(mode, follow_symlinks=False) def unlink(self, missing_ok=False): """ @@ -1367,7 +1217,7 @@ class Path(PurePath): Like stat(), except if the path points to a symlink, the symlink's status information is returned, rather than its target's. """ - return self._accessor.lstat(self) + return self.stat(follow_symlinks=False) def rename(self, target): """ @@ -1402,6 +1252,14 @@ class Path(PurePath): """ self._accessor.symlink(target, self, target_is_directory) + def hardlink_to(self, target): + """ + Make this path a hard link pointing to the same file as *target*. + + Note the order of arguments (self, target) is the reverse of os.link's. + """ + self._accessor.link(target, self) + def link_to(self, target): """ Make the target path a hard link pointing to this path. @@ -1411,8 +1269,14 @@ class Path(PurePath): 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. """ - self._accessor.link_to(self, target) + 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._accessor.link(self, target) # Convenience functions for querying the stat results @@ -1569,7 +1433,9 @@ class Path(PurePath): """ if (not (self._drv or self._root) and self._parts and self._parts[0][:1] == '~'): - homedir = self._flavour.gethomedir(self._parts[0][1:]) + homedir = self._accessor.expanduser(self._parts[0]) + if homedir[:1] == "~": + raise RuntimeError("Could not determine home directory.") return self._from_parts([homedir] + self._parts[1:]) return self diff --git a/contrib/tools/python3/src/Lib/pickle.py b/contrib/tools/python3/src/Lib/pickle.py index 3d2c75a8538..e7f30f22610 100644 --- a/contrib/tools/python3/src/Lib/pickle.py +++ b/contrib/tools/python3/src/Lib/pickle.py @@ -818,6 +818,7 @@ class _Pickler: self._write_large_bytes(BYTEARRAY8 + pack("{_DOTTED_WORDS})(?P:(?P{_DOTTED_WORDS})?)?$', re.U) -del _DOTTED_WORDS +_NAME_PATTERN = None def resolve_name(name): """ @@ -675,6 +673,15 @@ def resolve_name(name): AttributeError - if a failure occurred when traversing the object hierarchy within the imported package to get to the desired object. """ + global _NAME_PATTERN + if _NAME_PATTERN is None: + # Lazy import to speedup Python startup time + import re + dotted_words = r'(?!\d)(\w+)(\.(?!\d)(\w+))*' + _NAME_PATTERN = re.compile(f'^(?P{dotted_words})' + f'(?P:(?P{dotted_words})?)?$', + re.UNICODE) + m = _NAME_PATTERN.match(name) if not m: raise ValueError(f'invalid format: {name!r}') diff --git a/contrib/tools/python3/src/Lib/platform.py b/contrib/tools/python3/src/Lib/platform.py index d6412e169b4..e32f9c11cdb 100755 --- a/contrib/tools/python3/src/Lib/platform.py +++ b/contrib/tools/python3/src/Lib/platform.py @@ -174,7 +174,7 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): The file is read and scanned in chunks of chunksize bytes. """ - if executable is None: + if not executable: try: ver = os.confstr('CS_GNU_LIBC_VERSION') # parse 'glibc 2.28' as ('glibc', '2.28') @@ -526,16 +526,6 @@ def system_alias(system, release, version): # XXX Whatever the new SunOS marketing name is... system = 'Solaris' - elif system == 'IRIX64': - # IRIX reports IRIX64 on platforms with 64-bit support; yet it - # is really a version and not a different platform, since 32-bit - # apps are also supported.. - system = 'IRIX' - if version: - version = version + ' (64bit)' - else: - version = '64bit' - elif system in ('win32', 'win16'): # In case one of the other tricks system = 'Windows' @@ -700,9 +690,6 @@ def architecture(executable=sys.executable, bits='', linkage=''): # Bits if '32-bit' in fileout: bits = '32bit' - elif 'N32' in fileout: - # On Irix only - bits = 'n32bit' elif '64-bit' in fileout: bits = '64bit' @@ -1258,6 +1245,63 @@ def platform(aliased=0, terse=0): _platform_cache[(aliased, terse)] = platform return platform +### 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[a-zA-Z0-9_]+)=(?P[\"\']?)(?P.*)(?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 + + +def _parse_os_release(lines): + # These fields are mandatory fields with well-known defaults + # in practice all Linux distributions override NAME, ID, and PRETTY_NAME. + info = { + "NAME": "Linux", + "ID": "linux", + "PRETTY_NAME": "Linux", + } + + for line in lines: + mo = _os_release_line.match(line) + if mo is not None: + info[mo.group('name')] = _os_release_unescape.sub( + r"\1", mo.group('value') + ) + + return info + + +def freedesktop_os_release(): + """Return operation system identification from freedesktop.org os-release + """ + global _os_release_cache + + if _os_release_cache is None: + errno = None + for candidate in _os_release_candidates: + try: + with open(candidate, encoding="utf-8") as f: + _os_release_cache = _parse_os_release(f) + break + except OSError as e: + errno = e.errno + else: + raise OSError( + errno, + f"Unable to read files {', '.join(_os_release_candidates)}" + ) + + return _os_release_cache.copy() + + ### Command line interface if __name__ == '__main__': diff --git a/contrib/tools/python3/src/Lib/posixpath.py b/contrib/tools/python3/src/Lib/posixpath.py index af2814bdb05..195374613a7 100644 --- a/contrib/tools/python3/src/Lib/posixpath.py +++ b/contrib/tools/python3/src/Lib/posixpath.py @@ -262,6 +262,9 @@ def expanduser(path): # password database, return the path unchanged return path userhome = pwent.pw_dir + # if no user home, return the path unchanged on VxWorks + if userhome is None and sys.platform == "vxworks": + return path if isinstance(path, bytes): userhome = os.fsencode(userhome) root = b'/' @@ -385,16 +388,16 @@ def abspath(path): # Return a canonical path (i.e. the absolute location of a file on the # filesystem). -def realpath(filename): +def realpath(filename, *, strict=False): """Return the canonical path of the specified filename, eliminating any symbolic links encountered in the path.""" filename = os.fspath(filename) - path, ok = _joinrealpath(filename[:0], filename, {}) + path, ok = _joinrealpath(filename[:0], filename, strict, {}) return abspath(path) # Join two paths, normalizing and eliminating any symbolic links # encountered in the second path. -def _joinrealpath(path, rest, seen): +def _joinrealpath(path, rest, strict, seen): if isinstance(path, bytes): sep = b'/' curdir = b'.' @@ -423,7 +426,15 @@ def _joinrealpath(path, rest, seen): path = pardir continue newpath = join(path, name) - if not islink(newpath): + try: + st = os.lstat(newpath) + except OSError: + if strict: + raise + is_link = False + else: + is_link = stat.S_ISLNK(st.st_mode) + if not is_link: path = newpath continue # Resolve the symbolic link @@ -434,10 +445,14 @@ def _joinrealpath(path, rest, seen): # use cached value continue # The symlink is not resolved, so we must have a symlink loop. - # Return already resolved part + rest of the path unchanged. - return join(newpath, rest), False + if strict: + # Raise OSError(errno.ELOOP) + os.stat(newpath) + else: + # Return already resolved part + rest of the path unchanged. + return join(newpath, rest), False seen[newpath] = None # not resolved symlink - path, ok = _joinrealpath(path, os.readlink(newpath), seen) + path, ok = _joinrealpath(path, os.readlink(newpath), strict, seen) if not ok: return join(path, rest), False seen[newpath] = path # resolved symlink diff --git a/contrib/tools/python3/src/Lib/pprint.py b/contrib/tools/python3/src/Lib/pprint.py index 7c1118a484b..d91421f0a6b 100644 --- a/contrib/tools/python3/src/Lib/pprint.py +++ b/contrib/tools/python3/src/Lib/pprint.py @@ -35,6 +35,7 @@ saferepr() """ import collections as _collections +import dataclasses as _dataclasses import re import sys as _sys import types as _types @@ -45,18 +46,20 @@ __all__ = ["pprint","pformat","isreadable","isrecursive","saferepr", def pprint(object, stream=None, indent=1, width=80, depth=None, *, - compact=False, sort_dicts=True): + compact=False, sort_dicts=True, underscore_numbers=False): """Pretty-print a Python object to a stream [default is sys.stdout].""" printer = PrettyPrinter( stream=stream, indent=indent, width=width, depth=depth, - compact=compact, sort_dicts=sort_dicts) + compact=compact, sort_dicts=sort_dicts, + underscore_numbers=underscore_numbers) printer.pprint(object) def pformat(object, indent=1, width=80, depth=None, *, - compact=False, sort_dicts=True): + compact=False, sort_dicts=True, underscore_numbers=False): """Format a Python object into a pretty-printed representation.""" return PrettyPrinter(indent=indent, width=width, depth=depth, - compact=compact, sort_dicts=sort_dicts).pformat(object) + compact=compact, sort_dicts=sort_dicts, + underscore_numbers=underscore_numbers).pformat(object) def pp(object, *args, sort_dicts=False, **kwargs): """Pretty-print a Python object""" @@ -64,15 +67,15 @@ def pp(object, *args, sort_dicts=False, **kwargs): def saferepr(object): """Version of repr() which can handle recursive data structures.""" - return _safe_repr(object, {}, None, 0, True)[0] + return PrettyPrinter()._safe_repr(object, {}, None, 0)[0] def isreadable(object): """Determine if saferepr(object) is readable by eval().""" - return _safe_repr(object, {}, None, 0, True)[1] + return PrettyPrinter()._safe_repr(object, {}, None, 0)[1] def isrecursive(object): """Determine if object requires a recursive representation.""" - return _safe_repr(object, {}, None, 0, True)[2] + return PrettyPrinter()._safe_repr(object, {}, None, 0)[2] class _safe_key: """Helper function for key functions when sorting unorderable objects. @@ -102,7 +105,7 @@ def _safe_tuple(t): class PrettyPrinter: def __init__(self, indent=1, width=80, depth=None, stream=None, *, - compact=False, sort_dicts=True): + compact=False, sort_dicts=True, underscore_numbers=False): """Handle pretty printing operations onto a stream using a set of configured parameters. @@ -143,6 +146,7 @@ class PrettyPrinter: self._stream = _sys.stdout self._compact = bool(compact) self._sort_dicts = sort_dicts + self._underscore_numbers = underscore_numbers def pprint(self, object): self._format(object, self._stream, 0, 0, {}, 0) @@ -176,14 +180,26 @@ class PrettyPrinter: p(self, object, stream, indent, allowance, context, level + 1) del context[objid] return - elif isinstance(object, dict): + elif (_dataclasses.is_dataclass(object) and + not isinstance(object, type) and + object.__dataclass_params__.repr and + # Check dataclass has generated repr method. + hasattr(object.__repr__, "__wrapped__") and + "__create_fn__" in object.__repr__.__wrapped__.__qualname__): context[objid] = 1 - self._pprint_dict(object, stream, indent, allowance, - context, level + 1) + self._pprint_dataclass(object, stream, indent, allowance, context, level + 1) del context[objid] return stream.write(rep) + def _pprint_dataclass(self, object, stream, indent, allowance, context, level): + cls_name = object.__class__.__name__ + indent += len(cls_name) + 1 + items = [(f.name, getattr(object, f.name)) for f in _dataclasses.fields(object) if f.repr] + stream.write(cls_name + '(') + self._format_namespace_items(items, stream, indent, allowance, context, level) + stream.write(')') + _dispatch = {} def _pprint_dict(self, object, stream, indent, allowance, context, level): @@ -350,21 +366,9 @@ class PrettyPrinter: else: cls_name = object.__class__.__name__ indent += len(cls_name) + 1 - delimnl = ',\n' + ' ' * indent items = object.__dict__.items() - last_index = len(items) - 1 - stream.write(cls_name + '(') - for i, (key, ent) in enumerate(items): - stream.write(key) - stream.write('=') - - last = i == last_index - self._format(ent, stream, indent + len(key) + 1, - allowance if last else 1, - context, level) - if not last: - stream.write(delimnl) + self._format_namespace_items(items, stream, indent, allowance, context, level) stream.write(')') _dispatch[_types.SimpleNamespace.__repr__] = _pprint_simplenamespace @@ -386,6 +390,25 @@ class PrettyPrinter: if not last: write(delimnl) + def _format_namespace_items(self, items, stream, indent, allowance, context, level): + write = stream.write + delimnl = ',\n' + ' ' * indent + last_index = len(items) - 1 + for i, (key, ent) in enumerate(items): + last = i == last_index + write(key) + write('=') + if id(ent) in context: + # Special-case representation of recursion to match standard + # recursive dataclass repr. + write("...") + else: + self._format(ent, stream, indent + len(key) + 1, + allowance if last else 1, + context, level) + if not last: + write(delimnl) + def _format_items(self, items, stream, indent, allowance, context, level): write = stream.write indent += self._indent_per_level @@ -441,7 +464,7 @@ class PrettyPrinter: and flags indicating whether the representation is 'readable' and whether the object represents a recursive construct. """ - return _safe_repr(object, context, maxlevels, level, self._sort_dicts) + return self._safe_repr(object, context, maxlevels, level) def _pprint_default_dict(self, object, stream, indent, allowance, context, level): if not len(object): @@ -524,79 +547,88 @@ class PrettyPrinter: _dispatch[_collections.UserString.__repr__] = _pprint_user_string -# Return triple (repr_string, isreadable, isrecursive). + def _safe_repr(self, object, context, maxlevels, level): + # Return triple (repr_string, isreadable, isrecursive). + typ = type(object) + if typ in _builtin_scalars: + return repr(object), True, False -def _safe_repr(object, context, maxlevels, level, sort_dicts): - typ = type(object) - if typ in _builtin_scalars: - return repr(object), True, False + r = getattr(typ, "__repr__", None) - r = getattr(typ, "__repr__", None) - if issubclass(typ, dict) and r is dict.__repr__: - if not object: - return "{}", True, False - objid = id(object) - if maxlevels and level >= maxlevels: - return "{...}", False, objid in context - if objid in context: - return _recursion(object), False, True - context[objid] = 1 - readable = True - recursive = False - components = [] - append = components.append - level += 1 - if sort_dicts: - items = sorted(object.items(), key=_safe_tuple) - else: - items = object.items() - for k, v in items: - krepr, kreadable, krecur = _safe_repr(k, context, maxlevels, level, sort_dicts) - vrepr, vreadable, vrecur = _safe_repr(v, context, maxlevels, level, sort_dicts) - append("%s: %s" % (krepr, vrepr)) - readable = readable and kreadable and vreadable - if krecur or vrecur: - recursive = True - del context[objid] - return "{%s}" % ", ".join(components), readable, recursive - - if (issubclass(typ, list) and r is list.__repr__) or \ - (issubclass(typ, tuple) and r is tuple.__repr__): - if issubclass(typ, list): - if not object: - return "[]", True, False - format = "[%s]" - elif len(object) == 1: - format = "(%s,)" - else: + if issubclass(typ, int) and r is int.__repr__: + if self._underscore_numbers: + return f"{object:_d}", True, False + else: + return repr(object), True, False + + if issubclass(typ, dict) and r is dict.__repr__: if not object: - return "()", True, False - format = "(%s)" - objid = id(object) - if maxlevels and level >= maxlevels: - return format % "...", False, objid in context - if objid in context: - return _recursion(object), False, True - context[objid] = 1 - readable = True - recursive = False - components = [] - append = components.append - level += 1 - for o in object: - orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level, sort_dicts) - append(orepr) - if not oreadable: - readable = False - if orecur: - recursive = True - del context[objid] - return format % ", ".join(components), readable, recursive - - rep = repr(object) - return rep, (rep and not rep.startswith('<')), False - -_builtin_scalars = frozenset({str, bytes, bytearray, int, float, complex, + return "{}", True, False + objid = id(object) + if maxlevels and level >= maxlevels: + return "{...}", False, objid in context + if objid in context: + return _recursion(object), False, True + context[objid] = 1 + readable = True + recursive = False + components = [] + append = components.append + level += 1 + if self._sort_dicts: + items = sorted(object.items(), key=_safe_tuple) + else: + items = object.items() + for k, v in items: + krepr, kreadable, krecur = self.format( + k, context, maxlevels, level) + vrepr, vreadable, vrecur = self.format( + v, context, maxlevels, level) + append("%s: %s" % (krepr, vrepr)) + readable = readable and kreadable and vreadable + if krecur or vrecur: + recursive = True + del context[objid] + return "{%s}" % ", ".join(components), readable, recursive + + if (issubclass(typ, list) and r is list.__repr__) or \ + (issubclass(typ, tuple) and r is tuple.__repr__): + if issubclass(typ, list): + if not object: + return "[]", True, False + format = "[%s]" + elif len(object) == 1: + format = "(%s,)" + else: + if not object: + return "()", True, False + format = "(%s)" + objid = id(object) + if maxlevels and level >= maxlevels: + return format % "...", False, objid in context + if objid in context: + return _recursion(object), False, True + context[objid] = 1 + readable = True + recursive = False + components = [] + append = components.append + level += 1 + for o in object: + orepr, oreadable, orecur = self.format( + o, context, maxlevels, level) + append(orepr) + if not oreadable: + readable = False + if orecur: + recursive = True + del context[objid] + return format % ", ".join(components), readable, recursive + + rep = repr(object) + return rep, (rep and not rep.startswith('<')), False + +_builtin_scalars = frozenset({str, bytes, bytearray, float, complex, bool, type(None)}) def _recursion(object): @@ -610,7 +642,7 @@ def _perfcheck(object=None): object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000 p = PrettyPrinter() t1 = time.perf_counter() - _safe_repr(object, {}, None, 0, True) + p._safe_repr(object, {}, None, 0, True) t2 = time.perf_counter() p.pformat(object) t3 = time.perf_counter() diff --git a/contrib/tools/python3/src/Lib/pty.py b/contrib/tools/python3/src/Lib/pty.py index a32432041fa..8d8ce40df54 100644 --- a/contrib/tools/python3/src/Lib/pty.py +++ b/contrib/tools/python3/src/Lib/pty.py @@ -1,7 +1,7 @@ """Pseudo terminal utilities.""" # Bugs: No signal handling. Doesn't set slave termios and window size. -# Only tested on Linux. +# Only tested on Linux, FreeBSD, and macOS. # See: W. Richard Stevens. 1992. Advanced Programming in the # UNIX Environment. Chapter 19. # Author: Steen Lumholt -- with additions by Guido. @@ -11,7 +11,11 @@ import os import sys import tty -__all__ = ["openpty","fork","spawn"] +# names imported directly for test mocking purposes +from os import close, waitpid +from tty import setraw, tcgetattr, tcsetattr + +__all__ = ["openpty", "fork", "spawn"] STDIN_FILENO = 0 STDOUT_FILENO = 1 @@ -105,8 +109,8 @@ def fork(): 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) + 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) @@ -133,14 +137,22 @@ def _copy(master_fd, master_read=_read, stdin_read=_read): pty master -> standard output (master_read) standard input -> pty master (stdin_read)""" fds = [master_fd, STDIN_FILENO] - while True: - rfds, wfds, xfds = select(fds, [], []) + while fds: + rfds, _wfds, _xfds = select(fds, [], []) + if master_fd in rfds: - data = master_read(master_fd) + # Some OSes signal EOF by returning an empty byte string, + # some throw OSErrors. + try: + data = master_read(master_fd) + except OSError: + data = b"" if not data: # Reached EOF. - fds.remove(master_fd) + return # Assume the child process has exited and is + # unreachable, so we clean up. else: os.write(STDOUT_FILENO, data) + if STDIN_FILENO in rfds: data = stdin_read(STDIN_FILENO) if not data: @@ -153,20 +165,23 @@ def spawn(argv, master_read=_read, stdin_read=_read): if type(argv) == type(''): argv = (argv,) sys.audit('pty.spawn', argv) + pid, master_fd = fork() if pid == CHILD: os.execlp(argv[0], *argv) + try: - mode = tty.tcgetattr(STDIN_FILENO) - tty.setraw(STDIN_FILENO) - restore = 1 + mode = tcgetattr(STDIN_FILENO) + setraw(STDIN_FILENO) + restore = True except tty.error: # This is the same as termios.error - restore = 0 + restore = False + try: _copy(master_fd, master_read, stdin_read) - except OSError: + finally: if restore: - tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) + tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) - os.close(master_fd) - return os.waitpid(pid, 0)[1] + close(master_fd) + return waitpid(pid, 0)[1] diff --git a/contrib/tools/python3/src/Lib/py_compile.py b/contrib/tools/python3/src/Lib/py_compile.py index a81f4937310..388614e51b1 100644 --- a/contrib/tools/python3/src/Lib/py_compile.py +++ b/contrib/tools/python3/src/Lib/py_compile.py @@ -173,43 +173,40 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, return cfile -def main(args=None): - """Compile several source files. - - The files named in 'args' (or on the command line, if 'args' is - not specified) are compiled and the resulting bytecode is cached - in the normal manner. This function does not search a directory - structure to locate source files; it only compiles files named - explicitly. If '-' is the only parameter in args, the list of - files is taken from standard input. - - """ - if args is None: - args = sys.argv[1:] - rv = 0 - if args == ['-']: - while True: - filename = sys.stdin.readline() - if not filename: - break - filename = filename.rstrip('\n') - try: - compile(filename, doraise=True) - except PyCompileError as error: - rv = 1 - sys.stderr.write("%s\n" % error.msg) - except OSError as error: - rv = 1 - sys.stderr.write("%s\n" % error) +def main(): + import argparse + + description = 'A simple command-line interface for py_compile module.' + parser = argparse.ArgumentParser(description=description) + parser.add_argument( + '-q', '--quiet', + action='store_true', + help='Suppress error output', + ) + parser.add_argument( + 'filenames', + nargs='+', + help='Files to compile', + ) + args = parser.parse_args() + if args.filenames == ['-']: + filenames = [filename.rstrip('\n') for filename in sys.stdin.readlines()] else: - for filename in args: - try: - compile(filename, doraise=True) - except PyCompileError as error: - # return value to indicate at least one failure - rv = 1 - sys.stderr.write("%s\n" % error.msg) - return rv + filenames = args.filenames + for filename in filenames: + try: + compile(filename, doraise=True) + except PyCompileError as error: + if args.quiet: + parser.exit(1) + else: + parser.exit(1, error.msg) + except OSError as error: + if args.quiet: + parser.exit(1) + else: + parser.exit(1, str(error)) + if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/contrib/tools/python3/src/Lib/pyclbr.py b/contrib/tools/python3/src/Lib/pyclbr.py index 99a17343fb6..37f86995d6c 100644 --- a/contrib/tools/python3/src/Lib/pyclbr.py +++ b/contrib/tools/python3/src/Lib/pyclbr.py @@ -21,11 +21,14 @@ has the following attributes: name -- name of the object; file -- file in which the object is defined; lineno -- line in the file where the object's definition starts; + end_lineno -- line in the file where the object's definition ends; parent -- parent of this object, if any; children -- nested objects contained in this object. The 'children' attribute is a dictionary mapping names to objects. -Instances of Function describe functions with the attributes from _Object. +Instances of Function describe functions with the attributes from _Object, +plus the following: + is_async -- if a function is defined with an 'async' prefix Instances of Class describe classes with the attributes from _Object, plus the following: @@ -38,11 +41,9 @@ are recognized and imported modules are scanned as well, this shouldn't happen often. """ -import io +import ast import sys import importlib.util -import tokenize -from token import NAME, DEDENT, OP __all__ = ["readmodule", "readmodule_ex", "Class", "Function"] @@ -51,48 +52,50 @@ _modules = {} # Initialize cache of modules we've seen. class _Object: "Information about Python class or function." - def __init__(self, module, name, file, lineno, parent): + def __init__(self, module, name, file, lineno, end_lineno, parent): self.module = module self.name = name self.file = file self.lineno = lineno + self.end_lineno = end_lineno self.parent = parent self.children = {} - - def _addchild(self, name, obj): - self.children[name] = obj + if parent is not None: + parent.children[name] = self +# Odd Function and Class signatures are for back-compatibility. class Function(_Object): "Information about a Python function, including methods." - def __init__(self, module, name, file, lineno, parent=None): - _Object.__init__(self, module, name, file, lineno, parent) + def __init__(self, module, name, file, lineno, + parent=None, is_async=False, *, end_lineno=None): + super().__init__(module, name, file, lineno, end_lineno, parent) + self.is_async = is_async + if isinstance(parent, Class): + parent.methods[name] = lineno class Class(_Object): "Information about a Python class." - def __init__(self, module, name, super, file, lineno, parent=None): - _Object.__init__(self, module, name, file, lineno, parent) - self.super = [] if super is None else super + def __init__(self, module, name, super_, file, lineno, + parent=None, *, end_lineno=None): + super().__init__(module, name, file, lineno, end_lineno, parent) + self.super = super_ or [] self.methods = {} - def _addmethod(self, name, lineno): - self.methods[name] = lineno - -def _nest_function(ob, func_name, lineno): +# These 2 functions are used in these tests +# Lib/test/test_pyclbr, Lib/idlelib/idle_test/test_browser.py +def _nest_function(ob, func_name, lineno, end_lineno, is_async=False): "Return a Function after nesting within ob." - newfunc = Function(ob.module, func_name, ob.file, lineno, ob) - ob._addchild(func_name, newfunc) - if isinstance(ob, Class): - ob._addmethod(func_name, lineno) - return newfunc + return Function(ob.module, func_name, ob.file, lineno, + parent=ob, is_async=is_async, end_lineno=end_lineno) -def _nest_class(ob, class_name, lineno, super=None): +def _nest_class(ob, class_name, lineno, end_lineno, super=None): "Return a Class after nesting within ob." - newclass = Class(ob.module, class_name, super, ob.file, lineno, ob) - ob._addchild(class_name, newclass) - return newclass + return Class(ob.module, class_name, super, ob.file, lineno, + parent=ob, end_lineno=end_lineno) + def readmodule(module, path=None): """Return Class objects for the top-level classes in module. @@ -115,6 +118,7 @@ def readmodule_ex(module, path=None): """ return _readmodule(module, path or []) + def _readmodule(module, path, inpackage=None): """Do the hard work for readmodule[_ex]. @@ -179,187 +183,93 @@ def _readmodule(module, path, inpackage=None): return _create_tree(fullmodule, path, fname, source, tree, inpackage) -def _create_tree(fullmodule, path, fname, source, tree, inpackage): - """Return the tree for a particular module. - - fullmodule (full module name), inpackage+module, becomes o.module. - path is passed to recursive calls of _readmodule. - fname becomes o.file. - source is tokenized. Imports cause recursive calls to _readmodule. - tree is {} or {'__path__': }. - inpackage, None or string, is passed to recursive calls of _readmodule. - - The effect of recursive calls is mutation of global _modules. - """ - f = io.StringIO(source) +class _ModuleBrowser(ast.NodeVisitor): + def __init__(self, module, path, file, tree, inpackage): + self.path = path + self.tree = tree + self.file = file + self.module = module + self.inpackage = inpackage + self.stack = [] + + def visit_ClassDef(self, node): + bases = [] + for base in node.bases: + name = ast.unparse(base) + if name in self.tree: + # We know this super class. + bases.append(self.tree[name]) + elif len(names := name.split(".")) > 1: + # Super class form is module.class: + # look in module for class. + *_, module, class_ = names + if module in _modules: + bases.append(_modules[module].get(class_, name)) + else: + bases.append(name) + + parent = self.stack[-1] if self.stack else None + class_ = Class(self.module, node.name, bases, self.file, node.lineno, + parent=parent, end_lineno=node.end_lineno) + if parent is None: + self.tree[node.name] = class_ + self.stack.append(class_) + self.generic_visit(node) + self.stack.pop() + + def visit_FunctionDef(self, node, *, is_async=False): + parent = self.stack[-1] if self.stack else None + function = Function(self.module, node.name, self.file, node.lineno, + parent, is_async, end_lineno=node.end_lineno) + if parent is None: + self.tree[node.name] = function + self.stack.append(function) + self.generic_visit(node) + self.stack.pop() + + def visit_AsyncFunctionDef(self, node): + self.visit_FunctionDef(node, is_async=True) + + def visit_Import(self, node): + if node.col_offset != 0: + return + + for module in node.names: + try: + try: + _readmodule(module.name, self.path, self.inpackage) + except ImportError: + _readmodule(module.name, []) + except (ImportError, SyntaxError): + # If we can't find or parse the imported module, + # too bad -- don't die here. + continue + + def visit_ImportFrom(self, node): + if node.col_offset != 0: + return + try: + module = "." * node.level + if node.module: + module += node.module + module = _readmodule(module, self.path, self.inpackage) + except (ImportError, SyntaxError): + return + + for name in node.names: + if name.name in module: + self.tree[name.asname or name.name] = module[name.name] + elif name.name == "*": + for import_name, import_value in module.items(): + if import_name.startswith("_"): + continue + self.tree[import_name] = import_value - stack = [] # Initialize stack of (class, indent) pairs. - g = tokenize.generate_tokens(f.readline) - try: - for tokentype, token, start, _end, _line in g: - if tokentype == DEDENT: - lineno, thisindent = start - # Close previous nested classes and defs. - while stack and stack[-1][1] >= thisindent: - del stack[-1] - elif token == 'def': - lineno, thisindent = start - # Close previous nested classes and defs. - while stack and stack[-1][1] >= thisindent: - del stack[-1] - tokentype, func_name, start = next(g)[0:3] - if tokentype != NAME: - continue # Skip def with syntax error. - cur_func = None - if stack: - cur_obj = stack[-1][0] - cur_func = _nest_function(cur_obj, func_name, lineno) - else: - # It is just a function. - cur_func = Function(fullmodule, func_name, fname, lineno) - tree[func_name] = cur_func - stack.append((cur_func, thisindent)) - elif token == 'class': - lineno, thisindent = start - # Close previous nested classes and defs. - while stack and stack[-1][1] >= thisindent: - del stack[-1] - tokentype, class_name, start = next(g)[0:3] - if tokentype != NAME: - continue # Skip class with syntax error. - # Parse what follows the class name. - tokentype, token, start = next(g)[0:3] - inherit = None - if token == '(': - names = [] # Initialize list of superclasses. - level = 1 - super = [] # Tokens making up current superclass. - while True: - tokentype, token, start = next(g)[0:3] - if token in (')', ',') and level == 1: - n = "".join(super) - if n in tree: - # We know this super class. - n = tree[n] - else: - c = n.split('.') - if len(c) > 1: - # Super class form is module.class: - # look in module for class. - m = c[-2] - c = c[-1] - if m in _modules: - d = _modules[m] - if c in d: - n = d[c] - names.append(n) - super = [] - if token == '(': - level += 1 - elif token == ')': - level -= 1 - if level == 0: - break - elif token == ',' and level == 1: - pass - # Only use NAME and OP (== dot) tokens for type name. - elif tokentype in (NAME, OP) and level == 1: - super.append(token) - # Expressions in the base list are not supported. - inherit = names - if stack: - cur_obj = stack[-1][0] - cur_class = _nest_class( - cur_obj, class_name, lineno, inherit) - else: - cur_class = Class(fullmodule, class_name, inherit, - fname, lineno) - tree[class_name] = cur_class - stack.append((cur_class, thisindent)) - elif token == 'import' and start[1] == 0: - modules = _getnamelist(g) - for mod, _mod2 in modules: - try: - # Recursively read the imported module. - if inpackage is None: - _readmodule(mod, path) - else: - try: - _readmodule(mod, path, inpackage) - except ImportError: - _readmodule(mod, []) - except: - # If we can't find or parse the imported module, - # too bad -- don't die here. - pass - elif token == 'from' and start[1] == 0: - mod, token = _getname(g) - if not mod or token != "import": - continue - names = _getnamelist(g) - try: - # Recursively read the imported module. - d = _readmodule(mod, path, inpackage) - except: - # If we can't find or parse the imported module, - # too bad -- don't die here. - continue - # Add any classes that were defined in the imported module - # to our name space if they were mentioned in the list. - for n, n2 in names: - if n in d: - tree[n2 or n] = d[n] - elif n == '*': - # Don't add names that start with _. - for n in d: - if n[0] != '_': - tree[n] = d[n] - except StopIteration: - pass - - f.close() - return tree - - -def _getnamelist(g): - """Return list of (dotted-name, as-name or None) tuples for token source g. - - An as-name is the name that follows 'as' in an as clause. - """ - names = [] - while True: - name, token = _getname(g) - if not name: - break - if token == 'as': - name2, token = _getname(g) - else: - name2 = None - names.append((name, name2)) - while token != "," and "\n" not in token: - token = next(g)[1] - if token != ",": - break - return names - - -def _getname(g): - "Return (dotted-name or None, next-token) tuple for token source g." - parts = [] - tokentype, token = next(g)[0:2] - if tokentype != NAME and token != '*': - return (None, token) - parts.append(token) - while True: - tokentype, token = next(g)[0:2] - if token != '.': - break - tokentype, token = next(g)[0:2] - if tokentype != NAME: - break - parts.append(token) - return (".".join(parts), token) +def _create_tree(fullmodule, path, fname, source, tree, inpackage): + mbrowser = _ModuleBrowser(fullmodule, path, fname, tree, inpackage) + mbrowser.visit(ast.parse(source)) + return mbrowser.tree def _main(): diff --git a/contrib/tools/python3/src/Lib/pydoc.py b/contrib/tools/python3/src/Lib/pydoc.py index ead67853076..e00ba4191c4 100755 --- a/contrib/tools/python3/src/Lib/pydoc.py +++ b/contrib/tools/python3/src/Lib/pydoc.py @@ -23,7 +23,7 @@ Run "pydoc -p " to start an HTTP server on the given port on the local machine. Port number 0 can be used to get an arbitrary unused port. Run "pydoc -b" to start an HTTP server on an arbitrary unused port and -open a Web browser to interactively browse documentation. Combine with +open a web browser to interactively browse documentation. Combine with the -n and -p options to control the hostname and port used. Run "pydoc -w " to write out the HTML documentation for a module @@ -508,7 +508,7 @@ class Doc: not file.startswith(os.path.join(basedir, 'site-packages')))) and object.__name__ not in ('xml.etree', 'test.pydoc_mod')): if docloc.startswith(("http://", "https://")): - docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower()) + docloc = "{}/{}.html".format(docloc.rstrip("/"), object.__name__.lower()) else: docloc = os.path.join(docloc, object.__name__.lower() + ".html") else: @@ -1598,9 +1598,10 @@ def plain(text): def pipepager(text, cmd): """Page through text by feeding it to another program.""" import subprocess - proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE) + proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + errors='backslashreplace') try: - with io.TextIOWrapper(proc.stdin, errors='backslashreplace') as pipe: + with proc.stdin as pipe: try: pipe.write(text) except KeyboardInterrupt: @@ -1822,7 +1823,6 @@ class Helper: 'False': '', 'None': '', 'True': '', - '__peg_parser__': '', 'and': 'BOOLEAN', 'as': 'with', 'assert': ('assert', ''), @@ -2070,7 +2070,7 @@ has the same effect as typing a particular string at the help> prompt. Welcome to Python {0}'s help utility! If this is your first time using Python, you should definitely check out -the tutorial on the Internet at https://docs.python.org/{0}/tutorial/. +the tutorial on the internet at https://docs.python.org/{0}/tutorial/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and @@ -2284,13 +2284,13 @@ def apropos(key): warnings.filterwarnings('ignore') # ignore problems during import ModuleScanner().run(callback, key, onerror=onerror) -# --------------------------------------- enhanced Web browser interface +# --------------------------------------- enhanced web browser interface def _start_server(urlhandler, hostname, port): """Start an HTTP server thread on a specific port. Start an HTML/text server thread, so HTML or text documents can be - browsed dynamically and interactively with a Web browser. Example use: + browsed dynamically and interactively with a web browser. Example use: >>> import time >>> import pydoc @@ -2676,7 +2676,7 @@ def _url_handler(url, content_type="text/html"): def browse(port=0, *, open_browser=True, hostname='localhost'): - """Start the enhanced pydoc Web server and open a Web browser. + """Start the enhanced pydoc web server and open a web browser. Use port '0' to start the server on an arbitrary port. Set open_browser to False to suppress opening a browser. @@ -2828,7 +2828,7 @@ def cli(): number 0 can be used to get an arbitrary unused port. {cmd} -b - Start an HTTP server on an arbitrary unused port and open a Web browser + Start an HTTP server on an arbitrary unused port and open a web browser to interactively browse documentation. This option can be used in combination with -n and/or -p. diff --git a/contrib/tools/python3/src/Lib/pydoc_data/topics.py b/contrib/tools/python3/src/Lib/pydoc_data/topics.py index 2546eb933bc..76db0426df3 100644 --- a/contrib/tools/python3/src/Lib/pydoc_data/topics.py +++ b/contrib/tools/python3/src/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Wed Mar 23 22:08:02 2022 +# Autogenerated by Sphinx on Wed Mar 23 20:11:40 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -433,11 +433,9 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'Execution of Python coroutines can be suspended and resumed at ' 'many\n' - 'points (see *coroutine*). Inside the body of a coroutine ' - 'function,\n' - '"await" and "async" identifiers become reserved keywords; "await"\n' - 'expressions, "async for" and "async with" can only be used in\n' - 'coroutine function bodies.\n' + 'points (see *coroutine*). "await" expressions, "async for" and ' + '"async\n' + 'with" can only be used in the body of a coroutine function.\n' '\n' 'Functions defined with "async def" syntax are always coroutine\n' 'functions, even if they do not contain "await" or "async" ' @@ -453,6 +451,10 @@ topics = {'assert': 'The "assert" statement\n' ' do_stuff()\n' ' await some_coroutine()\n' '\n' + 'Changed in version 3.7: "await" and "async" are now keywords;\n' + 'previously they were only treated as such inside the body of a\n' + 'coroutine function.\n' + '\n' '\n' 'The "async for" statement\n' '=========================\n' @@ -549,13 +551,65 @@ topics = {'assert': 'The "assert" statement\n' 'exception.\n' ' That new exception causes the old one to be lost.\n' '\n' - '[2] A string literal appearing as the first statement in the ' + '[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' - '[3] A string literal appearing as the first statement in the class\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', 'atom-identifiers': 'Identifiers (Names)\n' @@ -882,32 +936,6 @@ topics = {'assert': 'The "assert" statement\n' '*instance* of the\n' ' owner class.\n' '\n' - 'object.__set_name__(self, owner, name)\n' - '\n' - ' Called at the time the owning class *owner* is ' - 'created. The\n' - ' descriptor has been assigned to *name*.\n' - '\n' - ' Note:\n' - '\n' - ' "__set_name__()" is only called implicitly as part ' - 'of the "type"\n' - ' constructor, so it will need to be called ' - 'explicitly with the\n' - ' appropriate parameters when a descriptor is added ' - 'to a class\n' - ' after initial creation:\n' - '\n' - ' class A:\n' - ' pass\n' - ' descr = custom_descriptor()\n' - ' A.attr = descr\n' - " descr.__set_name__(A, 'attr')\n" - '\n' - ' See Creating the class object for more details.\n' - '\n' - ' New in version 3.6.\n' - '\n' 'The attribute "__objclass__" is interpreted by the ' '"inspect" module as\n' 'specifying the class where this object was defined ' @@ -1736,7 +1764,7 @@ topics = {'assert': 'The "assert" statement\n' 'original global namespace. (Usually, the suite contains mostly\n' 'function definitions.) When the class’s suite finishes execution, ' 'its\n' - 'execution frame is discarded but its local namespace is saved. [3] ' + 'execution frame is discarded but its local namespace is saved. [5] ' 'A\n' 'class object is then created using the inheritance list for the ' 'base\n' @@ -2219,6 +2247,7 @@ topics = {'assert': 'The "assert" statement\n' ' | for_stmt\n' ' | try_stmt\n' ' | with_stmt\n' + ' | match_stmt\n' ' | funcdef\n' ' | classdef\n' ' | async_with_stmt\n' @@ -2356,33 +2385,6 @@ topics = {'assert': 'The "assert" statement\n' ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, ' '2]".\n' '\n' - 'Note:\n' - '\n' - ' There is a subtlety when the sequence is being modified by the ' - 'loop\n' - ' (this can only occur for mutable sequences, e.g. lists). An\n' - ' internal counter is used to keep track of which item is used ' - 'next,\n' - ' and this is incremented on each iteration. When this counter ' - 'has\n' - ' reached the length of the sequence the loop terminates. This ' - 'means\n' - ' that if the suite deletes the current (or a previous) item ' - 'from the\n' - ' sequence, the next item will be skipped (since it gets the ' - 'index of\n' - ' the current item which has already been treated). Likewise, ' - 'if the\n' - ' suite inserts an item in the sequence before the current item, ' - 'the\n' - ' current item will be treated again the next time through the ' - 'loop.\n' - ' This can lead to nasty bugs that can be avoided by making a\n' - ' temporary copy using a slice of the whole sequence, e.g.,\n' - '\n' - ' for x in a[:]:\n' - ' if x < 0: a.remove(x)\n' - '\n' '\n' 'The "try" statement\n' '===================\n' @@ -2487,11 +2489,32 @@ topics = {'assert': 'The "assert" statement\n' '(see\n' 'section The standard type hierarchy) identifying the point in ' 'the\n' - 'program where the exception occurred. "sys.exc_info()" values ' - 'are\n' - 'restored to their previous values (before the call) when ' - 'returning\n' - 'from a function that handled an exception.\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' + '\n' + ' >>> print(sys.exc_info())\n' + ' (None, None, None)\n' + ' >>> try:\n' + ' ... raise TypeError\n' + ' ... except:\n' + ' ... print(sys.exc_info())\n' + ' ... try:\n' + ' ... raise ValueError\n' + ' ... except:\n' + ' ... print(sys.exc_info())\n' + ' ... print(sys.exc_info())\n' + ' ...\n' + " (, TypeError(), )\n' + " (, ValueError(), )\n' + " (, TypeError(), )\n' + ' >>> print(sys.exc_info())\n' + ' (None, None, None)\n' '\n' 'The optional "else" clause is executed if the control flow ' 'leaves the\n' @@ -2576,8 +2599,10 @@ topics = {'assert': 'The "assert" statement\n' 'usage\n' 'patterns to be encapsulated for convenient reuse.\n' '\n' - ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' - ' with_item ::= expression ["as" target]\n' + ' with_stmt ::= "with" ( "(" with_stmt_contents ","? ' + '")" | with_stmt_contents ) ":" suite\n' + ' with_stmt_contents ::= with_item ("," with_item)*\n' + ' with_item ::= expression ["as" target]\n' '\n' 'The execution of the "with" statement with one “item” proceeds ' 'as\n' @@ -2669,9 +2694,23 @@ topics = {'assert': 'The "assert" statement\n' ' with B() as b:\n' ' SUITE\n' '\n' + 'You can also write multi-item context managers in multiple lines ' + 'if\n' + 'the items are surrounded by parentheses. For example:\n' + '\n' + ' with (\n' + ' A() as a,\n' + ' B() as b,\n' + ' ):\n' + ' SUITE\n' + '\n' 'Changed in version 3.1: Support for multiple context ' 'expressions.\n' '\n' + 'Changed in version 3.10: Support for using grouping parentheses ' + 'to\n' + 'break the statement in multiple lines.\n' + '\n' 'See also:\n' '\n' ' **PEP 343** - The “with” statement\n' @@ -2680,6 +2719,746 @@ topics = {'assert': 'The "assert" statement\n' ' statement.\n' '\n' '\n' + 'The "match" statement\n' + '=====================\n' + '\n' + 'New in version 3.10.\n' + '\n' + 'The match statement is used for pattern matching. Syntax:\n' + '\n' + ' match_stmt ::= \'match\' subject_expr ":" NEWLINE INDENT ' + 'case_block+ DEDENT\n' + ' subject_expr ::= star_named_expression "," ' + 'star_named_expressions?\n' + ' | named_expression\n' + ' case_block ::= \'case\' patterns [guard] ":" block\n' + '\n' + 'Note:\n' + '\n' + ' This section uses single quotes to denote soft keywords.\n' + '\n' + 'Pattern matching takes a pattern as input (following "case") and ' + 'a\n' + 'subject value (following "match"). The pattern (which may ' + 'contain\n' + 'subpatterns) is matched against the subject value. The outcomes ' + 'are:\n' + '\n' + '* A match success or failure (also termed a pattern success or\n' + ' failure).\n' + '\n' + '* Possible binding of matched values to a name. The ' + 'prerequisites for\n' + ' this are further discussed below.\n' + '\n' + 'The "match" and "case" keywords are soft keywords.\n' + '\n' + 'See also:\n' + '\n' + ' * **PEP 634** – Structural Pattern Matching: Specification\n' + '\n' + ' * **PEP 636** – Structural Pattern Matching: Tutorial\n' + '\n' + '\n' + 'Overview\n' + '--------\n' + '\n' + 'Here’s an overview of the logical flow of a match statement:\n' + '\n' + '1. The subject expression "subject_expr" is evaluated and a ' + 'resulting\n' + ' subject value obtained. If the subject expression contains a ' + 'comma,\n' + ' a tuple is constructed using the standard rules.\n' + '\n' + '2. Each pattern in a "case_block" is attempted to match with ' + 'the\n' + ' subject value. The specific rules for success or failure are\n' + ' described below. The match attempt can also bind some or all ' + 'of the\n' + ' standalone names within the pattern. The precise pattern ' + 'binding\n' + ' rules vary per pattern type and are specified below. **Name\n' + ' bindings made during a successful pattern match outlive the\n' + ' executed block and can be used after the match statement**.\n' + '\n' + ' Note:\n' + '\n' + ' During failed pattern matches, some subpatterns may ' + 'succeed.\n' + ' Do not rely on bindings being made for a failed match.\n' + ' Conversely, do not rely on variables remaining unchanged ' + 'after\n' + ' a failed match. The exact behavior is dependent on\n' + ' implementation and may vary. This is an intentional ' + 'decision\n' + ' made to allow different implementations to add ' + 'optimizations.\n' + '\n' + '3. If the pattern succeeds, the corresponding guard (if present) ' + 'is\n' + ' evaluated. In this case all name bindings are guaranteed to ' + 'have\n' + ' happened.\n' + '\n' + ' * If the guard evaluates as true or is missing, the "block" ' + 'inside\n' + ' "case_block" is executed.\n' + '\n' + ' * Otherwise, the next "case_block" is attempted as described ' + 'above.\n' + '\n' + ' * If there are no further case blocks, the match statement ' + 'is\n' + ' completed.\n' + '\n' + 'Note:\n' + '\n' + ' Users should generally never rely on a pattern being ' + 'evaluated.\n' + ' Depending on implementation, the interpreter may cache values ' + 'or use\n' + ' other optimizations which skip repeated evaluations.\n' + '\n' + 'A sample match statement:\n' + '\n' + ' >>> flag = False\n' + ' >>> match (100, 200):\n' + ' ... case (100, 300): # Mismatch: 200 != 300\n' + " ... print('Case 1')\n" + ' ... case (100, 200) if flag: # Successful match, but ' + 'guard fails\n' + " ... print('Case 2')\n" + ' ... case (100, y): # Matches and binds y to 200\n' + " ... print(f'Case 3, y: {y}')\n" + ' ... case _: # Pattern not attempted\n' + " ... print('Case 4, I match anything!')\n" + ' ...\n' + ' Case 3, y: 200\n' + '\n' + 'In this case, "if flag" is a guard. Read more about that in the ' + 'next\n' + 'section.\n' + '\n' + '\n' + 'Guards\n' + '------\n' + '\n' + ' guard ::= "if" named_expression\n' + '\n' + 'A "guard" (which is part of the "case") must succeed for code ' + 'inside\n' + 'the "case" block to execute. It takes the form: "if" followed ' + 'by an\n' + 'expression.\n' + '\n' + 'The logical flow of a "case" block with a "guard" follows:\n' + '\n' + '1. Check that the pattern in the "case" block succeeded. If ' + 'the\n' + ' pattern failed, the "guard" is not evaluated and the next ' + '"case"\n' + ' block is checked.\n' + '\n' + '2. If the pattern succeeded, evaluate the "guard".\n' + '\n' + ' * If the "guard" condition evaluates as true, the case block ' + 'is\n' + ' selected.\n' + '\n' + ' * If the "guard" condition evaluates as false, the case block ' + 'is\n' + ' not selected.\n' + '\n' + ' * If the "guard" raises an exception during evaluation, the\n' + ' exception bubbles up.\n' + '\n' + 'Guards are allowed to have side effects as they are ' + 'expressions.\n' + 'Guard evaluation must proceed from the first to the last case ' + 'block,\n' + 'one at a time, skipping case blocks whose pattern(s) don’t all\n' + 'succeed. (I.e., guard evaluation must happen in order.) Guard\n' + 'evaluation must stop once a case block is selected.\n' + '\n' + '\n' + 'Irrefutable Case Blocks\n' + '-----------------------\n' + '\n' + 'An irrefutable case block is a match-all case block. A match\n' + 'statement may have at most one irrefutable case block, and it ' + 'must be\n' + 'last.\n' + '\n' + 'A case block is considered irrefutable if it has no guard and ' + 'its\n' + 'pattern is irrefutable. A pattern is considered irrefutable if ' + 'we can\n' + 'prove from its syntax alone that it will always succeed. Only ' + 'the\n' + 'following patterns are irrefutable:\n' + '\n' + '* AS Patterns whose left-hand side is irrefutable\n' + '\n' + '* OR Patterns containing at least one irrefutable pattern\n' + '\n' + '* Capture Patterns\n' + '\n' + '* Wildcard Patterns\n' + '\n' + '* parenthesized irrefutable patterns\n' + '\n' + '\n' + 'Patterns\n' + '--------\n' + '\n' + 'Note:\n' + '\n' + ' This section uses grammar notations beyond standard EBNF:\n' + '\n' + ' * the notation "SEP.RULE+" is shorthand for "RULE (SEP ' + 'RULE)*"\n' + '\n' + ' * the notation "!RULE" is shorthand for a negative lookahead\n' + ' assertion\n' + '\n' + 'The top-level syntax for "patterns" is:\n' + '\n' + ' patterns ::= open_sequence_pattern | pattern\n' + ' pattern ::= as_pattern | or_pattern\n' + ' closed_pattern ::= | literal_pattern\n' + ' | capture_pattern\n' + ' | wildcard_pattern\n' + ' | value_pattern\n' + ' | group_pattern\n' + ' | sequence_pattern\n' + ' | mapping_pattern\n' + ' | class_pattern\n' + '\n' + 'The descriptions below will include a description “in simple ' + 'terms” of\n' + 'what a pattern does for illustration purposes (credits to ' + 'Raymond\n' + 'Hettinger for a document that inspired most of the ' + 'descriptions). Note\n' + 'that these descriptions are purely for illustration purposes and ' + '**may\n' + 'not** reflect the underlying implementation. Furthermore, they ' + 'do not\n' + 'cover all valid forms.\n' + '\n' + '\n' + 'OR Patterns\n' + '~~~~~~~~~~~\n' + '\n' + 'An OR pattern is two or more patterns separated by vertical bars ' + '"|".\n' + 'Syntax:\n' + '\n' + ' or_pattern ::= "|".closed_pattern+\n' + '\n' + 'Only the final subpattern may be irrefutable, and each ' + 'subpattern must\n' + 'bind the same set of names to avoid ambiguity.\n' + '\n' + 'An OR pattern matches each of its subpatterns in turn to the ' + 'subject\n' + 'value, until one succeeds. The OR pattern is then considered\n' + 'successful. Otherwise, if none of the subpatterns succeed, the ' + 'OR\n' + 'pattern fails.\n' + '\n' + 'In simple terms, "P1 | P2 | ..." will try to match "P1", if it ' + 'fails\n' + 'it will try to match "P2", succeeding immediately if any ' + 'succeeds,\n' + 'failing otherwise.\n' + '\n' + '\n' + 'AS Patterns\n' + '~~~~~~~~~~~\n' + '\n' + 'An AS pattern matches an OR pattern on the left of the "as" ' + 'keyword\n' + 'against a subject. Syntax:\n' + '\n' + ' as_pattern ::= or_pattern "as" capture_pattern\n' + '\n' + 'If the OR pattern fails, the AS pattern fails. Otherwise, the ' + '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' + '\n' + 'In simple terms "P as NAME" will match with "P", and on success ' + 'it\n' + 'will set "NAME = ".\n' + '\n' + '\n' + 'Literal Patterns\n' + '~~~~~~~~~~~~~~~~\n' + '\n' + 'A literal pattern corresponds to most literals in Python. ' + 'Syntax:\n' + '\n' + ' literal_pattern ::= signed_number\n' + ' | signed_number "+" NUMBER\n' + ' | signed_number "-" NUMBER\n' + ' | strings\n' + ' | "None"\n' + ' | "True"\n' + ' | "False"\n' + ' | signed_number: NUMBER | "-" NUMBER\n' + '\n' + 'The rule "strings" and the token "NUMBER" are defined in the ' + 'standard\n' + 'Python grammar. Triple-quoted strings are supported. Raw ' + 'strings and\n' + 'byte strings are supported. Formatted string literals are not\n' + 'supported.\n' + '\n' + 'The forms "signed_number \'+\' NUMBER" and "signed_number \'-\' ' + 'NUMBER"\n' + 'are for expressing complex numbers; they require a real number ' + 'on the\n' + 'left and an imaginary number on the right. E.g. "3 + 4j".\n' + '\n' + 'In simple terms, "LITERAL" will succeed only if " ==\n' + 'LITERAL". For the singletons "None", "True" and "False", the ' + '"is"\n' + 'operator is used.\n' + '\n' + '\n' + 'Capture Patterns\n' + '~~~~~~~~~~~~~~~~\n' + '\n' + 'A capture pattern binds the subject value to a name. Syntax:\n' + '\n' + " capture_pattern ::= !'_' NAME\n" + '\n' + 'A single underscore "_" is not a capture pattern (this is what ' + '"!\'_\'"\n' + 'expresses). It is instead treated as a "wildcard_pattern".\n' + '\n' + 'In a given pattern, a given name can only be bound once. E.g. ' + '"case\n' + 'x, x: ..." is invalid while "case [x] | x: ..." is allowed.\n' + '\n' + 'Capture patterns always succeed. The binding follows scoping ' + 'rules\n' + 'established by the assignment expression operator in **PEP ' + '572**; the\n' + 'name becomes a local variable in the closest containing function ' + 'scope\n' + 'unless there’s an applicable "global" or "nonlocal" statement.\n' + '\n' + 'In simple terms "NAME" will always succeed and it will set "NAME ' + '=\n' + '".\n' + '\n' + '\n' + 'Wildcard Patterns\n' + '~~~~~~~~~~~~~~~~~\n' + '\n' + 'A wildcard pattern always succeeds (matches anything) and binds ' + 'no\n' + 'name. Syntax:\n' + '\n' + " wildcard_pattern ::= '_'\n" + '\n' + '"_" is a soft keyword within any pattern, but only within ' + 'patterns.\n' + 'It is an identifier, as usual, even within "match" subject\n' + 'expressions, "guard"s, and "case" blocks.\n' + '\n' + 'In simple terms, "_" will always succeed.\n' + '\n' + '\n' + 'Value Patterns\n' + '~~~~~~~~~~~~~~\n' + '\n' + 'A value pattern represents a named value in Python. Syntax:\n' + '\n' + ' value_pattern ::= attr\n' + ' attr ::= name_or_attr "." NAME\n' + ' name_or_attr ::= attr | NAME\n' + '\n' + 'The dotted name in the pattern is looked up using standard ' + 'Python name\n' + 'resolution rules. The pattern succeeds if the value found ' + 'compares\n' + 'equal to the subject value (using the "==" equality operator).\n' + '\n' + 'In simple terms "NAME1.NAME2" will succeed only if " ' + '==\n' + 'NAME1.NAME2"\n' + '\n' + 'Note:\n' + '\n' + ' If the same value occurs multiple times in the same match ' + 'statement,\n' + ' the interpreter may cache the first value found and reuse it ' + 'rather\n' + ' than repeat the same lookup. This cache is strictly tied to a ' + 'given\n' + ' execution of a given match statement.\n' + '\n' + '\n' + 'Group Patterns\n' + '~~~~~~~~~~~~~~\n' + '\n' + 'A group pattern allows users to add parentheses around patterns ' + 'to\n' + 'emphasize the intended grouping. Otherwise, it has no ' + 'additional\n' + 'syntax. Syntax:\n' + '\n' + ' group_pattern ::= "(" pattern ")"\n' + '\n' + 'In simple terms "(P)" has the same effect as "P".\n' + '\n' + '\n' + 'Sequence Patterns\n' + '~~~~~~~~~~~~~~~~~\n' + '\n' + 'A sequence pattern contains several subpatterns to be matched ' + 'against\n' + 'sequence elements. The syntax is similar to the unpacking of a ' + 'list or\n' + 'tuple.\n' + '\n' + ' sequence_pattern ::= "[" [maybe_sequence_pattern] "]"\n' + ' | "(" [open_sequence_pattern] ")"\n' + ' open_sequence_pattern ::= maybe_star_pattern "," ' + '[maybe_sequence_pattern]\n' + ' maybe_sequence_pattern ::= ",".maybe_star_pattern+ ","?\n' + ' maybe_star_pattern ::= star_pattern | pattern\n' + ' star_pattern ::= "*" (capture_pattern | ' + 'wildcard_pattern)\n' + '\n' + 'There is no difference if parentheses or square brackets are ' + 'used for\n' + 'sequence patterns (i.e. "(...)" vs "[...]" ).\n' + '\n' + 'Note:\n' + '\n' + ' A single pattern enclosed in parentheses without a trailing ' + 'comma\n' + ' (e.g. "(3 | 4)") is a group pattern. While a single pattern ' + 'enclosed\n' + ' in square brackets (e.g. "[3 | 4]") is still a sequence ' + 'pattern.\n' + '\n' + 'At most one star subpattern may be in a sequence pattern. The ' + 'star\n' + 'subpattern may occur in any position. If no star subpattern is\n' + 'present, the sequence pattern is a fixed-length sequence ' + 'pattern;\n' + 'otherwise it is a variable-length sequence pattern.\n' + '\n' + 'The following is the logical flow for matching a sequence ' + 'pattern\n' + 'against a subject value:\n' + '\n' + '1. If the subject value is not a sequence [2], the sequence ' + 'pattern\n' + ' fails.\n' + '\n' + '2. If the subject value is an instance of "str", "bytes" or\n' + ' "bytearray" the sequence pattern fails.\n' + '\n' + '3. The subsequent steps depend on whether the sequence pattern ' + 'is\n' + ' fixed or variable-length.\n' + '\n' + ' If the sequence pattern is fixed-length:\n' + '\n' + ' 1. If the length of the subject sequence is not equal to the ' + 'number\n' + ' of subpatterns, the sequence pattern fails\n' + '\n' + ' 2. Subpatterns in the sequence pattern are matched to their\n' + ' corresponding items in the subject sequence from left to ' + 'right.\n' + ' Matching stops as soon as a subpattern fails. If all\n' + ' subpatterns succeed in matching their corresponding item, ' + 'the\n' + ' sequence pattern succeeds.\n' + '\n' + ' Otherwise, if the sequence pattern is variable-length:\n' + '\n' + ' 1. If the length of the subject sequence is less than the ' + 'number of\n' + ' non-star subpatterns, the sequence pattern fails.\n' + '\n' + ' 2. The leading non-star subpatterns are matched to their\n' + ' corresponding items as for fixed-length sequences.\n' + '\n' + ' 3. If the previous step succeeds, the star subpattern matches ' + 'a\n' + ' list formed of the remaining subject items, excluding the\n' + ' remaining items corresponding to non-star subpatterns ' + 'following\n' + ' the star subpattern.\n' + '\n' + ' 4. Remaining non-star subpatterns are matched to their\n' + ' corresponding subject items, as for a fixed-length ' + 'sequence.\n' + '\n' + ' Note:\n' + '\n' + ' The length of the subject sequence is obtained via "len()" ' + '(i.e.\n' + ' via the "__len__()" protocol). This length may be cached ' + 'by the\n' + ' interpreter in a similar manner as value patterns.\n' + '\n' + 'In simple terms "[P1, P2, P3," … ", P]" matches only if all ' + 'the\n' + 'following happens:\n' + '\n' + '* check "" is a sequence\n' + '\n' + '* "len(subject) == "\n' + '\n' + '* "P1" matches "[0]" (note that this match can also ' + 'bind\n' + ' names)\n' + '\n' + '* "P2" matches "[1]" (note that this match can also ' + 'bind\n' + ' names)\n' + '\n' + '* … and so on for the corresponding pattern/element.\n' + '\n' + '\n' + 'Mapping Patterns\n' + '~~~~~~~~~~~~~~~~\n' + '\n' + 'A mapping pattern contains one or more key-value patterns. The ' + 'syntax\n' + 'is similar to the construction of a dictionary. Syntax:\n' + '\n' + ' mapping_pattern ::= "{" [items_pattern] "}"\n' + ' items_pattern ::= ",".key_value_pattern+ ","?\n' + ' key_value_pattern ::= (literal_pattern | value_pattern) ":" ' + 'pattern\n' + ' | double_star_pattern\n' + ' double_star_pattern ::= "**" capture_pattern\n' + '\n' + 'At most one double star pattern may be in a mapping pattern. ' + 'The\n' + 'double star pattern must be the last subpattern in the mapping\n' + 'pattern.\n' + '\n' + 'Duplicate keys in mapping patterns are disallowed. Duplicate ' + 'literal\n' + 'keys will raise a "SyntaxError". Two keys that otherwise have ' + 'the same\n' + 'value will raise a "ValueError" at runtime.\n' + '\n' + 'The following is the logical flow for matching a mapping ' + 'pattern\n' + 'against a subject value:\n' + '\n' + '1. If the subject value is not a mapping [3],the mapping ' + 'pattern\n' + ' fails.\n' + '\n' + '2. If every key given in the mapping pattern is present in the ' + 'subject\n' + ' mapping, and the pattern for each key matches the ' + 'corresponding\n' + ' item of the subject mapping, the mapping pattern succeeds.\n' + '\n' + '3. If duplicate keys are detected in the mapping pattern, the ' + 'pattern\n' + ' is considered invalid. A "SyntaxError" is raised for ' + 'duplicate\n' + ' literal values; or a "ValueError" for named keys of the same ' + 'value.\n' + '\n' + 'Note:\n' + '\n' + ' Key-value pairs are matched using the two-argument form of ' + 'the\n' + ' mapping subject’s "get()" method. Matched key-value pairs ' + 'must\n' + ' already be present in the mapping, and not created on-the-fly ' + 'via\n' + ' "__missing__()" or "__getitem__()".\n' + '\n' + 'In simple terms "{KEY1: P1, KEY2: P2, ... }" matches only if all ' + 'the\n' + 'following happens:\n' + '\n' + '* check "" is a mapping\n' + '\n' + '* "KEY1 in "\n' + '\n' + '* "P1" matches "[KEY1]"\n' + '\n' + '* … and so on for the corresponding KEY/pattern pair.\n' + '\n' + '\n' + 'Class Patterns\n' + '~~~~~~~~~~~~~~\n' + '\n' + 'A class pattern represents a class and its positional and ' + 'keyword\n' + 'arguments (if any). Syntax:\n' + '\n' + ' class_pattern ::= name_or_attr "(" [pattern_arguments ' + '","?] ")"\n' + ' pattern_arguments ::= positional_patterns ["," ' + 'keyword_patterns]\n' + ' | keyword_patterns\n' + ' positional_patterns ::= ",".pattern+\n' + ' keyword_patterns ::= ",".keyword_pattern+\n' + ' keyword_pattern ::= NAME "=" pattern\n' + '\n' + 'The same keyword should not be repeated in class patterns.\n' + '\n' + 'The following is the logical flow for matching a class pattern ' + 'against\n' + 'a subject value:\n' + '\n' + '1. If "name_or_attr" is not an instance of the builtin "type" , ' + 'raise\n' + ' "TypeError".\n' + '\n' + '2. If the subject value is not an instance of "name_or_attr" ' + '(tested\n' + ' via "isinstance()"), the class pattern fails.\n' + '\n' + '3. If no pattern arguments are present, the pattern succeeds.\n' + ' Otherwise, the subsequent steps depend on whether keyword or\n' + ' positional argument patterns are present.\n' + '\n' + ' For a number of built-in types (specified below), a single\n' + ' positional subpattern is accepted which will match the ' + 'entire\n' + ' subject; for these types keyword patterns also work as for ' + 'other\n' + ' types.\n' + '\n' + ' If only keyword patterns are present, they are processed as\n' + ' follows, one by one:\n' + '\n' + ' I. The keyword is looked up as an attribute on the subject.\n' + '\n' + ' * If this raises an exception other than "AttributeError", ' + 'the\n' + ' exception bubbles up.\n' + '\n' + ' * If this raises "AttributeError", the class pattern has ' + 'failed.\n' + '\n' + ' * Else, the subpattern associated with the keyword pattern ' + 'is\n' + ' matched against the subject’s attribute value. If this ' + 'fails,\n' + ' the class pattern fails; if this succeeds, the match ' + 'proceeds\n' + ' to the next keyword.\n' + '\n' + ' II. If all keyword patterns succeed, the class pattern ' + 'succeeds.\n' + '\n' + ' If any positional patterns are present, they are converted ' + 'to\n' + ' keyword patterns using the "__match_args__" attribute on the ' + 'class\n' + ' "name_or_attr" before matching:\n' + '\n' + ' I. The equivalent of "getattr(cls, "__match_args__", ())" is\n' + ' called.\n' + '\n' + ' * If this raises an exception, the exception bubbles up.\n' + '\n' + ' * If the returned value is not a tuple, the conversion ' + 'fails and\n' + ' "TypeError" is raised.\n' + '\n' + ' * If there are more positional patterns than\n' + ' "len(cls.__match_args__)", "TypeError" is raised.\n' + '\n' + ' * Otherwise, positional pattern "i" is converted to a ' + 'keyword\n' + ' pattern using "__match_args__[i]" as the keyword.\n' + ' "__match_args__[i]" must be a string; if not "TypeError" ' + 'is\n' + ' raised.\n' + '\n' + ' * If there are duplicate keywords, "TypeError" is raised.\n' + '\n' + ' See also:\n' + '\n' + ' Customizing positional arguments in class pattern ' + 'matching\n' + '\n' + ' II. Once all positional patterns have been converted to ' + 'keyword\n' + ' patterns,\n' + ' the match proceeds as if there were only keyword ' + 'patterns.\n' + '\n' + ' For the following built-in types the handling of positional\n' + ' subpatterns is different:\n' + '\n' + ' * "bool"\n' + '\n' + ' * "bytearray"\n' + '\n' + ' * "bytes"\n' + '\n' + ' * "dict"\n' + '\n' + ' * "float"\n' + '\n' + ' * "frozenset"\n' + '\n' + ' * "int"\n' + '\n' + ' * "list"\n' + '\n' + ' * "set"\n' + '\n' + ' * "str"\n' + '\n' + ' * "tuple"\n' + '\n' + ' These classes accept a single positional argument, and the ' + 'pattern\n' + ' there is matched against the whole object rather than an ' + 'attribute.\n' + ' For example "int(0|1)" matches the value "0", but not the ' + 'values\n' + ' "0.0" or "False".\n' + '\n' + 'In simple terms "CLS(P1, attr=P2)" matches only if the ' + 'following\n' + 'happens:\n' + '\n' + '* "isinstance(, CLS)"\n' + '\n' + '* convert "P1" to a keyword pattern using "CLS.__match_args__"\n' + '\n' + '* For each keyword argument "attr=P2":\n' + ' * "hasattr(, "attr")"\n' + '\n' + ' * "P2" matches ".attr"\n' + '\n' + '* … and so on for the corresponding keyword argument/pattern ' + 'pair.\n' + '\n' + 'See also:\n' + '\n' + ' * **PEP 634** – Structural Pattern Matching: Specification\n' + '\n' + ' * **PEP 636** – Structural Pattern Matching: Tutorial\n' + '\n' + '\n' 'Function definitions\n' '====================\n' '\n' @@ -2717,7 +3496,7 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'The function definition does not execute the function body; this ' 'gets\n' - 'executed only when the function is called. [2]\n' + 'executed only when the function is called. [4]\n' '\n' 'A function definition may be wrapped by one or more *decorator*\n' 'expressions. Decorator expressions are evaluated when the ' @@ -2770,17 +3549,17 @@ topics = {'assert': 'The "assert" statement\n' '“pre-\n' 'computed” value is used for each call. This is especially ' 'important\n' - 'to understand when a default parameter is a mutable object, such ' - 'as a\n' - 'list or a dictionary: if the function modifies the object (e.g. ' - 'by\n' - 'appending an item to a list), the default value is in effect ' - 'modified.\n' - 'This is generally not what was intended. A way around this is ' - 'to use\n' - '"None" as the default, and explicitly test for it in the body of ' - 'the\n' - 'function, e.g.:\n' + 'to understand when a default parameter value is a mutable ' + 'object, such\n' + 'as a list or a dictionary: if the function modifies the object ' + '(e.g.\n' + 'by appending an item to a list), the default parameter value is ' + 'in\n' + 'effect modified. This is generally not what was intended. A ' + 'way\n' + 'around this is to use "None" as the default, and explicitly test ' + 'for\n' + 'it in the body of the function, e.g.:\n' '\n' ' def whats_on_the_telly(penguin=None):\n' ' if penguin is None:\n' @@ -2922,7 +3701,7 @@ topics = {'assert': 'The "assert" statement\n' 'function definitions.) When the class’s suite finishes ' 'execution, its\n' 'execution frame is discarded but its local namespace is saved. ' - '[3] A\n' + '[5] A\n' 'class object is then created using the inheritance list for the ' 'base\n' 'classes and the saved local namespace for the attribute ' @@ -3007,12 +3786,9 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'Execution of Python coroutines can be suspended and resumed at ' 'many\n' - 'points (see *coroutine*). Inside the body of a coroutine ' - 'function,\n' - '"await" and "async" identifiers become reserved keywords; ' - '"await"\n' - 'expressions, "async for" and "async with" can only be used in\n' - 'coroutine function bodies.\n' + 'points (see *coroutine*). "await" expressions, "async for" and ' + '"async\n' + 'with" can only be used in the body of a coroutine function.\n' '\n' 'Functions defined with "async def" syntax are always coroutine\n' 'functions, even if they do not contain "await" or "async" ' @@ -3028,6 +3804,10 @@ topics = {'assert': 'The "assert" statement\n' ' do_stuff()\n' ' await some_coroutine()\n' '\n' + 'Changed in version 3.7: "await" and "async" are now keywords;\n' + 'previously they were only treated as such inside the body of a\n' + 'coroutine function.\n' + '\n' '\n' 'The "async for" statement\n' '-------------------------\n' @@ -3125,13 +3905,65 @@ topics = {'assert': 'The "assert" statement\n' 'exception.\n' ' That new exception causes the old one to be lost.\n' '\n' - '[2] A string literal appearing as the first statement in the ' + '[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' - '[3] A string literal appearing as the first statement in the ' + '[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', @@ -4637,20 +5469,32 @@ topics = {'assert': 'The "assert" statement\n' 'binding\n' 'operations.\n' '\n' - 'The following constructs bind names: formal parameters to ' - 'functions,\n' - '"import" statements, class and function definitions (these bind ' - 'the\n' - 'class or function name in the defining block), and targets that ' - 'are\n' - 'identifiers if occurring in an assignment, "for" loop header, ' - 'or after\n' - '"as" in a "with" statement or "except" clause. The "import" ' - 'statement\n' - 'of the form "from ... import *" binds all names defined in the\n' - 'imported module, except those beginning with an underscore. ' - 'This form\n' - 'may only be used at the module level.\n' + 'The following constructs bind names:\n' + '\n' + '* formal parameters to functions,\n' + '\n' + '* class definitions,\n' + '\n' + '* function definitions,\n' + '\n' + '* assignment expressions,\n' + '\n' + '* targets that are identifiers if occurring in an assignment:\n' + '\n' + ' * "for" loop header,\n' + '\n' + ' * after "as" in a "with" statement, "except" clause or in the ' + 'as-\n' + ' pattern in structural pattern matching,\n' + '\n' + ' * in a capture pattern in structural pattern matching\n' + '\n' + '* "import" statements.\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' + 'underscore. This form may only be used at the module level.\n' '\n' 'A target occurring in a "del" statement is also considered ' 'bound for\n' @@ -5031,30 +5875,7 @@ topics = {'assert': 'The "assert" statement\n' 'all by the loop. Hint: the built-in function "range()" returns an\n' 'iterator of integers suitable to emulate the effect of Pascal’s "for ' 'i\n' - ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n' - '\n' - 'Note:\n' - '\n' - ' There is a subtlety when the sequence is being modified by the ' - 'loop\n' - ' (this can only occur for mutable sequences, e.g. lists). An\n' - ' internal counter is used to keep track of which item is used next,\n' - ' and this is incremented on each iteration. When this counter has\n' - ' reached the length of the sequence the loop terminates. This ' - 'means\n' - ' that if the suite deletes the current (or a previous) item from ' - 'the\n' - ' sequence, the next item will be skipped (since it gets the index ' - 'of\n' - ' the current item which has already been treated). Likewise, if ' - 'the\n' - ' suite inserts an item in the sequence before the current item, the\n' - ' current item will be treated again the next time through the loop.\n' - ' This can lead to nasty bugs that can be avoided by making a\n' - ' temporary copy using a slice of the whole sequence, e.g.,\n' - '\n' - ' for x in a[:]:\n' - ' if x < 0: a.remove(x)\n', + ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n', 'formatstrings': 'Format String Syntax\n' '********************\n' '\n' @@ -5300,9 +6121,9 @@ topics = {'assert': 'The "assert" statement\n' ' | | in the form ‘+000000120’. This alignment ' 'option is only |\n' ' | | valid for numeric types. It becomes the ' - 'default when ‘0’ |\n' - ' | | immediately precedes the field ' - 'width. |\n' + 'default for |\n' + ' | | numbers when ‘0’ immediately precedes the ' + 'field width. |\n' ' ' '+-----------+------------------------------------------------------------+\n' ' | "\'^\'" | Forces the field to be centered within ' @@ -5410,6 +6231,10 @@ topics = {'assert': 'The "assert" statement\n' 'with an\n' '*alignment* type of "\'=\'".\n' '\n' + 'Changed in version 3.10: Preceding the *width* field by ' + '"\'0\'" no\n' + 'longer affects the default alignment for strings.\n' + '\n' 'The *precision* is a decimal integer indicating how many ' 'digits should\n' 'be displayed after the decimal point for presentation types ' @@ -5868,7 +6693,7 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'The function definition does not execute the function body; this ' 'gets\n' - 'executed only when the function is called. [2]\n' + 'executed only when the function is called. [4]\n' '\n' 'A function definition may be wrapped by one or more *decorator*\n' 'expressions. Decorator expressions are evaluated when the ' @@ -5921,17 +6746,17 @@ topics = {'assert': 'The "assert" statement\n' '“pre-\n' 'computed” value is used for each call. This is especially ' 'important\n' - 'to understand when a default parameter is a mutable object, such ' - 'as a\n' - 'list or a dictionary: if the function modifies the object (e.g. ' - 'by\n' - 'appending an item to a list), the default value is in effect ' - 'modified.\n' - 'This is generally not what was intended. A way around this is ' - 'to use\n' - '"None" as the default, and explicitly test for it in the body of ' - 'the\n' - 'function, e.g.:\n' + 'to understand when a default parameter value is a mutable ' + 'object, such\n' + 'as a list or a dictionary: if the function modifies the object ' + '(e.g.\n' + 'by appending an item to a list), the default parameter value is ' + 'in\n' + 'effect modified. This is generally not what was intended. A ' + 'way\n' + 'around this is to use "None" as the default, and explicitly test ' + 'for\n' + 'it in the body of the function, e.g.:\n' '\n' ' def whats_on_the_telly(penguin=None):\n' ' if penguin is None:\n' @@ -6054,8 +6879,10 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'Names listed in a "global" statement must not be defined as ' 'formal\n' - 'parameters or in a "for" loop control target, "class" definition,\n' - 'function definition, "import" statement, or variable annotation.\n' + 'parameters, or as targets in "with" statements or "except" ' + 'clauses, or\n' + 'in a "for" target list, "class" definition, function definition,\n' + '"import" statement, or variable annotation.\n' '\n' '**CPython implementation detail:** The current implementation does ' 'not\n' @@ -6087,22 +6914,31 @@ topics = {'assert': 'The "assert" statement\n' 'trailing underscore characters:\n' '\n' '"_*"\n' - ' Not imported by "from module import *". The special ' - 'identifier "_"\n' - ' is used in the interactive interpreter to store the result ' - 'of the\n' - ' last evaluation; it is stored in the "builtins" module. ' - 'When not\n' - ' in interactive mode, "_" has no special meaning and is not ' - 'defined.\n' - ' See section The import statement.\n' + ' Not imported by "from module import *".\n' + '\n' + '"_"\n' + ' In a "case" pattern within a "match" statement, "_" is a ' + 'soft\n' + ' keyword that denotes a wildcard.\n' + '\n' + ' Separately, the interactive interpreter makes the result of ' + 'the\n' + ' last evaluation available in the variable "_". (It is ' + 'stored in the\n' + ' "builtins" module, alongside built-in functions like ' + '"print".)\n' + '\n' + ' Elsewhere, "_" is a regular identifier. It is often used to ' + 'name\n' + ' “special” items, but it is not special to Python itself.\n' '\n' ' Note:\n' '\n' ' The name "_" is often used in conjunction with\n' ' internationalization; refer to the documentation for the\n' ' "gettext" module for more information on this ' - 'convention.\n' + 'convention.It is\n' + ' also commonly used for unused variables.\n' '\n' '"__*__"\n' ' System-defined names, informally known as “dunder” names. ' @@ -6225,6 +7061,28 @@ topics = {'assert': 'The "assert" statement\n' ' async elif if or yield\n' '\n' '\n' + 'Soft Keywords\n' + '=============\n' + '\n' + 'New in version 3.10.\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' + '\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' + '\n' + '\n' 'Reserved classes of identifiers\n' '===============================\n' '\n' @@ -6235,15 +7093,23 @@ topics = {'assert': 'The "assert" statement\n' 'trailing underscore characters:\n' '\n' '"_*"\n' - ' Not imported by "from module import *". The special ' - 'identifier "_"\n' - ' is used in the interactive interpreter to store the result ' + ' Not imported by "from module import *".\n' + '\n' + '"_"\n' + ' In a "case" pattern within a "match" statement, "_" is a ' + 'soft\n' + ' keyword that denotes a wildcard.\n' + '\n' + ' Separately, the interactive interpreter makes the result ' 'of the\n' - ' last evaluation; it is stored in the "builtins" module. ' - 'When not\n' - ' in interactive mode, "_" has no special meaning and is not ' - 'defined.\n' - ' See section The import statement.\n' + ' last evaluation available in the variable "_". (It is ' + 'stored in the\n' + ' "builtins" module, alongside built-in functions like ' + '"print".)\n' + '\n' + ' Elsewhere, "_" is a regular identifier. It is often used ' + 'to name\n' + ' “special” items, but it is not special to Python itself.\n' '\n' ' Note:\n' '\n' @@ -6251,7 +7117,8 @@ topics = {'assert': 'The "assert" statement\n' ' internationalization; refer to the documentation for ' 'the\n' ' "gettext" module for more information on this ' - 'convention.\n' + 'convention.It is\n' + ' also commonly used for unused variables.\n' '\n' '"__*__"\n' ' System-defined names, informally known as “dunder” names. ' @@ -6712,20 +7579,32 @@ topics = {'assert': 'The "assert" statement\n' '*Names* refer to objects. Names are introduced by name binding\n' 'operations.\n' '\n' - 'The following constructs bind names: formal parameters to ' - 'functions,\n' - '"import" statements, class and function definitions (these bind ' - 'the\n' - 'class or function name in the defining block), and targets that ' - 'are\n' - 'identifiers if occurring in an assignment, "for" loop header, or ' - 'after\n' - '"as" in a "with" statement or "except" clause. The "import" ' - 'statement\n' - 'of the form "from ... import *" binds all names defined in the\n' - 'imported module, except those beginning with an underscore. This ' - 'form\n' - 'may only be used at the module level.\n' + 'The following constructs bind names:\n' + '\n' + '* formal parameters to functions,\n' + '\n' + '* class definitions,\n' + '\n' + '* function definitions,\n' + '\n' + '* assignment expressions,\n' + '\n' + '* targets that are identifiers if occurring in an assignment:\n' + '\n' + ' * "for" loop header,\n' + '\n' + ' * after "as" in a "with" statement, "except" clause or in the ' + 'as-\n' + ' pattern in structural pattern matching,\n' + '\n' + ' * in a capture pattern in structural pattern matching\n' + '\n' + '* "import" statements.\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' + 'underscore. This form may only be used at the module level.\n' '\n' 'A target occurring in a "del" statement is also considered bound ' 'for\n' @@ -7092,16 +7971,6 @@ topics = {'assert': 'The "assert" statement\n' 'the data\n' ' model.\n' '\n' - ' Note:\n' - '\n' - ' Due to a bug in the dispatching mechanism for "**=", a ' - 'class that\n' - ' defines "__ipow__()" but returns "NotImplemented" ' - 'would fail to\n' - ' fall back to "x.__pow__(y)" and "y.__rpow__(x)". This ' - 'bug is\n' - ' fixed in Python 3.10.\n' - '\n' 'object.__neg__(self)\n' 'object.__pos__(self)\n' 'object.__abs__(self)\n' @@ -7851,19 +8720,13 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'object.__iter__(self)\n' '\n' - ' This method is called when an iterator is required for ' - 'a container.\n' - ' This method should return a new iterator object that ' - 'can iterate\n' - ' over all the objects in the container. For mappings, ' - 'it should\n' - ' iterate over the keys of the container.\n' - '\n' - ' Iterator objects also need to implement this method; ' - 'they are\n' - ' required to return themselves. For more information on ' - 'iterator\n' - ' objects, see Iterator Types.\n' + ' This method is called when an *iterator* is required ' + 'for a\n' + ' container. This method should return a new iterator ' + 'object that can\n' + ' iterate over all the objects in the container. For ' + 'mappings, it\n' + ' should iterate over the keys of the container.\n' '\n' 'object.__reversed__(self)\n' '\n' @@ -8820,32 +9683,6 @@ topics = {'assert': 'The "assert" statement\n' 'of the\n' ' owner class.\n' '\n' - 'object.__set_name__(self, owner, name)\n' - '\n' - ' Called at the time the owning class *owner* is created. ' - 'The\n' - ' descriptor has been assigned to *name*.\n' - '\n' - ' Note:\n' - '\n' - ' "__set_name__()" is only called implicitly as part of ' - 'the "type"\n' - ' constructor, so it will need to be called explicitly ' - 'with the\n' - ' appropriate parameters when a descriptor is added to a ' - 'class\n' - ' after initial creation:\n' - '\n' - ' class A:\n' - ' pass\n' - ' descr = custom_descriptor()\n' - ' A.attr = descr\n' - " descr.__set_name__(A, 'attr')\n" - '\n' - ' See Creating the class object for more details.\n' - '\n' - ' New in version 3.6.\n' - '\n' 'The attribute "__objclass__" is interpreted by the "inspect" ' 'module as\n' 'specifying the class where this object was defined (setting ' @@ -9141,6 +9978,38 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' New in version 3.6.\n' '\n' + 'When a class is created, "type.__new__()" scans the class ' + 'variables\n' + 'and makes callbacks to those with a "__set_name__()" hook.\n' + '\n' + 'object.__set_name__(self, owner, name)\n' + '\n' + ' Automatically called at the time the owning class *owner* ' + 'is\n' + ' created. The object has been assigned to *name* in that ' + 'class:\n' + '\n' + ' class A:\n' + ' x = C() # Automatically calls: x.__set_name__(A, ' + "'x')\n" + '\n' + ' If the class variable is assigned after the class is ' + 'created,\n' + ' "__set_name__()" will not be called automatically. If ' + 'needed,\n' + ' "__set_name__()" can be called directly:\n' + '\n' + ' class A:\n' + ' pass\n' + '\n' + ' c = C()\n' + ' A.x = c # The hook is not called\n' + " c.__set_name__(A, 'x') # Manually invoke the hook\n" + '\n' + ' See Creating the class object for more details.\n' + '\n' + ' New in version 3.6.\n' + '\n' '\n' 'Metaclasses\n' '-----------\n' @@ -9336,22 +10205,21 @@ topics = {'assert': 'The "assert" statement\n' 'When using the default metaclass "type", or any metaclass ' 'that\n' 'ultimately calls "type.__new__", the following additional\n' - 'customisation steps are invoked after creating the class ' + 'customization steps are invoked after creating the class ' 'object:\n' '\n' - '* first, "type.__new__" collects all of the descriptors in ' - 'the class\n' - ' namespace that define a "__set_name__()" method;\n' + '1. The "type.__new__" method collects all of the attributes ' + 'in the\n' + ' class namespace that define a "__set_name__()" method;\n' '\n' - '* second, all of these "__set_name__" methods are called ' - 'with the\n' - ' class being defined and the assigned name of that ' - 'particular\n' - ' descriptor;\n' + '2. Those "__set_name__" methods are called with the class ' + 'being\n' + ' defined and the assigned name of that particular ' + 'attribute;\n' '\n' - '* finally, the "__init_subclass__()" hook is called on the ' - 'immediate\n' - ' parent of the new class in its method resolution order.\n' + '3. The "__init_subclass__()" hook is called on the immediate ' + 'parent of\n' + ' the new class in its method resolution order.\n' '\n' 'After the class object is created, it is passed to the ' 'class\n' @@ -9814,19 +10682,13 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'object.__iter__(self)\n' '\n' - ' This method is called when an iterator is required for a ' - 'container.\n' - ' This method should return a new iterator object that can ' - 'iterate\n' - ' over all the objects in the container. For mappings, it ' - 'should\n' - ' iterate over the keys of the container.\n' - '\n' - ' Iterator objects also need to implement this method; they ' - 'are\n' - ' required to return themselves. For more information on ' - 'iterator\n' - ' objects, see Iterator Types.\n' + ' This method is called when an *iterator* is required for ' + 'a\n' + ' container. This method should return a new iterator ' + 'object that can\n' + ' iterate over all the objects in the container. For ' + 'mappings, it\n' + ' should iterate over the keys of the container.\n' '\n' 'object.__reversed__(self)\n' '\n' @@ -10019,16 +10881,6 @@ topics = {'assert': 'The "assert" statement\n' 'the data\n' ' model.\n' '\n' - ' Note:\n' - '\n' - ' Due to a bug in the dispatching mechanism for "**=", a ' - 'class that\n' - ' defines "__ipow__()" but returns "NotImplemented" would ' - 'fail to\n' - ' fall back to "x.__pow__(y)" and "y.__rpow__(x)". This ' - 'bug is\n' - ' fixed in Python 3.10.\n' - '\n' 'object.__neg__(self)\n' 'object.__pos__(self)\n' 'object.__abs__(self)\n' @@ -10147,6 +10999,51 @@ topics = {'assert': 'The "assert" statement\n' ' statement.\n' '\n' '\n' + 'Customizing positional arguments in class pattern matching\n' + '==========================================================\n' + '\n' + 'When using a class name in a pattern, positional arguments ' + 'in the\n' + 'pattern are not allowed by default, i.e. "case MyClass(x, ' + 'y)" is\n' + 'typically invalid without special support in "MyClass". To ' + 'be able to\n' + 'use that kind of patterns, the class needs to define a\n' + '*__match_args__* attribute.\n' + '\n' + 'object.__match_args__\n' + '\n' + ' This class variable can be assigned a tuple of strings. ' + 'When this\n' + ' class is used in a class pattern with positional ' + 'arguments, each\n' + ' positional argument will be converted into a keyword ' + 'argument,\n' + ' using the corresponding value in *__match_args__* as the ' + 'keyword.\n' + ' The absence of this attribute is equivalent to setting it ' + 'to "()".\n' + '\n' + 'For example, if "MyClass.__match_args__" is "("left", ' + '"center",\n' + '"right")" that means that "case MyClass(x, y)" is equivalent ' + 'to "case\n' + 'MyClass(left=x, center=y)". Note that the number of ' + 'arguments in the\n' + 'pattern must be smaller than or equal to the number of ' + 'elements in\n' + '*__match_args__*; if it is larger, the pattern match attempt ' + 'will\n' + 'raise a "TypeError".\n' + '\n' + 'New in version 3.10.\n' + '\n' + 'See also:\n' + '\n' + ' **PEP 634** - Structural Pattern Matching\n' + ' The specification for the Python "match" statement.\n' + '\n' + '\n' 'Special method lookup\n' '=====================\n' '\n' @@ -10317,7 +11214,7 @@ topics = {'assert': 'The "assert" statement\n' '*start* and\n' ' *end* are interpreted as in slice notation.\n' '\n' - 'str.encode(encoding="utf-8", errors="strict")\n' + "str.encode(encoding='utf-8', errors='strict')\n" '\n' ' Return an encoded version of the string as a bytes ' 'object. Default\n' @@ -10823,7 +11720,7 @@ topics = {'assert': 'The "assert" statement\n' 'followed by\n' ' the string itself.\n' '\n' - 'str.rsplit(sep=None, maxsplit=-1)\n' + 'str.rsplit(sep=None, maxsplit=- 1)\n' '\n' ' Return a list of the words in the string, using *sep* ' 'as the\n' @@ -10864,7 +11761,7 @@ topics = {'assert': 'The "assert" statement\n' " >>> 'Monty Python'.removesuffix(' Python')\n" " 'Monty'\n" '\n' - 'str.split(sep=None, maxsplit=-1)\n' + 'str.split(sep=None, maxsplit=- 1)\n' '\n' ' Return a list of the words in the string, using *sep* ' 'as the\n' @@ -11593,9 +12490,31 @@ topics = {'assert': 'The "assert" statement\n' '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. "sys.exc_info()" values are\n' - 'restored to their previous values (before the call) when returning\n' - 'from a function that handled an exception.\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' + '\n' + ' >>> print(sys.exc_info())\n' + ' (None, None, None)\n' + ' >>> try:\n' + ' ... raise TypeError\n' + ' ... except:\n' + ' ... print(sys.exc_info())\n' + ' ... try:\n' + ' ... raise ValueError\n' + ' ... except:\n' + ' ... print(sys.exc_info())\n' + ' ... print(sys.exc_info())\n' + ' ...\n' + " (, TypeError(), )\n' + " (, ValueError(), )\n' + " (, TypeError(), )\n' + ' >>> print(sys.exc_info())\n' + ' (None, None, None)\n' '\n' 'The optional "else" clause is executed if the control flow leaves ' 'the\n' @@ -11855,7 +12774,7 @@ topics = {'assert': 'The "assert" statement\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' + '*char*\n' ' type; instead, every code point in the string is ' 'represented\n' ' as a string object with length "1". The built-in ' @@ -12115,7 +13034,13 @@ topics = {'assert': 'The "assert" statement\n' '| |\n' ' | | and "\'return\'" for the ' 'return | |\n' - ' | | annotation, if provided. ' + ' | | annotation, if provided. For ' + '| |\n' + ' | | more information on working ' + '| |\n' + ' | | with this attribute, see ' + '| |\n' + ' | | Annotations Best Practices. ' '| |\n' ' ' '+---------------------------+---------------------------------+-------------+\n' @@ -12236,20 +13161,18 @@ topics = {'assert': 'The "assert" statement\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 ' - 'object\n' - ' which can be used to execute the body of the function: ' - 'calling\n' - ' the iterator’s "iterator.__next__()" method will cause the\n' - ' function to execute until it provides a value using the ' - '"yield"\n' - ' statement. When the function executes a "return" statement ' - 'or\n' - ' falls off the end, a "StopIteration" exception is raised and ' - 'the\n' - ' iterator will have reached the end of the set of values to ' - 'be\n' - ' returned.\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 ' + 'of\n' + ' values to be returned.\n' '\n' ' Coroutine functions\n' ' A function or method which is defined using "async def" is\n' @@ -12265,9 +13188,9 @@ topics = {'assert': 'The "assert" statement\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 ' - 'for"\n' - ' statement to execute the body of the function.\n' + ' *asynchronous iterator* object which can be used in an ' + '"async\n' + ' for" statement to execute the body of the function.\n' '\n' ' Calling the asynchronous iterator’s "aiterator.__anext__" ' 'method\n' @@ -12340,20 +13263,34 @@ topics = {'assert': 'The "assert" statement\n' ' Attribute assignment updates the module’s namespace dictionary,\n' ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' '\n' - ' Predefined (writable) attributes: "__name__" is the module’s ' - 'name;\n' - ' "__doc__" is the module’s documentation string, or "None" if\n' - ' unavailable; "__annotations__" (optional) is a dictionary\n' - ' containing *variable annotations* collected during module body\n' - ' execution; "__file__" is the pathname of the file from which ' + ' Predefined (writable) attributes:\n' + '\n' + ' "__name__"\n' + ' The module’s name.\n' + '\n' + ' "__doc__"\n' + ' The module’s documentation string, or "None" if ' + 'unavailable.\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' - ' module was loaded, if it was loaded from a file. The "__file__"\n' - ' attribute may be missing for certain types of modules, such as ' - 'C\n' - ' modules that are statically linked into the interpreter; for\n' - ' extension modules loaded dynamically from a shared library, it ' - 'is\n' - ' the pathname of the shared library file.\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' @@ -12411,20 +13348,31 @@ topics = {'assert': 'The "assert" statement\n' 'instance\n' ' (see below).\n' '\n' - ' Special attributes: "__name__" is the class name; "__module__" ' - 'is\n' - ' the module name in which the class was defined; "__dict__" is ' - 'the\n' - ' dictionary containing the class’s namespace; "__bases__" is a ' - 'tuple\n' - ' containing the base classes, in the order of their occurrence ' - 'in\n' - ' the base class list; "__doc__" is the class’s documentation ' - 'string,\n' - ' or "None" if undefined; "__annotations__" (optional) is a\n' - ' dictionary containing *variable annotations* collected during ' - 'class\n' - ' body execution.\n' + ' Special attributes:\n' + '\n' + ' "__name__"\n' + ' The class name.\n' + '\n' + ' "__module__"\n' + ' The name of the module in which the class was defined.\n' + '\n' + ' "__dict__"\n' + ' The dictionary containing the class’s namespace.\n' + '\n' + ' "__bases__"\n' + ' A tuple containing the base classes, in the order of ' + 'their\n' + ' occurrence in the base class list.\n' + '\n' + ' "__doc__"\n' + ' The class’s documentation string, or "None" if undefined.\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 ' @@ -12725,9 +13673,8 @@ topics = {'assert': 'The "assert" statement\n' ' object actually returned is the wrapped object, which is not\n' ' subject to any further transformation. Static method objects ' 'are\n' - ' not themselves callable, although the objects they wrap ' - 'usually\n' - ' are. Static method objects are created by the built-in\n' + ' also callable. Static method objects are created by the ' + 'built-in\n' ' "staticmethod()" constructor.\n' '\n' ' Class method objects\n' @@ -13192,6 +14139,14 @@ topics = {'assert': 'The "assert" statement\n' ' Changed in version 3.8: Dictionary views are now ' 'reversible.\n' '\n' + 'dictview.mapping\n' + '\n' + ' Return a "types.MappingProxyType" that wraps the ' + 'original\n' + ' dictionary to which the view refers.\n' + '\n' + ' New in version 3.10.\n' + '\n' 'Keys views are set-like since their entries are unique and ' 'hashable.\n' 'If all values are hashable, so that "(key, value)" pairs are ' @@ -13237,7 +14192,15 @@ topics = {'assert': 'The "assert" statement\n' " >>> keys & {'eggs', 'bacon', 'salad'}\n" " {'bacon'}\n" " >>> keys ^ {'sausage', 'juice'}\n" - " {'juice', 'sausage', 'bacon', 'spam'}\n", + " {'juice', 'sausage', 'bacon', 'spam'}\n" + '\n' + ' >>> # get back a read-only proxy for the original ' + 'dictionary\n' + ' >>> values.mapping\n' + " mappingproxy({'eggs': 2, 'sausage': 1, 'bacon': 1, " + "'spam': 500})\n" + " >>> values.mapping['spam']\n" + ' 500\n', 'typesmethods': 'Methods\n' '*******\n' '\n' @@ -13432,6 +14395,14 @@ topics = {'assert': 'The "assert" statement\n' 'Comparisons in\n' 'the language reference.)\n' '\n' + 'Forward and reversed iterators over mutable sequences access ' + 'values\n' + 'using an index. That index will continue to march forward (or\n' + 'backward) even if the underlying sequence is mutated. The ' + 'iterator\n' + 'terminates only when an "IndexError" or a "StopIteration" is\n' + 'encountered (or when the index drops below zero).\n' + '\n' 'Notes:\n' '\n' '1. While the "in" and "not in" operations are used only for ' @@ -14244,8 +15215,10 @@ topics = {'assert': 'The "assert" statement\n' 'usage\n' 'patterns to be encapsulated for convenient reuse.\n' '\n' - ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' - ' with_item ::= expression ["as" target]\n' + ' with_stmt ::= "with" ( "(" with_stmt_contents ","? ")" | ' + 'with_stmt_contents ) ":" suite\n' + ' with_stmt_contents ::= with_item ("," with_item)*\n' + ' with_item ::= expression ["as" target]\n' '\n' 'The execution of the "with" statement with one “item” proceeds as\n' 'follows:\n' @@ -14331,8 +15304,20 @@ topics = {'assert': 'The "assert" statement\n' ' with B() as b:\n' ' SUITE\n' '\n' + 'You can also write multi-item context managers in multiple lines if\n' + 'the items are surrounded by parentheses. For example:\n' + '\n' + ' with (\n' + ' A() as a,\n' + ' B() as b,\n' + ' ):\n' + ' SUITE\n' + '\n' 'Changed in version 3.1: Support for multiple context expressions.\n' '\n' + 'Changed in version 3.10: Support for using grouping parentheses to\n' + 'break the statement in multiple lines.\n' + '\n' 'See also:\n' '\n' ' **PEP 343** - The “with” statement\n' diff --git a/contrib/tools/python3/src/Lib/random.py b/contrib/tools/python3/src/Lib/random.py index 1d4b5eb36f1..1310a2d9d0e 100644 --- a/contrib/tools/python3/src/Lib/random.py +++ b/contrib/tools/python3/src/Lib/random.py @@ -48,9 +48,10 @@ General notes on the underlying Mersenne Twister core generator: 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 +from math import tau as TWOPI, floor as _floor, isfinite as _isfinite from os import urandom as _urandom from _collections_abc import Set as _Set, Sequence as _Sequence +from operator import index as _index from itertools import accumulate as _accumulate, repeat as _repeat from bisect import bisect as _bisect import os as _os @@ -96,6 +97,7 @@ LOG4 = _log(4.0) SG_MAGICCONST = 1.0 + _log(4.5) BPF = 53 # Number of bits in a float RECIP_BPF = 2 ** -BPF +_ONE = 1 class Random(_random.Random): @@ -287,7 +289,7 @@ class Random(_random.Random): ## -------------------- integer methods ------------------- - def randrange(self, start, stop=None, step=1): + def randrange(self, start, stop=None, step=_ONE): """Choose a random item from range(start, stop[, step]). This fixes the problem with randint() which includes the @@ -297,38 +299,68 @@ class Random(_random.Random): # This code is a bit messy to make it fast for the # common case while still doing adequate error checking. - istart = int(start) - if istart != start: - raise ValueError("non-integer arg 1 for randrange()") + 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) 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') if istart > 0: return self._randbelow(istart) raise ValueError("empty range for randrange()") # stop argument supplied. - istop = int(stop) - if istop != stop: - raise ValueError("non-integer stop for randrange()") + 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) width = istop - istart - if step == 1 and width > 0: - return istart + self._randbelow(width) - if step == 1: + 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) + # 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)) # Non-unit step argument supplied. - istep = int(step) - if istep != step: - raise ValueError("non-integer step for randrange()") if istep > 0: n = (width + istep - 1) // istep elif istep < 0: n = (width + istep + 1) // istep else: raise ValueError("zero step for randrange()") - if n <= 0: raise ValueError("empty range for randrange()") - return istart + istep * self._randbelow(n) def randint(self, a, b): @@ -424,13 +456,14 @@ class Random(_random.Random): # too many calls to _randbelow(), making them slower and # causing them to eat more entropy than necessary. - if isinstance(population, _Set): - _warn('Sampling from a set deprecated\n' - 'since Python 3.9 and will be removed in a subsequent version.', - DeprecationWarning, 2) - population = tuple(population) if not isinstance(population, _Sequence): - raise TypeError("Population must be a sequence. For dicts or sets, use sorted(d).") + if isinstance(population, _Set): + _warn('Sampling from a set deprecated\n' + 'since Python 3.9 and will be removed in a subsequent version.', + DeprecationWarning, 2) + population = tuple(population) + else: + raise TypeError("Population must be a sequence. For dicts or sets, use sorted(d).") n = len(population) if counts is not None: cum_counts = list(_accumulate(counts)) @@ -500,6 +533,8 @@ class Random(_random.Random): total = cum_weights[-1] + 0.0 # convert to float if total <= 0.0: raise ValueError('Total of weights must be greater than zero') + if not _isfinite(total): + raise ValueError('Total of weights must be finite') bisect = _bisect hi = n - 1 return [population[bisect(cum_weights, random() * total, 0, hi)] @@ -690,7 +725,7 @@ class Random(_random.Random): bbb = alpha - LOG4 ccc = alpha + ainv - while 1: + while True: u1 = random() if not 1e-7 < u1 < 0.9999999: continue @@ -757,7 +792,7 @@ class Random(_random.Random): # Jain, pg. 495 u = 1.0 - self.random() - return 1.0 / u ** (1.0 / alpha) + return u ** (-1.0 / alpha) def weibullvariate(self, alpha, beta): """Weibull distribution. @@ -853,7 +888,7 @@ def _test_generator(n, func, args): from time import perf_counter t0 = perf_counter() - data = [func(*args) for i in range(n)] + data = [func(*args) for i in _repeat(None, n)] t1 = perf_counter() xbar = mean(data) diff --git a/contrib/tools/python3/src/Lib/re.py b/contrib/tools/python3/src/Lib/re.py index bfb7b1ccd93..1d82b500639 100644 --- a/contrib/tools/python3/src/Lib/re.py +++ b/contrib/tools/python3/src/Lib/re.py @@ -176,7 +176,6 @@ class RegexFlag(enum.IntFlag): res = f'~{res}' return res __str__ = object.__str__ - globals().update(RegexFlag.__members__) # sre exception diff --git a/contrib/tools/python3/src/Lib/rlcompleter.py b/contrib/tools/python3/src/Lib/rlcompleter.py index 923f5c05411..98b7930b32f 100644 --- a/contrib/tools/python3/src/Lib/rlcompleter.py +++ b/contrib/tools/python3/src/Lib/rlcompleter.py @@ -31,6 +31,7 @@ Notes: import atexit import builtins +import inspect import __main__ __all__ = ["Completer"] @@ -96,7 +97,13 @@ class Completer: def _callable_postfix(self, val, word): if callable(val): - word = word + "(" + word += "(" + try: + if not inspect.signature(val).parameters: + word += ")" + except ValueError: + pass + return word def global_matches(self, text): diff --git a/contrib/tools/python3/src/Lib/runpy.py b/contrib/tools/python3/src/Lib/runpy.py index 7e1e1ac5dde..caba1214262 100644 --- a/contrib/tools/python3/src/Lib/runpy.py +++ b/contrib/tools/python3/src/Lib/runpy.py @@ -16,7 +16,6 @@ import importlib.util import io import types import os -from pkgutil import read_code, get_importer __all__ = [ "run_module", "run_path", @@ -233,6 +232,7 @@ def _get_main_module_details(error=ImportError): def _get_code_from_file(run_name, fname): # Check for a compiled file first + from pkgutil import read_code decoded_path = os.path.abspath(os.fsdecode(fname)) with io.open_code(decoded_path) as f: code = read_code(f) @@ -255,6 +255,7 @@ def run_path(path_name, init_globals=None, run_name=None): if run_name is None: run_name = "" 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 diff --git a/contrib/tools/python3/src/Lib/sched.py b/contrib/tools/python3/src/Lib/sched.py index ff87874a3a4..14613cf2987 100644 --- a/contrib/tools/python3/src/Lib/sched.py +++ b/contrib/tools/python3/src/Lib/sched.py @@ -26,23 +26,19 @@ has another way to reference private data (besides global variables). import time import heapq from collections import namedtuple +from itertools import count import threading from time import monotonic as _time __all__ = ["scheduler"] -class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')): - __slots__ = [] - def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority) - def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority) - def __le__(s, o): return (s.time, s.priority) <= (o.time, o.priority) - def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority) - def __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority) - +Event = namedtuple('Event', 'time, priority, sequence, action, argument, kwargs') Event.time.__doc__ = ('''Numeric type compatible with the return value of the timefunc function passed to the constructor.''') Event.priority.__doc__ = ('''Events scheduled for the same time will be executed in the order of their priority.''') +Event.sequence.__doc__ = ('''A continually increasing sequence number that + separates events if time and priority are equal.''') Event.action.__doc__ = ('''Executing the event means executing action(*argument, **kwargs)''') Event.argument.__doc__ = ('''argument is a sequence holding the positional @@ -61,6 +57,7 @@ class scheduler: self._lock = threading.RLock() self.timefunc = timefunc self.delayfunc = delayfunc + self._sequence_generator = count() def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel): """Enter a new event in the queue at an absolute time. @@ -71,8 +68,10 @@ class scheduler: """ if kwargs is _sentinel: kwargs = {} - event = Event(time, priority, action, argument, kwargs) + with self._lock: + event = Event(time, priority, next(self._sequence_generator), + action, argument, kwargs) heapq.heappush(self._queue, event) return event # The ID @@ -136,7 +135,8 @@ class scheduler: with lock: if not q: break - time, priority, action, argument, kwargs = q[0] + (time, priority, sequence, action, + argument, kwargs) = q[0] now = timefunc() if time > now: delay = True diff --git a/contrib/tools/python3/src/Lib/shelve.py b/contrib/tools/python3/src/Lib/shelve.py index 5d443a0fa8d..e053c397345 100644 --- a/contrib/tools/python3/src/Lib/shelve.py +++ b/contrib/tools/python3/src/Lib/shelve.py @@ -56,7 +56,7 @@ entries in the cache, and empty the cache (d.sync() also synchronizes the persistent dictionary on disk, if feasible). """ -from pickle import Pickler, Unpickler +from pickle import DEFAULT_PROTOCOL, Pickler, Unpickler from io import BytesIO import collections.abc @@ -85,7 +85,7 @@ class Shelf(collections.abc.MutableMapping): keyencoding="utf-8"): self.dict = dict if protocol is None: - protocol = 3 + protocol = DEFAULT_PROTOCOL self._protocol = protocol self.writeback = writeback self.cache = {} diff --git a/contrib/tools/python3/src/Lib/shutil.py b/contrib/tools/python3/src/Lib/shutil.py index c048cdf9b2c..37bf98df796 100644 --- a/contrib/tools/python3/src/Lib/shutil.py +++ b/contrib/tools/python3/src/Lib/shutil.py @@ -32,16 +32,6 @@ try: except ImportError: _LZMA_SUPPORTED = False -try: - from pwd import getpwnam -except ImportError: - getpwnam = None - -try: - from grp import getgrnam -except ImportError: - getgrnam = None - _WINDOWS = os.name == 'nt' posix = nt = None if os.name == 'posix': @@ -860,8 +850,14 @@ def _is_immutable(src): def _get_gid(name): """Returns a gid, given a group name.""" - if getgrnam is None or name is None: + if name is None: + return None + + try: + from grp import getgrnam + except ImportError: return None + try: result = getgrnam(name) except KeyError: @@ -872,8 +868,14 @@ def _get_gid(name): def _get_uid(name): """Returns an uid, given a user name.""" - if getpwnam is None or name is None: + if name is None: return None + + try: + from pwd import getpwnam + except ImportError: + return None + try: result = getpwnam(name) except KeyError: diff --git a/contrib/tools/python3/src/Lib/site.py b/contrib/tools/python3/src/Lib/site.py index 19c10bc07ff..844505eb5c9 100644 --- a/contrib/tools/python3/src/Lib/site.py +++ b/contrib/tools/python3/src/Lib/site.py @@ -88,6 +88,11 @@ USER_SITE = None USER_BASE = None +def _trace(message): + if sys.flags.verbose: + print(message, file=sys.stderr) + + def makepath(*paths): dir = os.path.join(*paths) try: @@ -100,8 +105,15 @@ def makepath(*paths): def abs_paths(): """Set all module __file__ and __cached__ attributes to an absolute path""" for m in set(sys.modules.values()): - if (getattr(getattr(m, '__loader__', None), '__module__', None) not in - ('_frozen_importlib', '_frozen_importlib_external')): + loader_module = None + try: + loader_module = m.__loader__.__module__ + except AttributeError: + try: + loader_module = m.__spec__.loader.__module__ + except AttributeError: + pass + if loader_module not in {'_frozen_importlib', '_frozen_importlib_external'}: continue # don't mess with a PEP 302-supplied __file__ try: m.__file__ = os.path.abspath(m.__file__) @@ -156,14 +168,19 @@ def addpackage(sitedir, name, known_paths): else: reset = False fullname = os.path.join(sitedir, name) + _trace(f"Processing .pth file: {fullname!r}") try: - f = io.TextIOWrapper(io.open_code(fullname)) + # locale encoding is not ideal especially on Windows. But we have used + # it for a long time. setuptools uses the locale encoding too. + f = io.TextIOWrapper(io.open_code(fullname), encoding="locale") except OSError: return with f: for n, line in enumerate(f): if line.startswith("#"): continue + if line.strip() == "": + continue try: if line.startswith(("import ", "import\t")): exec(line) @@ -190,6 +207,7 @@ def addpackage(sitedir, name, known_paths): def addsitedir(sitedir, known_paths=None): """Add 'sitedir' argument to sys.path if missing and handle .pth files in 'sitedir'""" + _trace(f"Adding directory: {sitedir!r}") if known_paths is None: known_paths = _init_pathinfo() reset = True @@ -248,6 +266,10 @@ def _getuserbase(): if env_base: return env_base + # VxWorks has no home directories + if sys.platform == "vxworks": + return None + def joinuser(*args): return os.path.expanduser(os.path.join(*args)) @@ -267,7 +289,8 @@ def _get_path(userbase): version = sys.version_info if os.name == 'nt': - return f'{userbase}\\Python{version[0]}{version[1]}\\site-packages' + ver_nodot = sys.winver.replace('.', '') + return f'{userbase}\\Python{ver_nodot}\\site-packages' if sys.platform == 'darwin' and sys._framework: return f'{userbase}/lib/python/site-packages' @@ -294,11 +317,14 @@ def getusersitepackages(): If the global variable ``USER_SITE`` is not initialized yet, this function will also set it. """ - global USER_SITE + global USER_SITE, ENABLE_USER_SITE userbase = getuserbase() # this will also set USER_BASE if USER_SITE is None: - USER_SITE = _get_path(userbase) + if userbase is None: + ENABLE_USER_SITE = False # disable user site and return None + else: + USER_SITE = _get_path(userbase) return USER_SITE @@ -310,6 +336,7 @@ def addusersitepackages(known_paths): """ # get the per user site-package path # this call will also make sure USER_BASE and USER_SITE are set + _trace("Processing user site-packages") user_site = getusersitepackages() if ENABLE_USER_SITE and os.path.isdir(user_site): @@ -354,6 +381,7 @@ def getsitepackages(prefixes=None): def addsitepackages(known_paths, prefixes=None): """Add site-packages to sys.path""" + _trace("Processing global site-packages") for sitedir in getsitepackages(prefixes): if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) @@ -611,11 +639,14 @@ def _script(): for dir in sys.path: print(" %r," % (dir,)) print("]") - print("USER_BASE: %r (%s)" % (user_base, - "exists" if os.path.isdir(user_base) else "doesn't exist")) - print("USER_SITE: %r (%s)" % (user_site, - "exists" if os.path.isdir(user_site) else "doesn't exist")) - print("ENABLE_USER_SITE: %r" % ENABLE_USER_SITE) + def exists(path): + if path is not None and os.path.isdir(path): + return "exists" + else: + return "doesn't exist" + print(f"USER_BASE: {user_base!r} ({exists(user_base)})") + print(f"USER_SITE: {user_site!r} ({exists(user_site)})") + print(f"ENABLE_USER_SITE: {ENABLE_USER_SITE!r}") sys.exit(0) buffer = [] diff --git a/contrib/tools/python3/src/Lib/smtpd.py b/contrib/tools/python3/src/Lib/smtpd.py index 8f1a22e9378..963e0a7689c 100755 --- a/contrib/tools/python3/src/Lib/smtpd.py +++ b/contrib/tools/python3/src/Lib/smtpd.py @@ -83,8 +83,6 @@ import errno import getopt import time import socket -import asyncore -import asynchat import collections from warnings import warn from email._header_value_parser import get_addr_spec, get_angle_addr @@ -94,6 +92,20 @@ __all__ = [ "MailmanProxy", ] +warn( + 'The smtpd module is deprecated and unmaintained and will be removed ' + 'in Python 3.12. Please see aiosmtpd ' + '(https://aiosmtpd.readthedocs.io/) for the recommended replacement.', + DeprecationWarning, + stacklevel=2) + + +# 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' @@ -163,7 +175,7 @@ class SMTPChannel(asynchat.async_chat): # a race condition may occur if the other end is closing # before we can get the peername self.close() - if err.args[0] != errno.ENOTCONN: + if err.errno != errno.ENOTCONN: raise return print('Peer:', repr(self.peer), file=DEBUGSTREAM) diff --git a/contrib/tools/python3/src/Lib/smtplib.py b/contrib/tools/python3/src/Lib/smtplib.py index b1fd45a003d..324a1c19f12 100755 --- a/contrib/tools/python3/src/Lib/smtplib.py +++ b/contrib/tools/python3/src/Lib/smtplib.py @@ -168,7 +168,7 @@ def quotedata(data): """Quote data for email. Double leading '.', and change Unix newline '\\n', or Mac '\\r' into - Internet CRLF end-of-line. + internet CRLF end-of-line. """ return re.sub(r'(?m)^\.', '..', re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) @@ -223,7 +223,7 @@ class SMTP: helo_resp = None ehlo_msg = "ehlo" ehlo_resp = None - does_esmtp = 0 + does_esmtp = False default_port = SMTP_PORT def __init__(self, host='', port=0, local_hostname=None, @@ -459,7 +459,7 @@ class SMTP: self.ehlo_resp = msg if code != 250: return (code, msg) - self.does_esmtp = 1 + self.does_esmtp = True #parse the ehlo response -ddm assert isinstance(self.ehlo_resp, bytes), repr(self.ehlo_resp) resp = self.ehlo_resp.decode("latin-1").split('\n') @@ -797,7 +797,7 @@ class SMTP: self.helo_resp = None self.ehlo_resp = None self.esmtp_features = {} - self.does_esmtp = 0 + self.does_esmtp = False else: # RFC 3207: # 501 Syntax error (no parameters allowed) diff --git a/contrib/tools/python3/src/Lib/socket.py b/contrib/tools/python3/src/Lib/socket.py index 46fc49ca323..63ba0acc908 100755 --- a/contrib/tools/python3/src/Lib/socket.py +++ b/contrib/tools/python3/src/Lib/socket.py @@ -337,6 +337,7 @@ class socket(_socket.socket): buffer = io.BufferedWriter(raw, buffering) if binary: return buffer + encoding = io.text_encoding(encoding) text = io.TextIOWrapper(buffer, encoding, errors, newline) text.mode = mode return text @@ -377,7 +378,7 @@ class socket(_socket.socket): try: while True: if timeout and not selector_select(timeout): - raise _socket.timeout('timed out') + raise TimeoutError('timed out') if count: blocksize = count - total_sent if blocksize <= 0: @@ -706,7 +707,7 @@ class SocketIO(io.RawIOBase): self._timeout_occurred = True raise except error as e: - if e.args[0] in _blocking_errnos: + if e.errno in _blocking_errnos: return None raise @@ -722,7 +723,7 @@ class SocketIO(io.RawIOBase): return self._sock.send(b) except error as e: # XXX what about EINTR? - if e.args[0] in _blocking_errnos: + if e.errno in _blocking_errnos: return None raise diff --git a/contrib/tools/python3/src/Lib/sqlite3/__init__.py b/contrib/tools/python3/src/Lib/sqlite3/__init__.py index 1e717450c29..0dedf186b1a 100644 --- a/contrib/tools/python3/src/Lib/sqlite3/__init__.py +++ b/contrib/tools/python3/src/Lib/sqlite3/__init__.py @@ -55,3 +55,17 @@ The sqlite3 module is written by Gerhard Häring . """ from sqlite3.dbapi2 import * + + +# 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}'") diff --git a/contrib/tools/python3/src/Lib/sqlite3/dbapi2.py b/contrib/tools/python3/src/Lib/sqlite3/dbapi2.py index 991682ce9ef..cfe6225f46e 100644 --- a/contrib/tools/python3/src/Lib/sqlite3/dbapi2.py +++ b/contrib/tools/python3/src/Lib/sqlite3/dbapi2.py @@ -84,6 +84,20 @@ 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) diff --git a/contrib/tools/python3/src/Lib/ssl.py b/contrib/tools/python3/src/Lib/ssl.py index e95e4cf5e98..26f7bd0a74b 100644 --- a/contrib/tools/python3/src/Lib/ssl.py +++ b/contrib/tools/python3/src/Lib/ssl.py @@ -253,7 +253,7 @@ if sys.platform == "win32": from _ssl import enum_certificates, enum_crls from socket import socket, SOCK_STREAM, create_connection -from socket import SOL_SOCKET, SO_TYPE +from socket import SOL_SOCKET, SO_TYPE, _GLOBAL_DEFAULT_TIMEOUT import socket as _socket import base64 # for DER-to-PEM translation import errno @@ -381,6 +381,11 @@ def match_hostname(cert, hostname): 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 " @@ -493,7 +498,14 @@ class SSLContext(_SSLContext): sslsocket_class = None # SSLSocket is assigned later. sslobject_class = None # SSLObject is assigned later. - def __new__(cls, protocol=PROTOCOL_TLS, *args, **kwargs): + def __new__(cls, protocol=None, *args, **kwargs): + if protocol is None: + warnings.warn( + "ssl.SSLContext() without protocol argument is deprecated.", + category=DeprecationWarning, + stacklevel=2 + ) + protocol = PROTOCOL_TLS self = _SSLContext.__new__(cls, protocol) return self @@ -532,6 +544,11 @@ class SSLContext(_SSLContext): ) def set_npn_protocols(self, npn_protocols): + warnings.warn( + "ssl NPN is deprecated, use ALPN instead", + DeprecationWarning, + stacklevel=2 + ) protos = bytearray() for protocol in npn_protocols: b = bytes(protocol, 'ascii') @@ -752,12 +769,15 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION, # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE # by default. - context = SSLContext(PROTOCOL_TLS) - if purpose == Purpose.SERVER_AUTH: # verify certs and host name in client mode + context = SSLContext(PROTOCOL_TLS_CLIENT) context.verify_mode = CERT_REQUIRED context.check_hostname = True + elif purpose == Purpose.CLIENT_AUTH: + context = SSLContext(PROTOCOL_TLS_SERVER) + else: + raise ValueError(purpose) if cafile or capath or cadata: context.load_verify_locations(cafile, capath, cadata) @@ -773,7 +793,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, context.keylog_filename = keylogfile return context -def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE, +def _create_unverified_context(protocol=None, *, cert_reqs=CERT_NONE, check_hostname=False, purpose=Purpose.SERVER_AUTH, certfile=None, keyfile=None, cafile=None, capath=None, cadata=None): @@ -790,10 +810,18 @@ def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE, # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION, # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE # by default. - context = SSLContext(protocol) + if purpose == Purpose.SERVER_AUTH: + # verify certs and host name in client mode + if protocol is None: + protocol = PROTOCOL_TLS_CLIENT + elif purpose == Purpose.CLIENT_AUTH: + if protocol is None: + protocol = PROTOCOL_TLS_SERVER + else: + raise ValueError(purpose) - if not check_hostname: - context.check_hostname = False + context = SSLContext(protocol) + context.check_hostname = check_hostname if cert_reqs is not None: context.verify_mode = cert_reqs if check_hostname: @@ -927,15 +955,17 @@ class SSLObject: """Return the currently selected NPN protocol as a string, or ``None`` if a next protocol was not negotiated or if NPN is not supported by one of the peers.""" - if _ssl.HAS_NPN: - return self._sslobj.selected_npn_protocol() + warnings.warn( + "ssl NPN is deprecated, use ALPN instead", + DeprecationWarning, + stacklevel=2 + ) def selected_alpn_protocol(self): """Return the currently selected ALPN protocol as a string, or ``None`` if a next protocol was not negotiated or if ALPN is not supported by one of the peers.""" - if _ssl.HAS_ALPN: - return self._sslobj.selected_alpn_protocol() + return self._sslobj.selected_alpn_protocol() def cipher(self): """Return the currently selected cipher as a 3-tuple ``(name, @@ -1144,10 +1174,12 @@ class SSLSocket(socket): @_sslcopydoc def selected_npn_protocol(self): self._checkClosed() - if self._sslobj is None or not _ssl.HAS_NPN: - return None - else: - return self._sslobj.selected_npn_protocol() + warnings.warn( + "ssl NPN is deprecated, use ALPN instead", + DeprecationWarning, + stacklevel=2 + ) + return None @_sslcopydoc def selected_alpn_protocol(self): @@ -1406,7 +1438,11 @@ def wrap_socket(sock, keyfile=None, certfile=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") @@ -1484,11 +1520,14 @@ def PEM_cert_to_DER_cert(pem_cert_string): d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] return base64.decodebytes(d.encode('ASCII', 'strict')) -def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None): +def get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, + ca_certs=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): """Retrieve the certificate from the server at the specified address, and return it as a PEM-encoded string. If 'ca_certs' is specified, validate the server cert against it. - If 'ssl_version' is specified, use it in the connection attempt.""" + If 'ssl_version' is specified, use it in the connection attempt. + If 'timeout' is specified, use it in the connection attempt. + """ host, port = addr if ca_certs is not None: @@ -1498,8 +1537,8 @@ def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None): context = _create_stdlib_context(ssl_version, cert_reqs=cert_reqs, cafile=ca_certs) - with create_connection(addr) as sock: - with context.wrap_socket(sock) as sslsock: + with create_connection(addr, timeout=timeout) as sock: + with context.wrap_socket(sock, server_hostname=host) as sslsock: dercert = sslsock.getpeercert(True) return DER_cert_to_PEM_cert(dercert) diff --git a/contrib/tools/python3/src/Lib/statistics.py b/contrib/tools/python3/src/Lib/statistics.py index 463ac9e92c6..f66245380ab 100644 --- a/contrib/tools/python3/src/Lib/statistics.py +++ b/contrib/tools/python3/src/Lib/statistics.py @@ -73,6 +73,30 @@ second argument to the four "spread" functions to avoid recalculating it: 2.5 +Statistics for relations between two inputs +------------------------------------------- + +================== ==================================================== +Function Description +================== ==================================================== +covariance Sample covariance for two variables. +correlation Pearson's correlation coefficient for two variables. +linear_regression Intercept and slope for simple linear regression. +================== ==================================================== + +Calculate covariance, Pearson's correlation, and simple linear regression +for two inputs: + +>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] +>>> y = [1, 2, 3, 1, 2, 3, 1, 2, 3] +>>> covariance(x, y) +0.75 +>>> correlation(x, y) #doctest: +ELLIPSIS +0.31622776601... +>>> linear_regression(x, y) #doctest: +LinearRegression(slope=0.1, intercept=1.5) + + Exceptions ---------- @@ -83,9 +107,12 @@ A single exception is defined: StatisticsError is a subclass of ValueError. __all__ = [ 'NormalDist', 'StatisticsError', + 'correlation', + 'covariance', 'fmean', 'geometric_mean', 'harmonic_mean', + 'linear_regression', 'mean', 'median', 'median_grouped', @@ -106,11 +133,11 @@ import random from fractions import Fraction from decimal import Decimal -from itertools import groupby +from itertools import groupby, repeat from bisect import bisect_left, bisect_right from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum from operator import itemgetter -from collections import Counter +from collections import Counter, namedtuple # === Exceptions === @@ -120,21 +147,17 @@ class StatisticsError(ValueError): # === Private utilities === -def _sum(data, start=0): - """_sum(data [, start]) -> (type, sum, count) +def _sum(data): + """_sum(data) -> (type, sum, count) Return a high-precision sum of the given numeric data as a fraction, together with the type to be converted to and the count of items. - If optional argument ``start`` is given, it is added to the total. - If ``data`` is empty, ``start`` (defaulting to 0) is returned. - - Examples -------- - >>> _sum([3, 2.25, 4.5, -0.5, 1.0], 0.75) - (, Fraction(11, 1), 5) + >>> _sum([3, 2.25, 4.5, -0.5, 0.25]) + (, Fraction(19, 2), 5) Some sources of round-off error will be avoided: @@ -157,10 +180,9 @@ def _sum(data, start=0): allowed. """ count = 0 - n, d = _exact_ratio(start) - partials = {d: n} + partials = {} partials_get = partials.get - T = _coerce(int, type(start)) + T = int for typ, values in groupby(data, type): T = _coerce(T, typ) # or raise TypeError for n, d in map(_exact_ratio, values): @@ -173,8 +195,7 @@ def _sum(data, start=0): assert not _isfinite(total) else: # Sum all the partial sums using builtin sum. - # FIXME is this faster if we sum them in order of the denominator? - total = sum(Fraction(n, d) for d, n in sorted(partials.items())) + total = sum(Fraction(n, d) for d, n in partials.items()) return (T, total, count) @@ -225,27 +246,19 @@ def _exact_ratio(x): x is expected to be an int, Fraction, Decimal or float. """ try: - # Optimise the common case of floats. We expect that the most often - # used numeric type will be builtin floats, so try to make this as - # fast as possible. - if type(x) is float or type(x) is Decimal: - return x.as_integer_ratio() - try: - # x may be an int, Fraction, or Integral ABC. - return (x.numerator, x.denominator) - except AttributeError: - try: - # x may be a float or Decimal subclass. - return x.as_integer_ratio() - except AttributeError: - # Just give up? - pass + return x.as_integer_ratio() + except AttributeError: + pass except (OverflowError, ValueError): # float NAN or INF. assert not _isfinite(x) return (x, None) - msg = "can't convert type '{}' to numerator/denominator" - raise TypeError(msg.format(type(x).__name__)) + try: + # x may be an Integral ABC. + return (x.numerator, x.denominator) + except AttributeError: + msg = f"can't convert type '{type(x).__name__}' to numerator/denominator" + raise TypeError(msg) def _convert(value, T): @@ -364,37 +377,36 @@ def geometric_mean(data): 'containing positive numbers') from None -def harmonic_mean(data): +def harmonic_mean(data, weights=None): """Return the harmonic mean of data. - The harmonic mean, sometimes called the subcontrary mean, is the - reciprocal of the arithmetic mean of the reciprocals of the data, - and is often appropriate when averaging quantities which are rates - or ratios, for example speeds. Example: + The harmonic mean is the reciprocal of the arithmetic mean of the + reciprocals of the data. It can be used for averaging ratios or + rates, for example speeds. - Suppose an investor purchases an equal value of shares in each of - three companies, with P/E (price/earning) ratios of 2.5, 3 and 10. - What is the average P/E ratio for the investor's portfolio? + Suppose a car travels 40 km/hr for 5 km and then speeds-up to + 60 km/hr for another 5 km. What is the average speed? - >>> harmonic_mean([2.5, 3, 10]) # For an equal investment portfolio. - 3.6 + >>> harmonic_mean([40, 60]) + 48.0 - Using the arithmetic mean would give an average of about 5.167, which - is too high. + Suppose a car travels 40 km/hr for 5 km, and when traffic clears, + speeds-up to 60 km/hr for the remaining 30 km of the journey. What + is the average speed? + + >>> harmonic_mean([40, 60], weights=[5, 30]) + 56.0 If ``data`` is empty, or any element is less than zero, ``harmonic_mean`` will raise ``StatisticsError``. """ - # For a justification for using harmonic mean for P/E ratios, see - # http://fixthepitch.pellucid.com/comps-analysis-the-missing-harmony-of-summary-statistics/ - # http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2621087 if iter(data) is data: data = list(data) errmsg = 'harmonic mean does not support negative values' n = len(data) if n < 1: raise StatisticsError('harmonic_mean requires at least one data point') - elif n == 1: + elif n == 1 and weights is None: x = data[0] if isinstance(x, (numbers.Real, Decimal)): if x < 0: @@ -402,13 +414,23 @@ def harmonic_mean(data): return x else: raise TypeError('unsupported type') + if weights is None: + weights = repeat(1, n) + sum_weights = n + else: + if iter(weights) is weights: + weights = list(weights) + if len(weights) != n: + raise StatisticsError('Number of weights does not match data size') + _, sum_weights, _ = _sum(w for w in _fail_neg(weights, errmsg)) try: - T, total, count = _sum(1 / x for x in _fail_neg(data, errmsg)) + data = _fail_neg(data, errmsg) + T, total, count = _sum(w / x if w else 0 for w, x in zip(weights, data)) except ZeroDivisionError: return 0 - assert count == n - return _convert(n / total, T) - + if total <= 0: + raise StatisticsError('Weighted sum must be positive') + return _convert(sum_weights / total, T) # FIXME: investigate ways to calculate medians without sorting? Quickselect? def median(data): @@ -683,14 +705,20 @@ def _ss(data, c=None): if c is not None: T, total, count = _sum((x-c)**2 for x in data) return (T, total) - c = mean(data) - T, total, count = _sum((x-c)**2 for x in data) - # The following sum should mathematically equal zero, but due to rounding - # error may not. - U, total2, count2 = _sum((x - c) for x in data) - assert T == U and count == count2 - total -= total2 ** 2 / len(data) - assert not total < 0, 'negative sum of square deviations: %f' % total + T, total, count = _sum(data) + mean_n, mean_d = (total / count).as_integer_ratio() + partials = Counter() + for n, d in map(_exact_ratio, data): + diff_n = n * mean_d - d * mean_n + diff_d = d * mean_d + partials[diff_d * diff_d] += diff_n * diff_n + if None in partials: + # The sum will be a NAN or INF. We can ignore all the finite + # partials, and just look at this special one. + total = partials[None] + assert not _isfinite(total) + else: + total = sum(Fraction(n, d) for d, n in partials.items()) return (T, total) @@ -794,6 +822,9 @@ def stdev(data, xbar=None): 1.0810874155219827 """ + # Fixme: Despite the exact sum of squared deviations, some inaccuracy + # remain because there are two rounding steps. The first occurs in + # the _convert() step for variance(), the second occurs in math.sqrt(). var = variance(data, xbar) try: return var.sqrt() @@ -810,6 +841,9 @@ def pstdev(data, mu=None): 0.986893273527251 """ + # Fixme: Despite the exact sum of squared deviations, some inaccuracy + # remain because there are two rounding steps. The first occurs in + # the _convert() step for pvariance(), the second occurs in math.sqrt(). var = pvariance(data, mu) try: return var.sqrt() @@ -817,6 +851,119 @@ def pstdev(data, mu=None): return math.sqrt(var) +# === Statistics for relations between two inputs === + +# See https://en.wikipedia.org/wiki/Covariance +# https://en.wikipedia.org/wiki/Pearson_correlation_coefficient +# https://en.wikipedia.org/wiki/Simple_linear_regression + + +def covariance(x, y, /): + """Covariance + + Return the sample covariance of two inputs *x* and *y*. Covariance + is a measure of the joint variability of two inputs. + + >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] + >>> y = [1, 2, 3, 1, 2, 3, 1, 2, 3] + >>> covariance(x, y) + 0.75 + >>> z = [9, 8, 7, 6, 5, 4, 3, 2, 1] + >>> covariance(x, z) + -7.5 + >>> covariance(z, x) + -7.5 + + """ + n = len(x) + if len(y) != n: + raise StatisticsError('covariance requires that both inputs have same number of data points') + if n < 2: + 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)) + return sxy / (n - 1) + + +def correlation(x, y, /): + """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. + + >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] + >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] + >>> correlation(x, x) + 1.0 + >>> correlation(x, y) + -1.0 + + """ + 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((xi - xbar) ** 2.0 for xi in x) + syy = fsum((yi - ybar) ** 2.0 for yi in y) + try: + return sxy / sqrt(sxx * syy) + except ZeroDivisionError: + raise StatisticsError('at least one of the inputs is constant') + + +LinearRegression = namedtuple('LinearRegression', ('slope', 'intercept')) + + +def linear_regression(x, y, /): + """Slope and intercept for simple linear regression. + + Return the slope and intercept of simple linear regression + parameters estimated using ordinary least squares. Simple linear + regression describes relationship between an independent variable + *x* and a dependent variable *y* in terms of linear function: + + y = slope * x + intercept + noise + + where *slope* and *intercept* are the regression parameters that are + estimated, and noise represents the variability of the data that was + not explained by the linear regression (it is equal to the + difference between predicted and actual values of the dependent + variable). + + The parameters are returned as a named tuple. + + >>> x = [1, 2, 3, 4, 5] + >>> noise = NormalDist().samples(5, seed=42) + >>> y = [3 * x[i] + 2 + noise[i] for i in range(5)] + >>> linear_regression(x, y) #doctest: +ELLIPSIS + LinearRegression(slope=3.09078914170..., intercept=1.75684970486...) + + """ + n = len(x) + if len(y) != n: + 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') + xbar = fsum(x) / n + ybar = fsum(y) / n + sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) + sxx = fsum((xi - xbar) ** 2.0 for xi in x) + try: + slope = sxy / sxx # equivalent to: covariance(x, y) / variance(x) + except ZeroDivisionError: + raise StatisticsError('x is constant') + intercept = ybar - slope * xbar + return LinearRegression(slope=slope, intercept=intercept) + + ## Normal Distribution ##################################################### diff --git a/contrib/tools/python3/src/Lib/subprocess.py b/contrib/tools/python3/src/Lib/subprocess.py index 4effc1d8b3f..ccb46a6337b 100644 --- a/contrib/tools/python3/src/Lib/subprocess.py +++ b/contrib/tools/python3/src/Lib/subprocess.py @@ -5,7 +5,6 @@ # Copyright (c) 2003-2005 by Peter Astrand # # Licensed to PSF under a Contributor Agreement. -# See http://www.python.org/2.4/license for licensing details. r"""Subprocesses with accessible I/O streams @@ -55,13 +54,10 @@ from time import monotonic as _time import types try: - import pwd + import fcntl except ImportError: - pwd = None -try: - import grp -except ImportError: - grp = None + fcntl = None + __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", "getoutput", "check_output", "run", "CalledProcessError", "DEVNULL", @@ -326,7 +322,7 @@ def _args_from_interpreter_flags(): if dev_mode: args.extend(('-X', 'dev')) for opt in ('faulthandler', 'tracemalloc', 'importtime', - 'showrefcount', 'utf8', 'oldparser'): + 'showrefcount', 'utf8'): if opt in xoptions: value = xoptions[opt] if value is True: @@ -664,8 +660,9 @@ def _use_posix_spawn(): # os.posix_spawn() is not available return False - if sys.platform == 'darwin': - # posix_spawn() is a syscall on macOS and properly reports errors + if sys.platform in ('darwin', 'sunos5'): + # posix_spawn() is a syscall on both macOS and Solaris, + # and properly reports errors return True # Check libc name and runtime libc version @@ -697,7 +694,7 @@ def _use_posix_spawn(): _USE_POSIX_SPAWN = _use_posix_spawn() -class Popen(object): +class Popen: """ Execute a child program in a new process. For a complete description of the arguments see the Python documentation. @@ -760,7 +757,7 @@ class Popen(object): startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, user=None, group=None, extra_groups=None, - encoding=None, errors=None, text=None, umask=-1): + encoding=None, errors=None, text=None, umask=-1, pipesize=-1): """Create new Popen instance.""" _cleanup() # Held while anything is calling waitpid before returncode has been @@ -777,6 +774,11 @@ class Popen(object): if not isinstance(bufsize, int): raise TypeError("bufsize must be an integer") + if pipesize is None: + pipesize = -1 # Restore default + if not isinstance(pipesize, int): + raise TypeError("pipesize must be an integer") + if _mswindows: if preexec_fn is not None: raise ValueError("preexec_fn is not supported on Windows " @@ -801,6 +803,7 @@ class Popen(object): self.returncode = None self.encoding = encoding self.errors = errors + self.pipesize = pipesize # Validate the combinations of text and universal_newlines if (text is not None and universal_newlines is not None @@ -842,6 +845,13 @@ class Popen(object): self.text_mode = encoding or errors or text or universal_newlines + # PEP 597: We suppress the EncodingWarning in subprocess module + # for now (at Python 3.10), because we focus on files for now. + # This will be changed to encoding = io.text_encoding(encoding) + # in the future. + if self.text_mode and encoding is None: + self.encoding = encoding = "locale" + # How long to resume waiting on a child after the first ^C. # There is no right value for this. The purpose is to be polite # yet remain good for interactive users trying to exit a tool. @@ -865,7 +875,9 @@ class Popen(object): "current platform") elif isinstance(group, str): - if grp is None: + try: + import grp + except ImportError: raise ValueError("The group parameter cannot be a string " "on systems without the grp module") @@ -891,7 +903,9 @@ class Popen(object): gids = [] for extra_group in extra_groups: if isinstance(extra_group, str): - if grp is None: + try: + import grp + except ImportError: raise ValueError("Items in extra_groups cannot be " "strings on systems without the " "grp module") @@ -917,10 +931,11 @@ class Popen(object): "the current platform") elif isinstance(user, str): - if pwd is None: + try: + import pwd + except ImportError: raise ValueError("The user parameter cannot be a string " "on systems without the pwd module") - uid = pwd.getpwnam(user).pw_uid elif isinstance(user, int): uid = user @@ -1577,6 +1592,8 @@ class Popen(object): 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): @@ -1589,6 +1606,8 @@ class Popen(object): 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): @@ -1601,6 +1620,8 @@ class Popen(object): 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 diff --git a/contrib/tools/python3/src/Lib/symbol.py b/contrib/tools/python3/src/Lib/symbol.py deleted file mode 100644 index aaac8c91443..00000000000 --- a/contrib/tools/python3/src/Lib/symbol.py +++ /dev/null @@ -1,122 +0,0 @@ -"""Non-terminal symbols of Python grammar (from "graminit.h").""" - -# This file is automatically generated; please don't muck it up! -# -# To update the symbols in this file, 'cd' to the top directory of -# the python source tree after building the interpreter and run: -# -# python3 Tools/scripts/generate_symbol_py.py Include/graminit.h Lib/symbol.py -# -# or just -# -# make regen-symbol - -import warnings - -warnings.warn( - "The symbol module is deprecated and will be removed " - "in future versions of Python", - DeprecationWarning, - stacklevel=2, -) - -#--start constants-- -single_input = 256 -file_input = 257 -eval_input = 258 -decorator = 259 -decorators = 260 -decorated = 261 -async_funcdef = 262 -funcdef = 263 -parameters = 264 -typedargslist = 265 -tfpdef = 266 -varargslist = 267 -vfpdef = 268 -stmt = 269 -simple_stmt = 270 -small_stmt = 271 -expr_stmt = 272 -annassign = 273 -testlist_star_expr = 274 -augassign = 275 -del_stmt = 276 -pass_stmt = 277 -flow_stmt = 278 -break_stmt = 279 -continue_stmt = 280 -return_stmt = 281 -yield_stmt = 282 -raise_stmt = 283 -import_stmt = 284 -import_name = 285 -import_from = 286 -import_as_name = 287 -dotted_as_name = 288 -import_as_names = 289 -dotted_as_names = 290 -dotted_name = 291 -global_stmt = 292 -nonlocal_stmt = 293 -assert_stmt = 294 -compound_stmt = 295 -async_stmt = 296 -if_stmt = 297 -while_stmt = 298 -for_stmt = 299 -try_stmt = 300 -with_stmt = 301 -with_item = 302 -except_clause = 303 -suite = 304 -namedexpr_test = 305 -test = 306 -test_nocond = 307 -lambdef = 308 -lambdef_nocond = 309 -or_test = 310 -and_test = 311 -not_test = 312 -comparison = 313 -comp_op = 314 -star_expr = 315 -expr = 316 -xor_expr = 317 -and_expr = 318 -shift_expr = 319 -arith_expr = 320 -term = 321 -factor = 322 -power = 323 -atom_expr = 324 -atom = 325 -testlist_comp = 326 -trailer = 327 -subscriptlist = 328 -subscript = 329 -sliceop = 330 -exprlist = 331 -testlist = 332 -dictorsetmaker = 333 -classdef = 334 -arglist = 335 -argument = 336 -comp_iter = 337 -sync_comp_for = 338 -comp_for = 339 -comp_if = 340 -encoding_decl = 341 -yield_expr = 342 -yield_arg = 343 -func_body_suite = 344 -func_type_input = 345 -func_type = 346 -typelist = 347 -#--end constants-- - -sym_name = {} -for _name, _value in list(globals().items()): - if type(_value) is type(0): - sym_name[_value] = _name -del _name, _value diff --git a/contrib/tools/python3/src/Lib/symtable.py b/contrib/tools/python3/src/Lib/symtable.py index 521540fe9ee..98db1e2557d 100644 --- a/contrib/tools/python3/src/Lib/symtable.py +++ b/contrib/tools/python3/src/Lib/symtable.py @@ -10,6 +10,11 @@ import weakref __all__ = ["symtable", "SymbolTable", "Class", "Function", "Symbol"] def symtable(code, filename, compile_type): + """ Return the toplevel *SymbolTable* for the source code. + + *filename* is the name of the file with the code + and *compile_type* is the *compile()* mode argument. + """ top = _symtable.symtable(code, filename, compile_type) return _newSymbolTable(top, filename) @@ -55,6 +60,11 @@ class SymbolTable: self._filename) def get_type(self): + """Return the type of the symbol table. + + The values retuned are 'class', 'module' and + 'function'. + """ if self._table.type == _symtable.TYPE_MODULE: return "module" if self._table.type == _symtable.TYPE_FUNCTION: @@ -65,27 +75,51 @@ class SymbolTable: "unexpected type: {0}".format(self._table.type) def get_id(self): + """Return an identifier for the table. + """ return self._table.id def get_name(self): + """Return the table's name. + + This corresponds to the name of the class, function + or 'top' if the table is for a class, function or + global respectively. + """ return self._table.name def get_lineno(self): + """Return the number of the first line in the + block for the table. + """ return self._table.lineno def is_optimized(self): + """Return *True* if the locals in the table + are optimizable. + """ return bool(self._table.type == _symtable.TYPE_FUNCTION) def is_nested(self): + """Return *True* if the block is a nested class + or function.""" return bool(self._table.nested) def has_children(self): + """Return *True* if the block has nested namespaces. + """ return bool(self._table.children) def get_identifiers(self): + """Return a list of names of symbols in the table. + """ return self._table.symbols.keys() def lookup(self, name): + """Lookup a *name* in the table. + + Returns a *Symbol* instance. + """ sym = self._symbols.get(name) if sym is None: flags = self._table.symbols[name] @@ -96,6 +130,9 @@ class SymbolTable: return sym def get_symbols(self): + """Return a list of *Symbol* instances for + names in the table. + """ return [self.lookup(ident) for ident in self.get_identifiers()] def __check_children(self, name): @@ -104,6 +141,8 @@ class SymbolTable: if st.name == name] def get_children(self): + """Return a list of the nested symbol tables. + """ return [_newSymbolTable(st, self._filename) for st in self._table.children] @@ -122,11 +161,15 @@ class Function(SymbolTable): if test_func(self._table.symbols[ident])) def get_parameters(self): + """Return a tuple of parameters to the function. + """ if self.__params is None: self.__params = self.__idents_matching(lambda x:x & DEF_PARAM) return self.__params def get_locals(self): + """Return a tuple of locals in the function. + """ if self.__locals is None: locs = (LOCAL, CELL) test = lambda x: ((x >> SCOPE_OFF) & SCOPE_MASK) in locs @@ -134,6 +177,8 @@ class Function(SymbolTable): return self.__locals def get_globals(self): + """Return a tuple of globals in the function. + """ if self.__globals is None: glob = (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) test = lambda x:((x >> SCOPE_OFF) & SCOPE_MASK) in glob @@ -141,11 +186,15 @@ class Function(SymbolTable): return self.__globals def get_nonlocals(self): + """Return a tuple of nonlocals in the function. + """ if self.__nonlocals is None: self.__nonlocals = self.__idents_matching(lambda x:x & DEF_NONLOCAL) return self.__nonlocals def get_frees(self): + """Return a tuple of free variables in the function. + """ if self.__frees is None: is_free = lambda x:((x >> SCOPE_OFF) & SCOPE_MASK) == FREE self.__frees = self.__idents_matching(is_free) @@ -157,6 +206,8 @@ class Class(SymbolTable): __methods = None def get_methods(self): + """Return a tuple of methods declared in the class. + """ if self.__methods is None: d = {} for st in self._table.children: @@ -178,12 +229,19 @@ class Symbol: return "".format(self.__name) def get_name(self): + """Return a name of a symbol. + """ return self.__name def is_referenced(self): + """Return *True* if the symbol is used in + its block. + """ return bool(self.__flags & _symtable.USE) def is_parameter(self): + """Return *True* if the symbol is a parameter. + """ return bool(self.__flags & DEF_PARAM) def is_global(self): @@ -193,9 +251,12 @@ class Symbol: or (self.__module_scope and self.__flags & DEF_BOUND)) def is_nonlocal(self): + """Return *True* if the symbol is nonlocal.""" return bool(self.__flags & DEF_NONLOCAL) def is_declared_global(self): + """Return *True* if the symbol is declared global + with a global statement.""" return bool(self.__scope == GLOBAL_EXPLICIT) def is_local(self): @@ -205,19 +266,28 @@ class Symbol: or (self.__module_scope and self.__flags & DEF_BOUND)) def is_annotated(self): + """Return *True* if the symbol is annotated. + """ return bool(self.__flags & DEF_ANNOT) def is_free(self): + """Return *True* if a referenced symbol is + not assigned to. + """ return bool(self.__scope == FREE) def is_imported(self): + """Return *True* if the symbol is created from + an import statement. + """ return bool(self.__flags & DEF_IMPORT) def is_assigned(self): + """Return *True* if a symbol is assigned to.""" return bool(self.__flags & DEF_LOCAL) def is_namespace(self): - """Returns true if name binding introduces new namespace. + """Returns *True* if name binding introduces new namespace. If the name is used as the target of a function or class statement, this will be true. @@ -234,7 +304,7 @@ class Symbol: return self.__namespaces def get_namespace(self): - """Returns the single namespace bound to this name. + """Return the single namespace bound to this name. Raises ValueError if the name is bound to multiple namespaces. """ diff --git a/contrib/tools/python3/src/Lib/sysconfig.py b/contrib/tools/python3/src/Lib/sysconfig.py index 55bd06f3a08..8e403a7b00e 100644 --- a/contrib/tools/python3/src/Lib/sysconfig.py +++ b/contrib/tools/python3/src/Lib/sysconfig.py @@ -56,42 +56,73 @@ _INSTALL_SCHEMES = { 'scripts': '{base}/Scripts', 'data': '{base}', }, - # NOTE: When modifying "purelib" scheme, update site._get_path() too. - 'nt_user': { - 'stdlib': '{userbase}/Python{py_version_nodot}', - 'platstdlib': '{userbase}/Python{py_version_nodot}', - 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', - 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', - 'include': '{userbase}/Python{py_version_nodot}/Include', - 'scripts': '{userbase}/Python{py_version_nodot}/Scripts', - 'data': '{userbase}', - }, - 'posix_user': { - 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', - 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', - 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', - 'platlib': '{userbase}/{platlibdir}/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', - }, - 'osx_framework_user': { - 'stdlib': '{userbase}/lib/python', - 'platstdlib': '{userbase}/lib/python', - 'purelib': '{userbase}/lib/python/site-packages', - 'platlib': '{userbase}/lib/python/site-packages', - 'include': '{userbase}/include', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', - }, + } + + +# NOTE: site.py has copy of this function. +# Sync it when modify this function. +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + if env_base: + return env_base + + # VxWorks has no home directories + if sys.platform == "vxworks": + return None + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + return joinuser(base, "Python") + + if sys.platform == "darwin" and sys._framework: + return joinuser("~", "Library", sys._framework, + f"{sys.version_info[0]}.{sys.version_info[1]}") + + return joinuser("~", ".local") + +_HAS_USER_BASE = (_getuserbase() is not None) + +if _HAS_USER_BASE: + _INSTALL_SCHEMES |= { + # NOTE: When modifying "purelib" scheme, update site._get_path() too. + 'nt_user': { + 'stdlib': '{userbase}/Python{py_version_nodot_plat}', + 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', + 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', + 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', + 'include': '{userbase}/Python{py_version_nodot_plat}/Include', + 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', + 'data': '{userbase}', + }, + 'posix_user': { + 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data': '{userbase}', + }, + 'osx_framework_user': { + 'stdlib': '{userbase}/lib/python', + 'platstdlib': '{userbase}/lib/python', + 'purelib': '{userbase}/lib/python/site-packages', + 'platlib': '{userbase}/lib/python/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data': '{userbase}', + }, } _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 'scripts', 'data') _PY_VERSION = sys.version.split()[0] -_PY_VERSION_SHORT = '%d.%d' % sys.version_info[:2] -_PY_VERSION_SHORT_NO_DOT = '%d%d' % sys.version_info[:2] +_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}' +_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}' _PREFIX = os.path.normpath(sys.prefix) _BASE_PREFIX = os.path.normpath(sys.base_prefix) _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) @@ -99,6 +130,12 @@ _BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) _CONFIG_VARS = None _USER_BASE = None +# Regexes needed for parsing Makefile (and similar syntaxes, +# like old-style Setup files). +_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)" +_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)" +_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}" + def _safe_realpath(path): try: @@ -147,18 +184,24 @@ _PYTHON_BUILD = is_python_build(True) if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): - _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include' - _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.' + # On POSIX-y platforms, Python will: + # - Build from .h files in 'headers' (which is only added to the + # scheme when building CPython) + # - Install .h files to 'include' + scheme = _INSTALL_SCHEMES[scheme] + scheme['headers'] = scheme['include'] + scheme['include'] = '{srcdir}/Include' + scheme['platinclude'] = '{projectbase}/.' def _subst_vars(s, local_vars): try: return s.format(**local_vars) - except KeyError: + except KeyError as var: try: return s.format(**os.environ) - except KeyError as var: - raise AttributeError('{%s}' % var) from None + except KeyError: + raise AttributeError(f'{var}') from None def _extend_dict(target_dict, other_dict): target_keys = target_dict.keys() @@ -181,60 +224,62 @@ def _expand_vars(scheme, vars): return res -def _get_default_scheme(): - if os.name == 'posix': - # the default scheme for posix is posix_prefix - return 'posix_prefix' - return os.name - - -# NOTE: site.py has copy of this function. -# Sync it when modify this function. -def _getuserbase(): - env_base = os.environ.get("PYTHONUSERBASE", None) - if env_base: - return env_base +def _get_preferred_schemes(): + if os.name == 'nt': + return { + 'prefix': 'nt', + 'home': 'posix_home', + 'user': 'nt_user', + } + if sys.platform == 'darwin' and sys._framework: + return { + 'prefix': 'posix_prefix', + 'home': 'posix_home', + 'user': 'osx_framework_user', + } + return { + 'prefix': 'posix_prefix', + 'home': 'posix_home', + 'user': 'posix_user', + } - def joinuser(*args): - return os.path.expanduser(os.path.join(*args)) - if os.name == "nt": - base = os.environ.get("APPDATA") or "~" - return joinuser(base, "Python") +def get_preferred_scheme(key): + scheme = _get_preferred_schemes()[key] + if scheme not in _INSTALL_SCHEMES: + raise ValueError( + f"{key!r} returned {scheme!r}, which is not a valid scheme " + f"on this platform" + ) + return scheme - if sys.platform == "darwin" and sys._framework: - return joinuser("~", "Library", sys._framework, - "%d.%d" % sys.version_info[:2]) - return joinuser("~", ".local") +def get_default_scheme(): + return get_preferred_scheme('prefix') -def _parse_makefile(filename, vars=None): +def _parse_makefile(filename, vars=None, keep_unresolved=True): """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. """ - # Regexes needed for parsing Makefile (and similar syntaxes, - # like old-style Setup files). import re - _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") - _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") - _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") if vars is None: vars = {} done = {} notdone = {} - with open(filename, errors="surrogateescape") as f: + with open(filename, encoding=sys.getfilesystemencoding(), + errors="surrogateescape") as f: lines = f.readlines() for line in lines: if line.startswith('#') or line.strip() == '': continue - m = _variable_rx.match(line) + m = re.match(_variable_rx, line) if m: n, v = m.group(1, 2) v = v.strip() @@ -267,8 +312,8 @@ def _parse_makefile(filename, vars=None): while len(variables) > 0: for name in tuple(variables): value = notdone[name] - m1 = _findvar1_rx.search(value) - m2 = _findvar2_rx.search(value) + m1 = re.search(_findvar1_rx, value) + m2 = re.search(_findvar2_rx, value) if m1 and m2: m = m1 if m1.start() < m2.start() else m2 else: @@ -323,9 +368,12 @@ def _parse_makefile(filename, vars=None): done[name] = value else: + # Adds unresolved variables to the done dict. + # This is disabled when called from distutils.sysconfig + if keep_unresolved: + done[name] = value # bogus variable reference (e.g. "prefix=$/opt/python"); # just drop it since we can't deal - done[name] = value variables.remove(name) # strip spurious spaces @@ -343,21 +391,20 @@ def get_makefile_filename(): if _PYTHON_BUILD: return os.path.join(_sys_home or _PROJECT_BASE, "Makefile") if hasattr(sys, 'abiflags'): - config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) + config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}' else: config_dir_name = 'config' if hasattr(sys.implementation, '_multiarch'): - config_dir_name += '-%s' % sys.implementation._multiarch + config_dir_name += f'-{sys.implementation._multiarch}' return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') def _get_sysconfigdata_name(): - return os.environ.get('_PYTHON_SYSCONFIGDATA_NAME', - '_sysconfigdata_{abi}_{platform}_{multiarch}'.format( - abi=sys.abiflags, - platform=sys.platform, - multiarch=getattr(sys.implementation, '_multiarch', ''), - )) + multiarch = getattr(sys.implementation, '_multiarch', '') + return os.environ.get( + '_PYTHON_SYSCONFIGDATA_NAME', + f'_sysconfigdata_{sys.abiflags}_{sys.platform}_{multiarch}', + ) def _generate_posix_vars(): @@ -369,19 +416,19 @@ def _generate_posix_vars(): try: _parse_makefile(makefile, vars) except OSError as e: - msg = "invalid Python installation: unable to open %s" % makefile + msg = f"invalid Python installation: unable to open {makefile}" if hasattr(e, "strerror"): - msg = msg + " (%s)" % e.strerror + msg = f"{msg} ({e.strerror})" raise OSError(msg) # load the installed pyconfig.h: config_h = get_config_h_filename() try: - with open(config_h) as f: + with open(config_h, encoding="utf-8") as f: parse_config_h(f, vars) except OSError as e: - msg = "invalid Python installation: unable to open %s" % config_h + msg = f"invalid Python installation: unable to open {config_h}" if hasattr(e, "strerror"): - msg = msg + " (%s)" % e.strerror + msg = f"{msg} ({e.strerror})" raise OSError(msg) # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed @@ -407,7 +454,7 @@ def _generate_posix_vars(): module.build_time_vars = vars sys.modules[name] = module - pybuilddir = 'build/lib.%s-%s' % (get_platform(), _PY_VERSION_SHORT) + pybuilddir = f'build/lib.{get_platform()}-{_PY_VERSION_SHORT}' if hasattr(sys, "gettotalrefcount"): pybuilddir += '-pydebug' os.makedirs(pybuilddir, exist_ok=True) @@ -443,6 +490,7 @@ def _init_non_posix(vars): vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + vars['TZPATH'] = '' # # public APIs @@ -505,7 +553,7 @@ def get_path_names(): return _SCHEME_KEYS -def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): +def get_paths(scheme=get_default_scheme(), vars=None, expand=True): """Return a mapping containing an install scheme. ``scheme`` is the install scheme name. If not provided, it will @@ -517,7 +565,7 @@ def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): return _INSTALL_SCHEMES[scheme] -def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): +def get_path(name, scheme=get_default_scheme(), vars=None, expand=True): """Return a path corresponding to the scheme. ``scheme`` is the install scheme name. @@ -557,20 +605,24 @@ def get_config_vars(*args): 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['TZPATH'] = '' if os.name == 'posix': _init_posix(_CONFIG_VARS) # For backward compatibility, see issue19555 SO = _CONFIG_VARS.get('EXT_SUFFIX') if SO is not None: _CONFIG_VARS['SO'] = SO - # 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() + 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) @@ -667,16 +719,16 @@ def get_platform(): # At least on Linux/Intel, 'machine' is the processor -- # i386, etc. # XXX what about Alpha, SPARC, etc? - return "%s-%s" % (osname, machine) + return f"{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:]) + release = f"{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] + machine += f".{bitness[sys.maxsize]}" # fall through to standard osname-release-machine representation elif osname[:3] == "aix": from _aix_support import aix_platform @@ -694,18 +746,44 @@ def get_platform(): get_config_vars(), osname, release, machine) - return "%s-%s-%s" % (osname, release, machine) + return f"{osname}-{release}-{machine}" def get_python_version(): return _PY_VERSION_SHORT +def expand_makefile_vars(s, vars): + """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in + 'string' according to 'vars' (a dictionary mapping variable names to + values). Variables not present in 'vars' are silently expanded to the + empty string. The variable values in 'vars' should not contain further + variable expansions; if 'vars' is the output of 'parse_makefile()', + you're fine. Returns a variable-expanded version of 's'. + """ + import re + + # This algorithm does multiple expansion, so if vars['foo'] contains + # "${bar}", it will expand ${foo} to ${bar}, and then expand + # ${bar}... and so forth. This is fine as long as 'vars' comes from + # 'parse_makefile()', which takes care of such expansions eagerly, + # according to make's variable expansion semantics. + + while True: + m = re.search(_findvar1_rx, s) or re.search(_findvar2_rx, s) + if m: + (beg, end) = m.span() + s = s[0:beg] + vars.get(m.group(1)) + s[end:] + else: + break + return s + + def _print_dict(title, data): for index, (key, value) in enumerate(sorted(data.items())): if index == 0: - print('%s: ' % (title)) - print('\t%s = "%s"' % (key, value)) + print(f'{title}: ') + print(f'\t{key} = "{value}"') def _main(): @@ -713,9 +791,9 @@ def _main(): if '--generate-posix-vars' in sys.argv: _generate_posix_vars() return - print('Platform: "%s"' % get_platform()) - print('Python version: "%s"' % get_python_version()) - print('Current installation scheme: "%s"' % _get_default_scheme()) + print(f'Platform: "{get_platform()}"') + print(f'Python version: "{get_python_version()}"') + print(f'Current installation scheme: "{get_default_scheme()}"') print() _print_dict('Paths', get_paths()) print() diff --git a/contrib/tools/python3/src/Lib/tarfile.py b/contrib/tools/python3/src/Lib/tarfile.py index 9438b08ae39..6ada9a05db9 100755 --- a/contrib/tools/python3/src/Lib/tarfile.py +++ b/contrib/tools/python3/src/Lib/tarfile.py @@ -200,6 +200,7 @@ def itn(n, digits=8, format=DEFAULT_FORMAT): # base-256 representation. This allows values up to (256**(digits-1))-1. # A 0o200 byte indicates a positive number, a 0o377 byte a negative # number. + original_n = n n = int(n) if 0 <= n < 8 ** (digits - 1): s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL @@ -363,7 +364,7 @@ class _Stream: try: import zlib except ImportError: - raise CompressionError("zlib module is not available") + raise CompressionError("zlib module is not available") from None self.zlib = zlib self.crc = zlib.crc32(b"") if mode == "r": @@ -376,7 +377,7 @@ class _Stream: try: import bz2 except ImportError: - raise CompressionError("bz2 module is not available") + raise CompressionError("bz2 module is not available") from None if mode == "r": self.dbuf = b"" self.cmp = bz2.BZ2Decompressor() @@ -388,7 +389,7 @@ class _Stream: try: import lzma except ImportError: - raise CompressionError("lzma module is not available") + raise CompressionError("lzma module is not available") from None if mode == "r": self.dbuf = b"" self.cmp = lzma.LZMADecompressor() @@ -541,8 +542,8 @@ class _Stream: break try: buf = self.cmp.decompress(buf) - except self.exception: - raise ReadError("invalid compressed data") + except self.exception as e: + raise ReadError("invalid compressed data") from e t.append(buf) c += len(buf) t = b"".join(t) @@ -1173,8 +1174,8 @@ class TarInfo(object): # Fetch the next header and process it. try: next = self.fromtarfile(tarfile) - except HeaderError: - raise SubsequentHeaderError("missing or bad subsequent header") + except HeaderError as e: + raise SubsequentHeaderError(str(e)) from None # Patch the TarInfo object from the next header with # the longname information. @@ -1286,8 +1287,8 @@ class TarInfo(object): # Fetch the next header. try: next = self.fromtarfile(tarfile) - except HeaderError: - raise SubsequentHeaderError("missing or bad subsequent header") + except HeaderError as e: + raise SubsequentHeaderError(str(e)) from None # Process GNU sparse information. if "GNU.sparse.map" in pax_headers: @@ -1542,7 +1543,7 @@ class TarFile(object): self.fileobj.seek(self.offset) break except HeaderError as e: - raise ReadError(str(e)) + raise ReadError(str(e)) from None if self.mode in ("a", "w", "x"): self._loaded = True @@ -1612,17 +1613,20 @@ class TarFile(object): # Find out which *open() is appropriate for opening the file. def not_compressed(comptype): return cls.OPEN_METH[comptype] == 'taropen' + error_msgs = [] for comptype in sorted(cls.OPEN_METH, key=not_compressed): func = getattr(cls, cls.OPEN_METH[comptype]) if fileobj is not None: saved_pos = fileobj.tell() try: return func(name, "r", fileobj, **kwargs) - except (ReadError, CompressionError): + except (ReadError, CompressionError) as e: + error_msgs.append(f'- method {comptype}: {e!r}') if fileobj is not None: fileobj.seek(saved_pos) continue - raise ReadError("file could not be opened successfully") + error_msgs_summary = '\n'.join(error_msgs) + raise ReadError(f"file could not be opened successfully:\n{error_msgs_summary}") elif ":" in mode: filemode, comptype = mode.split(":", 1) @@ -1678,21 +1682,21 @@ class TarFile(object): try: from gzip import GzipFile except ImportError: - raise CompressionError("gzip module is not available") + raise CompressionError("gzip module is not available") from None try: fileobj = GzipFile(name, mode + "b", compresslevel, fileobj) - except OSError: + except OSError as e: if fileobj is not None and mode == 'r': - raise ReadError("not a gzip file") + raise ReadError("not a gzip file") from e raise try: t = cls.taropen(name, mode, fileobj, **kwargs) - except OSError: + except OSError as e: fileobj.close() if mode == 'r': - raise ReadError("not a gzip file") + raise ReadError("not a gzip file") from e raise except: fileobj.close() @@ -1711,16 +1715,16 @@ class TarFile(object): try: from bz2 import BZ2File except ImportError: - raise CompressionError("bz2 module is not available") + raise CompressionError("bz2 module is not available") from None fileobj = BZ2File(fileobj or name, mode, compresslevel=compresslevel) try: t = cls.taropen(name, mode, fileobj, **kwargs) - except (OSError, EOFError): + except (OSError, EOFError) as e: fileobj.close() if mode == 'r': - raise ReadError("not a bzip2 file") + raise ReadError("not a bzip2 file") from e raise except: fileobj.close() @@ -1739,16 +1743,16 @@ class TarFile(object): try: from lzma import LZMAFile, LZMAError except ImportError: - raise CompressionError("lzma module is not available") + raise CompressionError("lzma module is not available") from None fileobj = LZMAFile(fileobj or name, mode, preset=preset) try: t = cls.taropen(name, mode, fileobj, **kwargs) - except (LZMAError, EOFError): + except (LZMAError, EOFError) as e: fileobj.close() if mode == 'r': - raise ReadError("not an lzma file") + raise ReadError("not an lzma file") from e raise except: fileobj.close() @@ -2262,7 +2266,7 @@ class TarFile(object): self._extract_member(self._find_link_target(tarinfo), targetpath) except KeyError: - raise ExtractError("unable to resolve link inside archive") + raise ExtractError("unable to resolve link inside archive") from None def chown(self, tarinfo, targetpath, numeric_owner): """Set owner of targetpath according to tarinfo. If numeric_owner @@ -2290,16 +2294,16 @@ class TarFile(object): os.lchown(targetpath, u, g) else: os.chown(targetpath, u, g) - except OSError: - raise ExtractError("could not change owner") + except OSError as e: + raise ExtractError("could not change owner") from e def chmod(self, tarinfo, targetpath): """Set file permissions of targetpath according to tarinfo. """ try: os.chmod(targetpath, tarinfo.mode) - except OSError: - raise ExtractError("could not change mode") + except OSError as e: + raise ExtractError("could not change mode") from e def utime(self, tarinfo, targetpath): """Set modification time of targetpath according to tarinfo. @@ -2308,8 +2312,8 @@ class TarFile(object): return try: os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) - except OSError: - raise ExtractError("could not change modification time") + except OSError as e: + raise ExtractError("could not change modification time") from e #-------------------------------------------------------------------------- def next(self): @@ -2345,20 +2349,20 @@ class TarFile(object): self.offset += BLOCKSIZE continue elif self.offset == 0: - raise ReadError(str(e)) + raise ReadError(str(e)) from None except EmptyHeaderError: if self.offset == 0: - raise ReadError("empty file") + raise ReadError("empty file") from None except TruncatedHeaderError as e: if self.offset == 0: - raise ReadError(str(e)) + raise ReadError(str(e)) from None except SubsequentHeaderError as e: - raise ReadError(str(e)) + raise ReadError(str(e)) from None except Exception as e: try: import zlib if isinstance(e, zlib.error): - raise ReadError(f'zlib error: {e}') + raise ReadError(f'zlib error: {e}') from None else: raise e except ImportError: diff --git a/contrib/tools/python3/src/Lib/tempfile.py b/contrib/tools/python3/src/Lib/tempfile.py index eafce6f25b6..7b6821240f2 100644 --- a/contrib/tools/python3/src/Lib/tempfile.py +++ b/contrib/tools/python3/src/Lib/tempfile.py @@ -103,7 +103,11 @@ def _infer_return_type(*args): "path components.") return_type = str if return_type is None: - return str # tempfile APIs return a str by default. + if tempdir is None or isinstance(tempdir, str): + return str # tempfile APIs return a str by default. + else: + # we could check for bytes but it'll fail later on anyway + return bytes return return_type @@ -147,10 +151,7 @@ class _RandomNameSequence: return self def __next__(self): - c = self.characters - choose = self.rng.choice - letters = [choose(c) for dummy in range(8)] - return ''.join(letters) + return ''.join(self.rng.choices(self.characters, k=8)) def _candidate_tempdir_list(): """Generate a list of candidate temporary directories which @@ -272,17 +273,17 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type): # User visible interfaces. def gettempprefix(): - """The default prefix for temporary directories.""" - return template + """The default prefix for temporary directories as string.""" + return _os.fsdecode(template) def gettempprefixb(): """The default prefix for temporary directories as bytes.""" - return _os.fsencode(gettempprefix()) + return _os.fsencode(template) tempdir = None -def gettempdir(): - """Accessor for tempfile.tempdir.""" +def _gettempdir(): + """Private accessor for tempfile.tempdir.""" global tempdir if tempdir is None: _once_lock.acquire() @@ -293,9 +294,13 @@ def gettempdir(): _once_lock.release() return tempdir +def gettempdir(): + """Returns tempfile.tempdir as str.""" + return _os.fsdecode(_gettempdir()) + def gettempdirb(): - """A bytes version of tempfile.gettempdir().""" - return _os.fsencode(gettempdir()) + """Returns tempfile.tempdir as bytes.""" + return _os.fsencode(_gettempdir()) def mkstemp(suffix=None, prefix=None, dir=None, text=False): """User-callable function to create and return a unique temporary @@ -542,6 +547,9 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, if _os.name == 'nt' and delete: flags |= _os.O_TEMPORARY + if "b" not in mode: + encoding = _io.text_encoding(encoding) + (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type) try: file = _io.open(fd, mode, buffering=buffering, @@ -582,6 +590,9 @@ else: """ global _O_TMPFILE_WORKS + if "b" not in mode: + encoding = _io.text_encoding(encoding) + prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) flags = _bin_openflags @@ -637,6 +648,7 @@ class SpooledTemporaryFile: if 'b' in mode: self._file = _io.BytesIO() else: + encoding = _io.text_encoding(encoding) self._file = _io.TextIOWrapper(_io.BytesIO(), encoding=encoding, errors=errors, newline=newline) @@ -767,7 +779,7 @@ class SpooledTemporaryFile: return rv -class TemporaryDirectory(object): +class TemporaryDirectory: """Create and return a temporary directory. This has the same behavior as mkdtemp but can be used as a context manager. For example: @@ -779,14 +791,17 @@ class TemporaryDirectory(object): in it are removed. """ - def __init__(self, suffix=None, prefix=None, dir=None): + def __init__(self, suffix=None, prefix=None, dir=None, + ignore_cleanup_errors=False): self.name = mkdtemp(suffix, prefix, dir) + self._ignore_cleanup_errors = ignore_cleanup_errors self._finalizer = _weakref.finalize( self, self._cleanup, self.name, - warn_message="Implicitly cleaning up {!r}".format(self)) + warn_message="Implicitly cleaning up {!r}".format(self), + ignore_errors=self._ignore_cleanup_errors) @classmethod - def _rmtree(cls, name): + def _rmtree(cls, name, ignore_errors=False): def onerror(func, path, exc_info): if issubclass(exc_info[0], PermissionError): def resetperms(path): @@ -805,19 +820,20 @@ class TemporaryDirectory(object): _os.unlink(path) # PermissionError is raised on FreeBSD for directories except (IsADirectoryError, PermissionError): - cls._rmtree(path) + cls._rmtree(path, ignore_errors=ignore_errors) except FileNotFoundError: pass elif issubclass(exc_info[0], FileNotFoundError): pass else: - raise + if not ignore_errors: + raise _shutil.rmtree(name, onerror=onerror) @classmethod - def _cleanup(cls, name, warn_message): - cls._rmtree(name) + def _cleanup(cls, name, warn_message, ignore_errors=False): + cls._rmtree(name, ignore_errors=ignore_errors) _warnings.warn(warn_message, ResourceWarning) def __repr__(self): @@ -830,7 +846,7 @@ class TemporaryDirectory(object): self.cleanup() def cleanup(self): - if self._finalizer.detach(): - self._rmtree(self.name) + if self._finalizer.detach() or _os.path.exists(self.name): + self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors) __class_getitem__ = classmethod(_types.GenericAlias) diff --git a/contrib/tools/python3/src/Lib/textwrap.py b/contrib/tools/python3/src/Lib/textwrap.py index 30e693c8de0..841de9baecf 100644 --- a/contrib/tools/python3/src/Lib/textwrap.py +++ b/contrib/tools/python3/src/Lib/textwrap.py @@ -215,8 +215,16 @@ class TextWrapper: # If we're allowed to break long words, then do so: put as much # of the next chunk onto the current line as will fit. if self.break_long_words: - cur_line.append(reversed_chunks[-1][:space_left]) - reversed_chunks[-1] = reversed_chunks[-1][space_left:] + end = space_left + chunk = reversed_chunks[-1] + if self.break_on_hyphens and len(chunk) > space_left: + # break after last hyphen, but only if there are + # non-hyphens before it + hyphen = chunk.rfind('-', 0, space_left) + if hyphen > 0 and any(c != '-' for c in chunk[:hyphen]): + end = hyphen + 1 + cur_line.append(chunk[:end]) + reversed_chunks[-1] = chunk[end:] # Otherwise, we have to preserve the long word intact. Only add # it to the current line if there's nothing already there -- diff --git a/contrib/tools/python3/src/Lib/threading.py b/contrib/tools/python3/src/Lib/threading.py index a3cb245ab96..2d897429136 100644 --- a/contrib/tools/python3/src/Lib/threading.py +++ b/contrib/tools/python3/src/Lib/threading.py @@ -28,7 +28,7 @@ __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'] + 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile'] # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread @@ -65,6 +65,10 @@ def setprofile(func): global _profile_hook _profile_hook = func +def getprofile(): + """Get the profiler function as set by threading.setprofile().""" + return _profile_hook + def settrace(func): """Set a trace function for all threads started from the threading module. @@ -75,6 +79,10 @@ def settrace(func): global _trace_hook _trace_hook = func +def gettrace(): + """Get the trace function as set by threading.settrace().""" + return _trace_hook + # Synchronization classes Lock = _allocate_lock @@ -380,7 +388,16 @@ class Condition: """ self.notify(len(self._waiters)) - notifyAll = notify_all + def notifyAll(self): + """Wake up all threads waiting on this condition. + + This method is deprecated, use notify_all() instead. + + """ + import warnings + warnings.warn('notifyAll() is deprecated, use notify_all() instead', + DeprecationWarning, stacklevel=2) + self.notify_all() class Semaphore: @@ -530,7 +547,16 @@ class Event: """Return true if and only if the internal flag is true.""" return self._flag - isSet = is_set + def isSet(self): + """Return true if and only if the internal flag is true. + + This method is deprecated, use notify_all() instead. + + """ + import warnings + warnings.warn('isSet() is deprecated, use is_set() instead', + DeprecationWarning, stacklevel=2) + return self.is_set() def set(self): """Set the internal flag to true. @@ -745,10 +771,9 @@ class BrokenBarrierError(RuntimeError): # Helper to generate new thread names -_counter = _count().__next__ -_counter() # Consume 0 so first non-main thread has id 1. -def _newname(template="Thread-%d"): - return template % _counter() +_counter = _count(1).__next__ +def _newname(name_template): + return name_template % _counter() # Active thread administration. # @@ -818,8 +843,19 @@ class Thread: assert group is None, "group argument must be None for now" if kwargs is None: kwargs = {} + if name: + name = str(name) + else: + name = _newname("Thread-%d") + if target is not None: + try: + target_name = target.__name__ + name += f" ({target_name})" + except AttributeError: + pass + self._target = target - self._name = str(name or _newname()) + self._name = name self._args = args self._kwargs = kwargs if daemon is not None: @@ -906,7 +942,7 @@ class Thread: """ try: - if self._target: + if self._target is not None: self._target(*self._args, **self._kwargs) finally: # Avoid a refcycle if the thread is running a function with @@ -1161,15 +1197,47 @@ class Thread: self._daemonic = daemonic def isDaemon(self): + """Return whether this thread is a daemon. + + This method is deprecated, use the daemon attribute instead. + + """ + import warnings + warnings.warn('isDaemon() is deprecated, get the daemon attribute instead', + DeprecationWarning, stacklevel=2) return self.daemon def setDaemon(self, daemonic): + """Set whether this thread is a daemon. + + This method is deprecated, use the .daemon property instead. + + """ + import warnings + warnings.warn('setDaemon() is deprecated, set the daemon attribute instead', + DeprecationWarning, stacklevel=2) self.daemon = daemonic def getName(self): + """Return a string used for identification purposes only. + + This method is deprecated, use the name attribute instead. + + """ + import warnings + warnings.warn('getName() is deprecated, get the name attribute instead', + DeprecationWarning, stacklevel=2) return self.name def setName(self, name): + """Set the name string for this thread. + + This method is deprecated, use the name attribute instead. + + """ + import warnings + warnings.warn('setName() is deprecated, set the name attribute instead', + DeprecationWarning, stacklevel=2) self.name = name @@ -1219,6 +1287,10 @@ except ImportError: stderr.flush() +# Original value of threading.excepthook +__excepthook__ = excepthook + + def _make_invoke_excepthook(): # Create a local namespace to ensure that variables remain alive # when _invoke_excepthook() is called, even if it is called late during @@ -1360,7 +1432,16 @@ def current_thread(): except KeyError: return _DummyThread() -currentThread = current_thread +def currentThread(): + """Return the current Thread object, corresponding to the caller's thread of control. + + This function is deprecated, use current_thread() instead. + + """ + import warnings + warnings.warn('currentThread() is deprecated, use current_thread() instead', + DeprecationWarning, stacklevel=2) + return current_thread() def active_count(): """Return the number of Thread objects currently alive. @@ -1372,7 +1453,16 @@ def active_count(): with _active_limbo_lock: return len(_active) + len(_limbo) -activeCount = active_count +def activeCount(): + """Return the number of Thread objects currently alive. + + This function is deprecated, use active_count() instead. + + """ + import warnings + warnings.warn('activeCount() is deprecated, use active_count() instead', + DeprecationWarning, stacklevel=2) + return active_count() def _enumerate(): # Same as enumerate(), but without the lock. Internal use only. diff --git a/contrib/tools/python3/src/Lib/timeit.py b/contrib/tools/python3/src/Lib/timeit.py index 6c3ec01067f..9dfd454936e 100755 --- a/contrib/tools/python3/src/Lib/timeit.py +++ b/contrib/tools/python3/src/Lib/timeit.py @@ -72,6 +72,7 @@ def inner(_it, _timer{init}): _t0 = _timer() for _i in _it: {stmt} + pass _t1 = _timer() return _t1 - _t0 """ diff --git a/contrib/tools/python3/src/Lib/token.py b/contrib/tools/python3/src/Lib/token.py index 493bf042650..9d0c0bf0fb0 100644 --- a/contrib/tools/python3/src/Lib/token.py +++ b/contrib/tools/python3/src/Lib/token.py @@ -62,12 +62,13 @@ AWAIT = 55 ASYNC = 56 TYPE_IGNORE = 57 TYPE_COMMENT = 58 +SOFT_KEYWORD = 59 # These aren't used by the C tokenizer but are needed for tokenize.py -ERRORTOKEN = 59 -COMMENT = 60 -NL = 61 -ENCODING = 62 -N_TOKENS = 63 +ERRORTOKEN = 60 +COMMENT = 61 +NL = 62 +ENCODING = 63 +N_TOKENS = 64 # Special definitions for cooperation with parser NT_OFFSET = 256 diff --git a/contrib/tools/python3/src/Lib/tokenize.py b/contrib/tools/python3/src/Lib/tokenize.py index a782f6250dd..7d7736fe985 100644 --- a/contrib/tools/python3/src/Lib/tokenize.py +++ b/contrib/tools/python3/src/Lib/tokenize.py @@ -27,6 +27,7 @@ __credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, ' from builtins import open as _builtin_open from codecs import lookup, BOM_UTF8 import collections +import functools from io import TextIOWrapper import itertools as _itertools import re @@ -95,6 +96,7 @@ def _all_string_prefixes(): result.add(''.join(u)) return result +@functools.lru_cache def _compile(expr): return re.compile(expr, re.UNICODE) diff --git a/contrib/tools/python3/src/Lib/trace.py b/contrib/tools/python3/src/Lib/trace.py index c505d8bc72a..2cf3643878d 100755 --- a/contrib/tools/python3/src/Lib/trace.py +++ b/contrib/tools/python3/src/Lib/trace.py @@ -116,7 +116,7 @@ class _Ignore: return 0 def _modname(path): - """Return a plausible module name for the patch.""" + """Return a plausible module name for the path.""" base = os.path.basename(path) filename, ext = os.path.splitext(base) diff --git a/contrib/tools/python3/src/Lib/traceback.py b/contrib/tools/python3/src/Lib/traceback.py index c771a137cd9..d6a010f4157 100644 --- a/contrib/tools/python3/src/Lib/traceback.py +++ b/contrib/tools/python3/src/Lib/traceback.py @@ -84,7 +84,25 @@ _context_message = ( "another exception occurred:\n\n") -def print_exception(etype, value, tb, limit=None, file=None, chain=True): +class _Sentinel: + def __repr__(self): + return "" + +_sentinel = _Sentinel() + +def _parse_value_tb(exc, value, tb): + if (value is _sentinel) != (tb is _sentinel): + raise ValueError("Both or neither of value and tb must be given") + if value is tb is _sentinel: + if exc is not None: + return exc, exc.__traceback__ + else: + return None, None + return value, tb + + +def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ + file=None, chain=True): """Print exception up to 'limit' stack trace entries from 'tb' to 'file'. This differs from print_tb() in the following ways: (1) if @@ -95,17 +113,16 @@ def print_exception(etype, value, tb, limit=None, file=None, chain=True): occurred with a caret on the next line indicating the approximate position of the error. """ - # format_exception has ignored etype for some time, and code such as cgitb - # passes in bogus values as a result. For compatibility with such code we - # ignore it here (rather than in the new TracebackException API). + value, tb = _parse_value_tb(exc, value, tb) if file is None: file = sys.stderr - for line in TracebackException( - type(value), value, tb, limit=limit).format(chain=chain): + te = TracebackException(type(value), value, tb, limit=limit, compact=True) + for line in te.format(chain=chain): print(line, file=file, end="") -def format_exception(etype, value, tb, limit=None, chain=True): +def format_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ + chain=True): """Format a stack trace and the exception information. The arguments have the same meaning as the corresponding arguments @@ -114,19 +131,15 @@ def format_exception(etype, value, tb, limit=None, chain=True): these lines are concatenated and printed, exactly the same text is printed as does print_exception(). """ - # format_exception has ignored etype for some time, and code such as cgitb - # passes in bogus values as a result. For compatibility with such code we - # ignore it here (rather than in the new TracebackException API). - return list(TracebackException( - type(value), value, tb, limit=limit).format(chain=chain)) + value, tb = _parse_value_tb(exc, value, tb) + te = TracebackException(type(value), value, tb, limit=limit, compact=True) + return list(te.format(chain=chain)) -def format_exception_only(etype, value): +def format_exception_only(exc, /, value=_sentinel): """Format the exception part of a traceback. - The arguments are the exception type and value such as given by - sys.last_type and sys.last_value. The return value is a list of - strings, each ending in a newline. + The return value is a list of strings, each ending in a newline. Normally, the list contains a single string; however, for SyntaxError exceptions, it contains several lines that (when @@ -137,7 +150,10 @@ def format_exception_only(etype, value): string in the list. """ - return list(TracebackException(etype, value, None).format_exception_only()) + if value is _sentinel: + value = exc + te = TracebackException(type(value), value, None, compact=True) + return list(te.format_exception_only()) # -- not official API but folk probably use these two functions. @@ -285,9 +301,10 @@ class FrameSummary: @property def line(self): if self._line is None: - self._line = linecache.getline(self.filename, self.lineno).strip() - return self._line - + if self.lineno is None: + return None + self._line = linecache.getline(self.filename, self.lineno) + return self._line.strip() def walk_stack(f): """Walk a stack yielding the frame and line number for each frame. @@ -458,61 +475,29 @@ class TracebackException: occurred. - :attr:`lineno` For syntax errors - the linenumber where the error occurred. + - :attr:`end_lineno` For syntax errors - the end linenumber where the error + occurred. Can be `None` if not present. - :attr:`text` For syntax errors - the text where the error 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:`msg` For syntax errors - the compiler error message. """ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, - lookup_lines=True, capture_locals=False, _seen=None): + lookup_lines=True, capture_locals=False, compact=False, + _seen=None): # NB: we need to accept exc_traceback, exc_value, exc_traceback to # permit backwards compat with the existing API, otherwise we # need stub thunk objects just to glue it together. # Handle loops in __cause__ or __context__. + is_recursive_call = _seen is not None if _seen is None: _seen = set() _seen.add(id(exc_value)) - # Gracefully handle (the way Python 2.4 and earlier did) the case of - # being called with no type or value (None, None, None). - self._truncated = False - try: - if (exc_value and exc_value.__cause__ is not None - and id(exc_value.__cause__) not in _seen): - cause = TracebackException( - type(exc_value.__cause__), - exc_value.__cause__, - exc_value.__cause__.__traceback__, - limit=limit, - lookup_lines=False, - capture_locals=capture_locals, - _seen=_seen) - else: - cause = None - if (exc_value and exc_value.__context__ is not None - and id(exc_value.__context__) not in _seen): - context = TracebackException( - type(exc_value.__context__), - exc_value.__context__, - exc_value.__context__.__traceback__, - limit=limit, - lookup_lines=False, - capture_locals=capture_locals, - _seen=_seen) - else: - context = None - except RecursionError: - # The recursive call to the constructors above - # may result in a stack overflow for long exception chains, - # so we must truncate. - self._truncated = True - cause = None - context = None - self.__cause__ = cause - self.__context__ = context - self.__suppress_context__ = \ - exc_value.__suppress_context__ if exc_value else False + # TODO: locals. self.stack = StackSummary.extract( walk_tb(exc_traceback), limit=limit, lookup_lines=lookup_lines, @@ -526,11 +511,60 @@ class TracebackException: self.filename = exc_value.filename lno = exc_value.lineno self.lineno = str(lno) if lno is not None else None + end_lno = exc_value.end_lineno + self.end_lineno = str(end_lno) if end_lno is not None else None self.text = exc_value.text self.offset = exc_value.offset + self.end_offset = exc_value.end_offset self.msg = exc_value.msg if lookup_lines: self._load_lines() + self.__suppress_context__ = \ + exc_value.__suppress_context__ if exc_value is not None else False + + # Convert __cause__ and __context__ to `TracebackExceptions`s, use a + # queue to avoid recursion (only the top-level call gets _seen == None) + if not is_recursive_call: + queue = [(self, exc_value)] + while queue: + te, e = queue.pop() + if (e and e.__cause__ is not None + and id(e.__cause__) not in _seen): + cause = TracebackException( + type(e.__cause__), + e.__cause__, + e.__cause__.__traceback__, + limit=limit, + lookup_lines=lookup_lines, + capture_locals=capture_locals, + _seen=_seen) + else: + cause = None + + if compact: + need_context = (cause is None and + e is not None and + not e.__suppress_context__) + else: + need_context = True + if (e and e.__context__ is not None + and need_context and id(e.__context__) not in _seen): + context = TracebackException( + type(e.__context__), + e.__context__, + e.__context__.__traceback__, + limit=limit, + lookup_lines=lookup_lines, + capture_locals=capture_locals, + _seen=_seen) + else: + context = None + te.__cause__ = cause + te.__context__ = context + if cause: + queue.append((te.__cause__, e.__cause__)) + if context: + queue.append((te.__context__, e.__context__)) @classmethod def from_exception(cls, exc, *args, **kwargs): @@ -541,10 +575,6 @@ class TracebackException: """Private API. force all lines in the stack to be loaded.""" for frame in self.stack: frame.line - if self.__context__: - self.__context__._load_lines() - if self.__cause__: - self.__cause__._load_lines() def __eq__(self, other): if isinstance(other, TracebackException): @@ -602,12 +632,20 @@ class TracebackException: ltext = rtext.lstrip(' \n\f') spaces = len(rtext) - len(ltext) yield ' {}\n'.format(ltext) - # Convert 1-based column offset to 0-based index into stripped text - caret = (self.offset or 0) - 1 - spaces - if caret >= 0: - # non-space whitespace (likes tabs) must be kept for alignment - caretspace = ((c if c.isspace() else ' ') for c in ltext[:caret]) - yield ' {}^\n'.format(''.join(caretspace)) + + if self.offset is not None: + offset = self.offset + end_offset = self.end_offset if self.end_offset not in {None, 0} else offset + if offset == end_offset or end_offset == -1: + end_offset = offset + 1 + + # Convert 1-based column offset to 0-based index into stripped text + colno = offset - 1 - spaces + end_colno = end_offset - 1 - spaces + if colno >= 0: + # non-space whitespace (likes tabs) must be kept for alignment + caretspace = ((c if c.isspace() else ' ') for c in ltext[:colno]) + yield ' {}{}'.format("".join(caretspace), ('^' * (end_colno - colno) + "\n")) msg = self.msg or "" yield "{}: {}{}\n".format(stype, msg, filename_suffix) @@ -623,19 +661,32 @@ class TracebackException: The message indicating which exception occurred is always the last string in the output. """ - if chain: - if self.__cause__ is not None: - yield from self.__cause__.format(chain=chain) - yield _cause_message - elif (self.__context__ is not None and - not self.__suppress_context__): - yield from self.__context__.format(chain=chain) - yield _context_message - if self._truncated: - yield ( - 'Chained exceptions have been truncated to avoid ' - 'stack overflow in traceback formatting:\n') - if self.stack: - yield 'Traceback (most recent call last):\n' - yield from self.stack.format() - yield from self.format_exception_only() + + output = [] + exc = self + while exc: + if chain: + if exc.__cause__ is not None: + chained_msg = _cause_message + chained_exc = exc.__cause__ + elif (exc.__context__ is not None and + not exc.__suppress_context__): + chained_msg = _context_message + chained_exc = exc.__context__ + else: + chained_msg = None + chained_exc = None + + output.append((chained_msg, exc)) + exc = chained_exc + else: + output.append((None, exc)) + exc = None + + for msg, exc in reversed(output): + if msg is not None: + yield msg + if exc.stack: + yield 'Traceback (most recent call last):\n' + yield from exc.stack.format() + yield from exc.format_exception_only() diff --git a/contrib/tools/python3/src/Lib/turtle.py b/contrib/tools/python3/src/Lib/turtle.py index 9c8f6ced250..f3b320b90ca 100644 --- a/contrib/tools/python3/src/Lib/turtle.py +++ b/contrib/tools/python3/src/Lib/turtle.py @@ -264,12 +264,12 @@ class Vec2D(tuple): def __neg__(self): return Vec2D(-self[0], -self[1]) def __abs__(self): - return (self[0]**2 + self[1]**2)**0.5 + return math.hypot(*self) def rotate(self, angle): """rotate self counterclockwise by angle """ perp = Vec2D(-self[1], self[0]) - angle = angle * math.pi / 180.0 + angle = math.radians(angle) c, s = math.cos(angle), math.sin(angle) return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s) def __getnewargs__(self): @@ -1598,7 +1598,7 @@ class TNavigator(object): >>> turtle.heading() 1.5707963267948966 """ - self._setDegreesPerAU(2*math.pi) + self._setDegreesPerAU(math.tau) def _go(self, distance): """move turtle forward by specified distance""" @@ -1889,7 +1889,7 @@ class TNavigator(object): elif isinstance(x, TNavigator): pos = x._position x, y = pos - self._position - result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0 + result = round(math.degrees(math.atan2(y, x)), 10) % 360.0 result /= self._degreesPerAU return (self._angleOffset + self._angleOrient*result) % self._fullcircle @@ -1904,7 +1904,7 @@ class TNavigator(object): 67.0 """ x, y = self._orient - result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0 + result = round(math.degrees(math.atan2(y, x)), 10) % 360.0 result /= self._degreesPerAU return (self._angleOffset + self._angleOrient*result) % self._fullcircle @@ -1977,7 +1977,7 @@ class TNavigator(object): steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac) w = 1.0 * extent / steps w2 = 0.5 * w - l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU) + l = 2.0 * radius * math.sin(math.radians(w2)*self._degreesPerAU) if radius < 0: l, w, w2 = -l, -w, -w2 tr = self._tracer() @@ -2862,7 +2862,7 @@ class RawTurtle(TPen, TNavigator): >>> turtle.fd(50) """ tilt = -angle * self._degreesPerAU * self._angleOrient - tilt = (tilt * math.pi / 180.0) % (2*math.pi) + tilt = math.radians(tilt) % math.tau self.pen(resizemode="user", tilt=tilt) def tiltangle(self, angle=None): @@ -2887,7 +2887,7 @@ class RawTurtle(TPen, TNavigator): >>> turtle.tiltangle() """ if angle is None: - tilt = -self._tilt * (180.0/math.pi) * self._angleOrient + tilt = -math.degrees(self._tilt) * self._angleOrient return (tilt / self._degreesPerAU) % self._fullcircle else: self.settiltangle(angle) @@ -2941,7 +2941,7 @@ class RawTurtle(TPen, TNavigator): if t11 * t22 - t12 * t21 == 0: raise TurtleGraphicsError("Bad shape transform matrix: must not be singular") self._shapetrafo = (m11, m12, m21, m22) - alfa = math.atan2(-m21, m11) % (2 * math.pi) + alfa = math.atan2(-m21, m11) % math.tau sa, ca = math.sin(alfa), math.cos(alfa) a11, a12, a21, a22 = (ca*m11 - sa*m21, ca*m12 - sa*m22, sa*m11 + ca*m21, sa*m12 + ca*m22) diff --git a/contrib/tools/python3/src/Lib/types.py b/contrib/tools/python3/src/Lib/types.py index f15fda5933a..62122a99486 100644 --- a/contrib/tools/python3/src/Lib/types.py +++ b/contrib/tools/python3/src/Lib/types.py @@ -155,7 +155,12 @@ class DynamicClassAttribute: class's __getattr__ method; this is done by raising AttributeError. This allows one to have properties active on an instance, and have virtual - attributes on the class with the same name (see Enum for an example). + attributes on the class with the same name. (Enum used this between Python + versions 3.4 - 3.9 .) + + Subclass from this to use a different method of accessing virtual atributes + and still be treated properly by the inspect module. (Enum uses this since + Python 3.10 .) """ def __init__(self, fget=None, fset=None, fdel=None, doc=None): @@ -292,8 +297,11 @@ def coroutine(func): return wrapped - GenericAlias = type(list[int]) +UnionType = type(int | str) +EllipsisType = type(Ellipsis) +NoneType = type(None) +NotImplementedType = type(NotImplemented) __all__ = [n for n in globals() if n[:1] != '_'] diff --git a/contrib/tools/python3/src/Lib/typing.py b/contrib/tools/python3/src/Lib/typing.py index d35a2a5b018..086d0f3f959 100644 --- a/contrib/tools/python3/src/Lib/typing.py +++ b/contrib/tools/python3/src/Lib/typing.py @@ -4,8 +4,10 @@ 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, ClassVar, Union, Optional -* Two classes whose instances can be type arguments in addition to types: ForwardRef and TypeVar +* _SpecialForm and its instances (special forms): + Any, NoReturn, ClassVar, Union, Optional, Concatenate +* 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. @@ -35,11 +37,13 @@ __all__ = [ 'Any', 'Callable', 'ClassVar', + 'Concatenate', 'Final', 'ForwardRef', 'Generic', 'Literal', 'Optional', + 'ParamSpec', 'Protocol', 'Tuple', 'Type', @@ -110,14 +114,19 @@ __all__ = [ 'get_args', 'get_origin', 'get_type_hints', + 'is_typeddict', 'NewType', 'no_type_check', 'no_type_check_decorator', 'NoReturn', 'overload', + 'ParamSpecArgs', + 'ParamSpecKwargs', 'runtime_checkable', 'Text', 'TYPE_CHECKING', + 'TypeAlias', + 'TypeGuard', ] # The pseudo-submodules 're' and 'io' are part of the public @@ -156,17 +165,23 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms= if (isinstance(arg, _GenericAlias) and arg.__origin__ in invalid_generic_forms): raise TypeError(f"{arg} is not valid as type argument") - if arg in (Any, NoReturn, Final): + if arg in (Any, NoReturn, Final, TypeAlias): return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") - if isinstance(arg, (type, TypeVar, ForwardRef)): + if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec, + ParamSpecArgs, ParamSpecKwargs)): return arg if not callable(arg): raise TypeError(f"{msg} Got {arg!r:.100}.") return arg +def _is_param_expr(arg): + return arg is ... or isinstance(arg, + (tuple, list, ParamSpec, _ConcatenateGenericAlias)) + + def _type_repr(obj): """Return the repr() of an object, special-casing types (internal helper). @@ -188,17 +203,19 @@ def _type_repr(obj): return repr(obj) -def _collect_type_vars(types): - """Collect all type variable contained in types in order of - first appearance (lexicographic order). For example:: +def _collect_type_vars(types_, typevar_types=None): + """Collect all type variable contained + in types in order of first appearance (lexicographic order). For example:: _collect_type_vars((T, List[S, T])) == (T, S) """ + if typevar_types is None: + typevar_types = TypeVar tvars = [] - for t in types: - if isinstance(t, TypeVar) and t not in tvars: + for t in types_: + if isinstance(t, typevar_types) and t not in tvars: tvars.append(t) - if isinstance(t, (_GenericAlias, GenericAlias)): + if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): tvars.extend([t for t in t.__parameters__ if t not in tvars]) return tuple(tvars) @@ -211,9 +228,27 @@ def _check_generic(cls, parameters, elen): raise TypeError(f"{cls} is not a generic class") alen = len(parameters) if alen != elen: - raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};" + raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};" f" actual {alen}, expected {elen}") +def _prepare_paramspec_params(cls, params): + """Prepares the parameters for a Generic containing ParamSpec + variables (internal helper). + """ + # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. + if (len(cls.__parameters__) == 1 + and params and not _is_param_expr(params[0])): + assert isinstance(cls.__parameters__[0], ParamSpec) + return (params,) + else: + _check_generic(cls, params, len(cls.__parameters__)) + _params = [] + # Convert lists to tuples to help other libraries cache the results. + for p, tvar in zip(params, cls.__parameters__): + if isinstance(tvar, ParamSpec) and isinstance(p, list): + p = tuple(p) + _params.append(p) + return tuple(_params) def _deduplicate(params): # Weed out strict duplicates, preserving the first of each occurrence. @@ -236,7 +271,7 @@ def _remove_dups_flatten(parameters): # Flatten out Union[Union[...], ...]. params = [] for p in parameters: - if isinstance(p, _UnionGenericAlias): + if isinstance(p, (_UnionGenericAlias, types.UnionType)): params.extend(p.__args__) elif isinstance(p, tuple) and len(p) > 0 and p[0] is Union: params.extend(p[1:]) @@ -290,12 +325,14 @@ def _eval_type(t, globalns, localns, recursive_guard=frozenset()): """ if isinstance(t, ForwardRef): return t._evaluate(globalns, localns, recursive_guard) - if isinstance(t, (_GenericAlias, GenericAlias)): + if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__args__) if ev_args == t.__args__: return t if isinstance(t, GenericAlias): return GenericAlias(t.__origin__, ev_args) + if isinstance(t, types.UnionType): + return functools.reduce(operator.or_, ev_args) else: return t.copy_with(ev_args) return t @@ -331,6 +368,12 @@ class _SpecialForm(_Final, _root=True): self._name = getitem.__name__ self.__doc__ = getitem.__doc__ + def __getattr__(self, item): + if item in {'__name__', '__qualname__'}: + return self._name + + raise AttributeError(item) + def __mro_entries__(self, bases): raise TypeError(f"Cannot subclass {self!r}") @@ -343,6 +386,12 @@ class _SpecialForm(_Final, _root=True): def __call__(self, *args, **kwds): raise TypeError(f"Cannot instantiate {self!r}") + def __or__(self, other): + return Union[self, other] + + def __ror__(self, other): + return Union[other, self] + def __instancecheck__(self, obj): raise TypeError(f"{self} cannot be used with isinstance()") @@ -467,6 +516,8 @@ def Union(self, parameters): parameters = _remove_dups_flatten(parameters) if len(parameters) == 1: return parameters[0] + if len(parameters) == 2 and type(None) in parameters: + return _UnionGenericAlias(self, parameters, name="Optional") return _UnionGenericAlias(self, parameters) @_SpecialForm @@ -513,6 +564,95 @@ def Literal(self, *parameters): return _LiteralGenericAlias(self, parameters) +@_SpecialForm +def TypeAlias(self, parameters): + """Special marker indicating that an assignment should + be recognized as a proper type alias definition by type + checkers. + + For example:: + + Predicate: TypeAlias = Callable[..., bool] + + It's invalid when used anywhere except as in the example above. + """ + raise TypeError(f"{self} is not subscriptable") + + +@_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. + + For example:: + + Callable[Concatenate[int, P], int] + + See PEP 612 for detailed information. + """ + if parameters == (): + raise TypeError("Cannot take a Concatenate of no types.") + if not isinstance(parameters, tuple): + parameters = (parameters,) + if not isinstance(parameters[-1], ParamSpec): + raise TypeError("The last parameter to Concatenate should be a " + "ParamSpec variable.") + 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, + _typevar_types=(TypeVar, ParamSpec), + _paramspec_tvars=True) + + +@_SpecialForm +def TypeGuard(self, parameters): + """Special typing form 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. + + ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static + type checkers to determine a more precise type of an expression within a + program's code flow. Usually type narrowing is done by analyzing + conditional code flow and applying the narrowing to a block of code. The + conditional expression here is sometimes referred to as a "type guard". + + Sometimes it would be convenient to use a user-defined boolean function + as a type guard. Such a function should use ``TypeGuard[...]`` as its + return type to alert static type checkers to this intention. + + Using ``-> TypeGuard`` tells the static type checker that for a given + function: + + 1. The return value is a boolean. + 2. If the return value is ``True``, the type of its argument + is the type inside ``TypeGuard``. + + 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``. + ... + + 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 + type-unsafe results. The main reason is to allow for things like + narrowing ``List[object]`` to ``List[str]`` even though the latter is not + a subtype of the former, since ``List`` is invariant. The responsibility of + writing type-safe type guards is left to the user. + + ``TypeGuard`` also works with type variables. For more information, see + PEP 647 (User-Defined Type Guards). + """ + item = _type_check(parameters, f'{self} accepts only single type.') + return _GenericAlias(self, (item,)) + + class ForwardRef(_Final, _root=True): """Internal wrapper to hold a forward reference.""" @@ -577,8 +717,41 @@ class ForwardRef(_Final, _root=True): def __repr__(self): return f'ForwardRef({self.__forward_arg__!r})' +class _TypeVarLike: + """Mixin for TypeVar-like types (TypeVar and ParamSpec).""" + 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] -class TypeVar(_Final, _Immutable, _root=True): + def __repr__(self): + if self.__covariant__: + prefix = '+' + elif self.__contravariant__: + prefix = '-' + else: + prefix = '~' + return prefix + self.__name__ + + def __reduce__(self): + return self.__name__ + + +class TypeVar( _Final, _Immutable, _TypeVarLike, _root=True): """Type variable. Usage:: @@ -628,20 +801,13 @@ class TypeVar(_Final, _Immutable, _root=True): def __init__(self, name, *constraints, bound=None, covariant=False, contravariant=False): self.__name__ = name - if covariant and contravariant: - raise ValueError("Bivariant types are not supported.") - self.__covariant__ = bool(covariant) - self.__contravariant__ = bool(contravariant) + 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) - if bound: - self.__bound__ = _type_check(bound, "Bound must be a type.") - else: - self.__bound__ = None try: def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') # for pickling except (AttributeError, ValueError): @@ -649,17 +815,121 @@ class TypeVar(_Final, _Immutable, _root=True): if def_mod != 'typing': self.__module__ = def_mod + +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): - if self.__covariant__: - prefix = '+' - elif self.__contravariant__: - prefix = '-' - else: - prefix = '~' - return prefix + self.__name__ + return f"{self.__origin__.__name__}.args" - def __reduce__(self): - return self.__name__ + 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, _TypeVarLike, _root=True): + """Parameter specification variable. + + Usage:: + + 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__ == 'T' + P.__bound__ == None + P.__covariant__ == False + P.__contravariant__ == False + + Note that only parameter specification variables defined in global scope can + be pickled. + """ + + __slots__ = ('__name__', '__bound__', '__covariant__', '__contravariant__', + '__dict__') + + @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) + try: + def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + def_mod = None + if def_mod != 'typing': + self.__module__ = def_mod def _is_dunder(attr): @@ -704,6 +974,9 @@ class _BaseGenericAlias(_Final, _root=True): return tuple(res) def __getattr__(self, attr): + if attr in {'__name__', '__qualname__'}: + return self._name or self.__origin__.__name__ + # We are careful for copy and pickle. # Also for simplicity we don't relay any dunder names if '__origin__' in self.__dict__ and not _is_dunder(attr): @@ -711,7 +984,8 @@ class _BaseGenericAlias(_Final, _root=True): raise AttributeError(attr) def __setattr__(self, attr, val): - if _is_dunder(attr) or attr in ('_name', '_inst', '_nparams'): + if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams', + '_typevar_types', '_paramspec_tvars'}: super().__setattr__(attr, val) else: setattr(self.__origin__, attr, val) @@ -723,6 +997,9 @@ class _BaseGenericAlias(_Final, _root=True): raise TypeError("Subscripted generics cannot be used with" " class and instance checks") + def __dir__(self): + return list(set(super().__dir__() + + [attr for attr in dir(self.__origin__) if not _is_dunder(attr)])) # Special typing constructs Union, Optional, Generic, Callable and Tuple # use three special attributes for internal bookkeeping of generic types: @@ -736,14 +1013,18 @@ class _BaseGenericAlias(_Final, _root=True): class _GenericAlias(_BaseGenericAlias, _root=True): - def __init__(self, origin, params, *, inst=True, name=None): + def __init__(self, origin, params, *, inst=True, name=None, + _typevar_types=TypeVar, + _paramspec_tvars=False): super().__init__(origin, inst=inst, name=name) if not isinstance(params, tuple): params = (params,) self.__args__ = tuple(... if a is _TypingEllipsis else () if a is _TypingEmpty else a for a in params) - self.__parameters__ = _collect_type_vars(params) + self.__parameters__ = _collect_type_vars(params, typevar_types=_typevar_types) + self._typevar_types = _typevar_types + self._paramspec_tvars = _paramspec_tvars if not name: self.__module__ = origin.__module__ @@ -756,6 +1037,12 @@ class _GenericAlias(_BaseGenericAlias, _root=True): def __hash__(self): return hash((self.__origin__, self.__args__)) + def __or__(self, right): + return Union[self, right] + + def __ror__(self, left): + return Union[left, self] + @_tp_cache def __getitem__(self, params): if self.__origin__ in (Generic, Protocol): @@ -763,25 +1050,40 @@ class _GenericAlias(_BaseGenericAlias, _root=True): raise TypeError(f"Cannot subscript already-subscripted {self}") if not isinstance(params, tuple): params = (params,) - msg = "Parameters to generic types must be types." - params = tuple(_type_check(p, msg) for p in params) - _check_generic(self, params, len(self.__parameters__)) + params = tuple(_type_convert(p) for p in params) + if (self._paramspec_tvars + and any(isinstance(t, ParamSpec) for t in self.__parameters__)): + params = _prepare_paramspec_params(self, params) + else: + _check_generic(self, params, len(self.__parameters__)) subst = dict(zip(self.__parameters__, params)) new_args = [] for arg in self.__args__: - if isinstance(arg, TypeVar): - arg = subst[arg] - elif isinstance(arg, (_GenericAlias, GenericAlias)): + if isinstance(arg, self._typevar_types): + if isinstance(arg, ParamSpec): + arg = subst[arg] + if not _is_param_expr(arg): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {arg}") + else: + arg = subst[arg] + elif isinstance(arg, (_GenericAlias, GenericAlias, types.UnionType)): subparams = arg.__parameters__ if subparams: subargs = tuple(subst[x] for x in subparams) arg = arg[subargs] - new_args.append(arg) + # Required to flatten out the args for CallableGenericAlias + if self.__origin__ == collections.abc.Callable and isinstance(arg, tuple): + new_args.extend(arg) + else: + new_args.append(arg) return self.copy_with(tuple(new_args)) def copy_with(self, params): - return self.__class__(self.__origin__, params, name=self._name, inst=self._inst) + return self.__class__(self.__origin__, params, name=self._name, inst=self._inst, + _typevar_types=self._typevar_types, + _paramspec_tvars=self._paramspec_tvars) def __repr__(self): if self._name: @@ -802,6 +1104,9 @@ class _GenericAlias(_BaseGenericAlias, _root=True): return operator.getitem, (origin, args) def __mro_entries__(self, bases): + if isinstance(self.__origin__, _SpecialForm): + raise TypeError(f"Cannot subclass {self!r}") + if self._name: # generic version of an ABC or built-in class return super().__mro_entries__(bases) if self.__origin__ is Generic: @@ -855,19 +1160,25 @@ class _SpecialGenericAlias(_BaseGenericAlias, _root=True): def __reduce__(self): return self._name + def __or__(self, right): + return Union[self, right] + + def __ror__(self, left): + return Union[left, self] class _CallableGenericAlias(_GenericAlias, _root=True): def __repr__(self): assert self._name == 'Callable' - if len(self.__args__) == 2 and self.__args__[0] is Ellipsis: + args = self.__args__ + if len(args) == 2 and _is_param_expr(args[0]): return super().__repr__() return (f'typing.Callable' - f'[[{", ".join([_type_repr(a) for a in self.__args__[:-1]])}], ' - f'{_type_repr(self.__args__[-1])}]') + f'[[{", ".join([_type_repr(a) for a in args[:-1]])}], ' + f'{_type_repr(args[-1])}]') def __reduce__(self): args = self.__args__ - if not (len(args) == 2 and args[0] is ...): + if not (len(args) == 2 and _is_param_expr(args[0])): args = list(args[:-1]), args[-1] return operator.getitem, (Callable, args) @@ -875,7 +1186,9 @@ class _CallableGenericAlias(_GenericAlias, _root=True): class _CallableType(_SpecialGenericAlias, _root=True): def copy_with(self, params): return _CallableGenericAlias(self.__origin__, params, - name=self._name, inst=self._inst) + name=self._name, inst=self._inst, + _typevar_types=(TypeVar, ParamSpec), + _paramspec_tvars=True) def __getitem__(self, params): if not isinstance(params, tuple) or len(params) != 2: @@ -926,7 +1239,7 @@ class _UnionGenericAlias(_GenericAlias, _root=True): return Union[params] def __eq__(self, other): - if not isinstance(other, _UnionGenericAlias): + if not isinstance(other, (_UnionGenericAlias, types.UnionType)): return NotImplemented return set(self.__args__) == set(other.__args__) @@ -942,6 +1255,18 @@ class _UnionGenericAlias(_GenericAlias, _root=True): return f'typing.Optional[{_type_repr(args[0])}]' return super().__repr__() + def __instancecheck__(self, obj): + return self.__subclasscheck__(type(obj)) + + def __subclasscheck__(self, cls): + for arg in self.__args__: + if issubclass(cls, arg): + return True + + def __reduce__(self): + func, (origin, args) = super().__reduce__() + return func, (Union, args) + def _value_and_type_iter(parameters): return ((p, type(p)) for p in parameters) @@ -959,6 +1284,18 @@ class _LiteralGenericAlias(_GenericAlias, _root=True): return hash(frozenset(_value_and_type_iter(self.__args__))) +class _ConcatenateGenericAlias(_GenericAlias, _root=True): + def copy_with(self, params): + if isinstance(params[-1], (list, tuple)): + return (*params[:-1], *params[-1]) + if isinstance(params[-1], _ConcatenateGenericAlias): + params = (*params[:-1], *params[-1].__args__) + elif not isinstance(params[-1], ParamSpec): + raise TypeError("The last parameter to Concatenate should be a " + "ParamSpec variable.") + return super().copy_with(params) + + class Generic: """Abstract base class for generic types. @@ -989,20 +1326,25 @@ class Generic: if not params and cls is not Tuple: raise TypeError( f"Parameter list to {cls.__qualname__}[...] cannot be empty") - msg = "Parameters to generic types must be types." - params = tuple(_type_check(p, msg) for p in 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 all(isinstance(p, TypeVar) for p in params): + if not all(isinstance(p, (TypeVar, ParamSpec)) for p in params): raise TypeError( - f"Parameters to {cls.__name__}[...] must all be type variables") + 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. - _check_generic(cls, params, len(cls.__parameters__)) - return _GenericAlias(cls, params) + if any(isinstance(t, ParamSpec) for t in cls.__parameters__): + params = _prepare_paramspec_params(cls, params) + else: + _check_generic(cls, params, len(cls.__parameters__)) + return _GenericAlias(cls, params, + _typevar_types=(TypeVar, ParamSpec), + _paramspec_tvars=True) def __init_subclass__(cls, *args, **kwargs): super().__init_subclass__(*args, **kwargs) @@ -1014,7 +1356,7 @@ class Generic: if error: raise TypeError("Cannot inherit from plain Generic") if '__orig_bases__' in cls.__dict__: - tvars = _collect_type_vars(cls.__orig_bases__) + tvars = _collect_type_vars(cls.__orig_bases__, (TypeVar, ParamSpec)) # Look for Generic[T1, ..., Tn]. # If found, tvars must be a subset of it. # If not found, tvars is it. @@ -1113,20 +1455,26 @@ def _no_init_or_replace_init(self, *args, **kwargs): cls.__init__(self, *args, **kwargs) +def _caller(depth=1, default='__main__'): + try: + return sys._getframe(depth + 1).f_globals.get('__name__', default) + except (AttributeError, ValueError): # For platforms without _getframe() + return None + -def _allow_reckless_class_cheks(): +def _allow_reckless_class_checks(depth=3): """Allow instance and class checks for special stdlib modules. The abc and functools modules indiscriminately call isinstance() and issubclass() on the whole MRO of a user class, which may contain protocols. """ try: - return sys._getframe(3).f_globals['__name__'] in ['abc', 'functools'] + return sys._getframe(depth).f_globals['__name__'] in ['abc', 'functools'] except (AttributeError, ValueError): # For platforms without _getframe(). return True -_PROTO_WHITELIST = { +_PROTO_ALLOWLIST = { 'collections.abc': [ 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', @@ -1141,6 +1489,14 @@ class _ProtocolMeta(ABCMeta): def __instancecheck__(cls, instance): # We need this method for situations where attributes are # assigned in __init__. + if ( + getattr(cls, '_is_protocol', False) and + not getattr(cls, '_is_runtime_protocol', False) and + not _allow_reckless_class_checks(depth=2) + ): + 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)): @@ -1203,12 +1559,12 @@ class Protocol(Generic, metaclass=_ProtocolMeta): # First, perform various sanity checks. if not getattr(cls, '_is_runtime_protocol', False): - if _allow_reckless_class_cheks(): + 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_cheks(): + if _allow_reckless_class_checks(): return NotImplemented raise TypeError("Protocols with non-method members" " don't support issubclass()") @@ -1245,8 +1601,8 @@ class Protocol(Generic, metaclass=_ProtocolMeta): # ... otherwise check consistency of bases, and prohibit instantiation. for base in cls.__bases__: if not (base in (object, Generic) or - base.__module__ in _PROTO_WHITELIST and - base.__name__ in _PROTO_WHITELIST[base.__module__] 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) @@ -1293,6 +1649,11 @@ class _AnnotatedAlias(_GenericAlias, _root=True): def __hash__(self): return hash((self.__origin__, self.__metadata__)) + def __getattr__(self, attr): + if attr in {'__name__', '__qualname__'}: + return 'Annotated' + return super().__getattr__(attr) + class Annotated: """Add context specific metadata to a type. @@ -1431,7 +1792,8 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): - If no dict arguments are passed, an attempt is made to use the globals from obj (or the respective module's globals for classes), and these are also used as the locals. If the object does not appear - to have globals, an empty dictionary is used. + to have globals, an empty dictionary is used. For classes, the search + order is globals first then locals. - If one dict argument is passed, it is used for both globals and locals. @@ -1447,16 +1809,27 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): hints = {} for base in reversed(obj.__mro__): if globalns is None: - base_globals = sys.modules[base.__module__].__dict__ + base_globals = getattr(sys.modules.get(base.__module__, None), '__dict__', {}) else: base_globals = globalns ann = base.__dict__.get('__annotations__', {}) + if isinstance(ann, types.GetSetDescriptorType): + ann = {} + base_locals = dict(vars(base)) if localns is None else localns + if localns is None and globalns is None: + # This is surprising, but required. Before Python 3.10, + # get_type_hints only evaluated the globalns of + # a class. To maintain backwards compatibility, we reverse + # the globalns and localns order so that eval() looks into + # *base_globals* first rather than *base_locals*. + # This only affects ForwardRefs. + base_globals, base_locals = base_locals, base_globals for name, value in ann.items(): if value is None: value = type(None) if isinstance(value, str): value = ForwardRef(value, is_argument=False, is_class=True) - value = _eval_type(value, base_globals, localns) + value = _eval_type(value, base_globals, base_locals) hints[name] = value return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} @@ -1516,6 +1889,12 @@ def _strip_annotations(t): if stripped_args == t.__args__: return t return GenericAlias(t.__origin__, stripped_args) + if isinstance(t, types.UnionType): + stripped_args = tuple(_strip_annotations(a) for a in t.__args__) + if stripped_args == t.__args__: + return t + return functools.reduce(operator.or_, stripped_args) + return t @@ -1532,13 +1911,17 @@ def get_origin(tp): 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 """ if isinstance(tp, _AnnotatedAlias): return Annotated - if isinstance(tp, (_BaseGenericAlias, GenericAlias)): + if isinstance(tp, (_BaseGenericAlias, GenericAlias, + ParamSpecArgs, ParamSpecKwargs)): return tp.__origin__ if tp is Generic: return Generic + if isinstance(tp, types.UnionType): + return types.UnionType return None @@ -1557,12 +1940,29 @@ def get_args(tp): return (tp.__origin__,) + tp.__metadata__ if isinstance(tp, (_GenericAlias, GenericAlias)): res = tp.__args__ - if tp.__origin__ is collections.abc.Callable and res[0] is not Ellipsis: + if (tp.__origin__ is collections.abc.Callable + and not (len(res) == 2 and _is_param_expr(res[0]))): res = (list(res[:-1]), res[-1]) return res + if isinstance(tp, types.UnionType): + return tp.__args__ return () +def is_typeddict(tp): + """Check if an annotation is a TypedDict class + + For example:: + class Film(TypedDict): + title: str + year: int + + is_typeddict(Film) # => True + is_typeddict(Union[list, str]) # => False + """ + return isinstance(tp, _TypedDictMeta) + + def no_type_check(arg): """Decorator to indicate that annotations are not type hints. @@ -2047,11 +2447,11 @@ _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) TypedDict.__mro_entries__ = lambda bases: (_TypedDict,) -def NewType(name, tp): +class NewType: """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 function that simply returns its argument. Usage:: + a dummy callable that simply returns its argument. Usage:: UserId = NewType('UserId', int) @@ -2066,12 +2466,30 @@ def NewType(name, tp): num = UserId(5) + 1 # type: int """ - def new_type(x): + def __init__(self, name, tp): + self.__qualname__ = name + if '.' in name: + name = name.rpartition('.')[-1] + self.__name__ = name + self.__supertype__ = tp + def_mod = _caller() + if def_mod != 'typing': + self.__module__ = def_mod + + def __repr__(self): + return f'{self.__module__}.{self.__qualname__}' + + def __call__(self, x): return x - new_type.__name__ = name - new_type.__supertype__ = tp - return new_type + def __reduce__(self): + return self.__qualname__ + + def __or__(self, other): + return Union[self, other] + + def __ror__(self, other): + return Union[other, self] # Python-version-specific alias (Python 2: unicode; Python 3: str) diff --git a/contrib/tools/python3/src/Lib/unittest/_log.py b/contrib/tools/python3/src/Lib/unittest/_log.py index 94e7e758bd9..94868e5bb95 100644 --- a/contrib/tools/python3/src/Lib/unittest/_log.py +++ b/contrib/tools/python3/src/Lib/unittest/_log.py @@ -26,11 +26,11 @@ class _CapturingHandler(logging.Handler): class _AssertLogsContext(_BaseTestCaseContext): - """A context manager used to implement TestCase.assertLogs().""" + """A context manager for assertLogs() and assertNoLogs() """ LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s" - def __init__(self, test_case, logger_name, level): + def __init__(self, test_case, logger_name, level, no_logs): _BaseTestCaseContext.__init__(self, test_case) self.logger_name = logger_name if level: @@ -38,6 +38,7 @@ class _AssertLogsContext(_BaseTestCaseContext): else: self.level = logging.INFO self.msg = None + self.no_logs = no_logs def __enter__(self): if isinstance(self.logger_name, logging.Logger): @@ -46,6 +47,7 @@ class _AssertLogsContext(_BaseTestCaseContext): logger = self.logger = logging.getLogger(self.logger_name) formatter = logging.Formatter(self.LOGGING_FORMAT) handler = _CapturingHandler() + handler.setLevel(self.level) handler.setFormatter(formatter) self.watcher = handler.watcher self.old_handlers = logger.handlers[:] @@ -54,16 +56,31 @@ class _AssertLogsContext(_BaseTestCaseContext): logger.handlers = [handler] logger.setLevel(self.level) logger.propagate = False + if self.no_logs: + return return handler.watcher def __exit__(self, exc_type, exc_value, tb): self.logger.handlers = self.old_handlers self.logger.propagate = self.old_propagate self.logger.setLevel(self.old_level) + if exc_type is not None: # let unexpected exceptions pass through return False - if len(self.watcher.records) == 0: - self._raiseFailure( - "no logs of level {} or higher triggered on {}" - .format(logging.getLevelName(self.level), self.logger.name)) + + if self.no_logs: + # assertNoLogs + if len(self.watcher.records) > 0: + self._raiseFailure( + "Unexpected logs found: {!r}".format( + self.watcher.output + ) + ) + + else: + # assertLogs + if len(self.watcher.records) == 0: + self._raiseFailure( + "no logs of level {} or higher triggered on {}" + .format(logging.getLevelName(self.level), self.logger.name)) diff --git a/contrib/tools/python3/src/Lib/unittest/async_case.py b/contrib/tools/python3/src/Lib/unittest/async_case.py index a2980e797ac..23231199f98 100644 --- a/contrib/tools/python3/src/Lib/unittest/async_case.py +++ b/contrib/tools/python3/src/Lib/unittest/async_case.py @@ -134,7 +134,7 @@ class IsolatedAsyncioTestCase(TestCase): task.cancel() loop.run_until_complete( - asyncio.gather(*to_cancel, loop=loop, return_exceptions=True)) + asyncio.gather(*to_cancel, return_exceptions=True)) for task in to_cancel: if task.cancelled(): diff --git a/contrib/tools/python3/src/Lib/unittest/case.py b/contrib/tools/python3/src/Lib/unittest/case.py index 88f1a408651..61003d0c6ea 100644 --- a/contrib/tools/python3/src/Lib/unittest/case.py +++ b/contrib/tools/python3/src/Lib/unittest/case.py @@ -295,7 +295,6 @@ class _AssertWarnsContext(_AssertRaisesBaseContext): self._raiseFailure("{} not triggered".format(exc_name)) - class _OrderedChainMap(collections.ChainMap): def __iter__(self): seen = set() @@ -794,7 +793,16 @@ class TestCase(object): """ # Lazy import to avoid importing logging if it is not needed. from ._log import _AssertLogsContext - return _AssertLogsContext(self, logger, level) + return _AssertLogsContext(self, logger, level, no_logs=False) + + def assertNoLogs(self, logger=None, level=None): + """ Fail unless no log messages of level *level* or higher are emitted + on *logger_name* or its children. + + This method must be used as a context manager. + """ + from ._log import _AssertLogsContext + return _AssertLogsContext(self, logger, level, no_logs=True) def _getAssertEqualityFunc(self, first, second): """Get a detailed comparison function for the types of the two args. @@ -1138,7 +1146,8 @@ class TestCase(object): def assertDictContainsSubset(self, subset, dictionary, msg=None): """Checks whether dictionary is a superset of subset.""" warnings.warn('assertDictContainsSubset is deprecated', - DeprecationWarning) + DeprecationWarning, + stacklevel=2) missing = [] mismatched = [] for key, value in subset.items(): diff --git a/contrib/tools/python3/src/Lib/unittest/mock.py b/contrib/tools/python3/src/Lib/unittest/mock.py index 3f5442ed809..7152f86ed96 100644 --- a/contrib/tools/python3/src/Lib/unittest/mock.py +++ b/contrib/tools/python3/src/Lib/unittest/mock.py @@ -36,6 +36,10 @@ from unittest.util import safe_repr from functools import wraps, partial +class InvalidSpecError(Exception): + """Indicates that an invalid value was used as a mock spec.""" + + _builtins = {name for name in dir(builtins) if not name.startswith('_')} FILTER_DIR = True @@ -631,9 +635,10 @@ class NonCallableMock(Base): elif _is_magic(name): raise AttributeError(name) if not self._mock_unsafe: - if name.startswith(('assert', 'assret')): - raise AttributeError("Attributes cannot start with 'assert' " - "or 'assret'") + if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')): + 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.") result = self._mock_children.get(name) if result is _deleted: @@ -652,10 +657,17 @@ class NonCallableMock(Base): self._mock_children[name] = result elif isinstance(result, _SpecState): - result = create_autospec( - result.spec, result.spec_set, result.instance, - result.parent, result.name - ) + try: + result = create_autospec( + result.spec, result.spec_set, result.instance, + result.parent, result.name + ) + except InvalidSpecError: + target_name = self.__dict__['_mock_name'] or self + raise InvalidSpecError( + f'Cannot autospec attr {name!r} from target ' + f'{target_name!r} as it has already been mocked out. ' + f'[target={self!r}, attr={result.spec!r}]') self._mock_children[name] = result return result @@ -1240,6 +1252,17 @@ def _importer(target): return thing +# _check_spec_arg_typos takes kwargs from commands like patch and checks that +# they don't contain common misspellings of arguments related to autospeccing. +def _check_spec_arg_typos(kwargs_to_check): + typos = ("autospect", "auto_spec", "set_spec") + for typo in typos: + if typo in kwargs_to_check: + raise RuntimeError( + f"{typo!r} might be a typo; use unsafe=True if this is intended" + ) + + class _patch(object): attribute_name = None @@ -1247,7 +1270,7 @@ class _patch(object): def __init__( self, getter, attribute, new, spec, create, - spec_set, autospec, new_callable, kwargs + spec_set, autospec, new_callable, kwargs, *, unsafe=False ): if new_callable is not None: if new is not DEFAULT: @@ -1258,6 +1281,16 @@ class _patch(object): raise ValueError( "Cannot use 'autospec' and 'new_callable' together" ) + if not unsafe: + _check_spec_arg_typos(kwargs) + if _is_instance_mock(spec): + raise InvalidSpecError( + f'Cannot spec attr {attribute!r} as the spec ' + f'has already been mocked out. [spec={spec!r}]') + if _is_instance_mock(spec_set): + raise InvalidSpecError( + f'Cannot spec attr {attribute!r} as the spec_set ' + f'target has already been mocked out. [spec_set={spec_set!r}]') self.getter = getter self.attribute = attribute @@ -1485,6 +1518,18 @@ class _patch(object): if autospec is True: autospec = original + if _is_instance_mock(self.target): + raise InvalidSpecError( + f'Cannot autospec attr {self.attribute!r} as the patch ' + f'target has already been mocked out. ' + f'[target={self.target!r}, attr={autospec!r}]') + if _is_instance_mock(autospec): + target_name = getattr(self.target, '__name__', self.target) + raise InvalidSpecError( + f'Cannot autospec attr {self.attribute!r} from target ' + f'{target_name!r} as it has already been mocked out. ' + f'[target={self.target!r}, attr={autospec!r}]') + new = create_autospec(autospec, spec_set=spec_set, _name=self.attribute, **kwargs) elif kwargs: @@ -1567,7 +1612,7 @@ def _get_target(target): def _patch_object( target, attribute, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, - new_callable=None, **kwargs + new_callable=None, *, unsafe=False, **kwargs ): """ patch the named member (`attribute`) on an object (`target`) with a mock @@ -1589,7 +1634,7 @@ def _patch_object( getter = lambda: target return _patch( getter, attribute, new, spec, create, - spec_set, autospec, new_callable, kwargs + spec_set, autospec, new_callable, kwargs, unsafe=unsafe ) @@ -1644,7 +1689,7 @@ def _patch_multiple(target, spec=None, create=False, spec_set=None, def patch( target, new=DEFAULT, spec=None, create=False, - spec_set=None, autospec=None, new_callable=None, **kwargs + spec_set=None, autospec=None, new_callable=None, *, unsafe=False, **kwargs ): """ `patch` acts as a function decorator, class decorator or a context @@ -1706,6 +1751,10 @@ def patch( use "as" then the patched object will be bound to the name after the "as"; very useful if `patch` is creating a mock object for you. + Patch will raise a `RuntimeError` if passed some common misspellings of + the arguments autospec and spec_set. Pass the argument `unsafe` with the + value True to disable that check. + `patch` takes arbitrary keyword arguments. These will be passed to `AsyncMock` if the patched object is asynchronous, to `MagicMock` otherwise or to `new_callable` if specified. @@ -1716,7 +1765,7 @@ def patch( getter, attribute = _get_target(target) return _patch( getter, attribute, new, spec, create, - spec_set, autospec, new_callable, kwargs + spec_set, autospec, new_callable, kwargs, unsafe=unsafe ) @@ -2566,7 +2615,7 @@ call = _Call(from_kall=False) def create_autospec(spec, spec_set=False, instance=False, _parent=None, - _name=None, **kwargs): + _name=None, *, unsafe=False, **kwargs): """Create a mock object using another object as a spec. Attributes on the mock will use the corresponding attribute on the `spec` object as their spec. @@ -2582,6 +2631,10 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, spec for an instance object by passing `instance=True`. The returned mock will only be callable if instances of the mock are callable. + `create_autospec` will raise a `RuntimeError` if passed some common + misspellings of the arguments autospec and spec_set. Pass the argument + `unsafe` with the value True to disable that check. + `create_autospec` also takes arbitrary keyword arguments that are passed to the constructor of the created mock.""" if _is_list(spec): @@ -2590,6 +2643,9 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, spec = type(spec) is_type = isinstance(spec, type) + if _is_instance_mock(spec): + raise InvalidSpecError(f'Cannot autospec a Mock object. ' + f'[object={spec!r}]') is_async_func = _is_async_func(spec) _kwargs = {'spec': spec} if spec_set: @@ -2599,6 +2655,8 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, _kwargs = {} if _kwargs and instance: _kwargs['_spec_as_instance'] = True + if not unsafe: + _check_spec_arg_typos(kwargs) _kwargs.update(kwargs) diff --git a/contrib/tools/python3/src/Lib/unittest/result.py b/contrib/tools/python3/src/Lib/unittest/result.py index 528d223850e..3da7005e603 100644 --- a/contrib/tools/python3/src/Lib/unittest/result.py +++ b/contrib/tools/python3/src/Lib/unittest/result.py @@ -175,7 +175,8 @@ class TestResult(object): exctype, value, tb = err tb = self._clean_tracebacks(exctype, value, tb, test) tb_e = traceback.TracebackException( - exctype, value, tb, capture_locals=self.tb_locals) + exctype, value, tb, + capture_locals=self.tb_locals, compact=True) msgLines = list(tb_e.format()) if self.buffer: diff --git a/contrib/tools/python3/src/Lib/urllib/parse.py b/contrib/tools/python3/src/Lib/urllib/parse.py index b7965fe3d2b..b35997bc00c 100644 --- a/contrib/tools/python3/src/Lib/urllib/parse.py +++ b/contrib/tools/python3/src/Lib/urllib/parse.py @@ -754,9 +754,8 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False, if max_num_fields < num_fields: raise ValueError('Max number of fields exceeded') - pairs = [s1 for s1 in qs.split(separator)] r = [] - for name_value in pairs: + for name_value in qs.split(separator): if not name_value and not strict_parsing: continue nv = name_value.split('=', 1) diff --git a/contrib/tools/python3/src/Lib/urllib/request.py b/contrib/tools/python3/src/Lib/urllib/request.py index 4e289fc67df..34b1b0b0b76 100644 --- a/contrib/tools/python3/src/Lib/urllib/request.py +++ b/contrib/tools/python3/src/Lib/urllib/request.py @@ -202,6 +202,8 @@ def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=cafile, capath=capath) + # send ALPN extension to indicate HTTP/1.1 protocol + context.set_alpn_protocols(['http/1.1']) https_handler = HTTPSHandler(context=context) opener = build_opener(https_handler) elif context: diff --git a/contrib/tools/python3/src/Lib/venv/scripts/common/Activate.ps1 b/contrib/tools/python3/src/Lib/venv/scripts/common/Activate.ps1 index 9d3646a4fc6..b49d77ba44b 100644 --- a/contrib/tools/python3/src/Lib/venv/scripts/common/Activate.ps1 +++ b/contrib/tools/python3/src/Lib/venv/scripts/common/Activate.ps1 @@ -96,6 +96,11 @@ function global:deactivate ([switch]$NonDestructive) { 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 @@ -228,6 +233,7 @@ if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " _OLD_VIRTUAL_PROMPT } + $env:VIRTUAL_ENV_PROMPT = $Prompt } # Clear PYTHONHOME diff --git a/contrib/tools/python3/src/Lib/venv/scripts/common/activate b/contrib/tools/python3/src/Lib/venv/scripts/common/activate index 45af3536aa1..6fbc2b8801d 100644 --- a/contrib/tools/python3/src/Lib/venv/scripts/common/activate +++ b/contrib/tools/python3/src/Lib/venv/scripts/common/activate @@ -28,6 +28,7 @@ deactivate () { fi unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT if [ ! "${1:-}" = "nondestructive" ] ; then # Self destruct! unset -f deactivate @@ -56,6 +57,8 @@ if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then _OLD_VIRTUAL_PS1="${PS1:-}" PS1="__VENV_PROMPT__${PS1:-}" export PS1 + VIRTUAL_ENV_PROMPT="__VENV_PROMPT__" + export VIRTUAL_ENV_PROMPT fi # This should detect bash and zsh, which have a hash command that must diff --git a/contrib/tools/python3/src/Lib/venv/scripts/nt/activate.bat b/contrib/tools/python3/src/Lib/venv/scripts/nt/activate.bat index f61413e2323..5daa45afc9f 100644 --- a/contrib/tools/python3/src/Lib/venv/scripts/nt/activate.bat +++ b/contrib/tools/python3/src/Lib/venv/scripts/nt/activate.bat @@ -25,6 +25,7 @@ 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 ( diff --git a/contrib/tools/python3/src/Lib/venv/scripts/nt/deactivate.bat b/contrib/tools/python3/src/Lib/venv/scripts/nt/deactivate.bat index 313c0791173..44dae495370 100644 --- a/contrib/tools/python3/src/Lib/venv/scripts/nt/deactivate.bat +++ b/contrib/tools/python3/src/Lib/venv/scripts/nt/deactivate.bat @@ -17,5 +17,6 @@ if defined _OLD_VIRTUAL_PATH ( set _OLD_VIRTUAL_PATH= set VIRTUAL_ENV= +set VIRTUAL_ENV_PROMPT= :END diff --git a/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.csh b/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.csh index 68a0dc74e1a..d6f697c55ed 100644 --- a/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.csh +++ b/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.csh @@ -3,7 +3,7 @@ # Created by Davide Di Blasi . # Ported to Python 3.3 venv by Andrew Svetlov -alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' # Unset irrelevant variables. deactivate nondestructive @@ -18,6 +18,7 @@ set _OLD_VIRTUAL_PROMPT="$prompt" if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then set prompt = "__VENV_PROMPT__$prompt" + setenv VIRTUAL_ENV_PROMPT "__VENV_PROMPT__" endif alias pydoc python -m pydoc diff --git a/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.fish b/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.fish index 54b9ea5676b..e40a1d71489 100644 --- a/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.fish +++ b/contrib/tools/python3/src/Lib/venv/scripts/posix/activate.fish @@ -20,6 +20,7 @@ function deactivate -d "Exit virtual environment and return to normal shell env end set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT if test "$argv[1]" != "nondestructive" # Self-destruct! functions -e deactivate @@ -61,4 +62,5 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" end set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT "__VENV_PROMPT__" end diff --git a/contrib/tools/python3/src/Lib/webbrowser.py b/contrib/tools/python3/src/Lib/webbrowser.py index 6023c1e1384..ec3cece48c9 100755 --- a/contrib/tools/python3/src/Lib/webbrowser.py +++ b/contrib/tools/python3/src/Lib/webbrowser.py @@ -1,5 +1,5 @@ #! /usr/bin/env python3 -"""Interfaces for launching and remotely controlling Web browsers.""" +"""Interfaces for launching and remotely controlling web browsers.""" # Maintained by Georg Brandl. import os @@ -532,6 +532,10 @@ def register_standard_browsers(): # OS X can use below Unix support (but we prefer using the OS X # specific stuff) + if sys.platform == "serenityos": + # SerenityOS webbrowser, simply called "Browser". + register("Browser", None, BackgroundBrowser("Browser")) + if sys.platform[:3] == "win": # First try to use the default Windows browser register("windows-default", WindowsDefault) diff --git a/contrib/tools/python3/src/Lib/xml/etree/ElementPath.py b/contrib/tools/python3/src/Lib/xml/etree/ElementPath.py index 880ea7bd991..a1170b572fe 100644 --- a/contrib/tools/python3/src/Lib/xml/etree/ElementPath.py +++ b/contrib/tools/python3/src/Lib/xml/etree/ElementPath.py @@ -65,8 +65,9 @@ xpath_tokenizer_re = re.compile( r"//?|" r"\.\.|" r"\(\)|" + r"!=|" r"[/.*:\[\]\(\)@=])|" - r"((?:\{[^}]+\})?[^/\[\]\(\)@=\s]+)|" + r"((?:\{[^}]+\})?[^/\[\]\(\)@!=\s]+)|" r"\s+" ) @@ -253,15 +254,19 @@ def prepare_predicate(next, token): if elem.get(key) is not None: yield elem return select - if signature == "@-='": - # [@attribute='value'] + if signature == "@-='" or signature == "@-!='": + # [@attribute='value'] or [@attribute!='value'] key = predicate[1] value = predicate[-1] def select(context, result): for elem in result: if elem.get(key) == value: yield elem - return select + def select_negated(context, result): + for elem in result: + if (attr_value := elem.get(key)) is not None and attr_value != value: + yield elem + return select_negated if '!=' in signature else select if signature == "-" and not re.match(r"\-?\d+$", predicate[0]): # [tag] tag = predicate[0] @@ -270,8 +275,10 @@ def prepare_predicate(next, token): if elem.find(tag) is not None: yield elem return select - if signature == ".='" or (signature == "-='" and not re.match(r"\-?\d+$", predicate[0])): - # [.='value'] or [tag='value'] + if signature == ".='" or signature == ".!='" or ( + (signature == "-='" or signature == "-!='") + and not re.match(r"\-?\d+$", predicate[0])): + # [.='value'] or [tag='value'] or [.!='value'] or [tag!='value'] tag = predicate[0] value = predicate[-1] if tag: @@ -281,12 +288,22 @@ def prepare_predicate(next, token): if "".join(e.itertext()) == value: yield elem break + def select_negated(context, result): + for elem in result: + for e in elem.iterfind(tag): + if "".join(e.itertext()) != value: + yield elem + break else: def select(context, result): for elem in result: if "".join(elem.itertext()) == value: yield elem - return select + def select_negated(context, result): + for elem in result: + if "".join(elem.itertext()) != value: + yield elem + return select_negated if '!=' in signature else select if signature == "-" or signature == "-()" or signature == "-()-": # [index] or [last()] or [last()-index] if signature == "-": diff --git a/contrib/tools/python3/src/Lib/xml/etree/ElementTree.py b/contrib/tools/python3/src/Lib/xml/etree/ElementTree.py index dae2251d859..07be8609b83 100644 --- a/contrib/tools/python3/src/Lib/xml/etree/ElementTree.py +++ b/contrib/tools/python3/src/Lib/xml/etree/ElementTree.py @@ -1562,7 +1562,6 @@ class XMLParser: # Configure pyexpat: buffering, new-style attribute handling. parser.buffer_text = 1 parser.ordered_attributes = 1 - parser.specified_attributes = 1 self._doctype = None self.entity = {} try: @@ -1582,7 +1581,6 @@ class XMLParser: for event_name in events_to_report: if event_name == "start": parser.ordered_attributes = 1 - parser.specified_attributes = 1 def handler(tag, attrib_in, event=event_name, append=append, start=self._start): append((event, start(tag, attrib_in))) diff --git a/contrib/tools/python3/src/Lib/xml/sax/handler.py b/contrib/tools/python3/src/Lib/xml/sax/handler.py index 481733d2cbe..e8d417e5194 100644 --- a/contrib/tools/python3/src/Lib/xml/sax/handler.py +++ b/contrib/tools/python3/src/Lib/xml/sax/handler.py @@ -340,3 +340,48 @@ all_properties = [property_lexical_handler, property_xml_string, property_encoding, property_interning_dict] + + +class LexicalHandler: + """Optional SAX2 handler for lexical events. + + This handler is used to obtain lexical information about an XML + document, that is, information about how the document was encoded + (as opposed to what it contains, which is reported to the + ContentHandler), such as comments and CDATA marked section + boundaries. + + To set the LexicalHandler of an XMLReader, use the setProperty + method with the property identifier + 'http://xml.org/sax/properties/lexical-handler'.""" + + def comment(self, content): + """Reports a comment anywhere in the document (including the + DTD and outside the document element). + + content is a string that holds the contents of the comment.""" + + def startDTD(self, name, public_id, system_id): + """Report the start of the DTD declarations, if the document + has an associated DTD. + + A startEntity event will be reported before declaration events + from the external DTD subset are reported, and this can be + used to infer from which subset DTD declarations derive. + + name is the name of the document element type, public_id the + public identifier of the DTD (or None if none were supplied) + and system_id the system identfier of the external subset (or + None if none were supplied).""" + + def endDTD(self): + """Signals the end of DTD declarations.""" + + def startCDATA(self): + """Reports the beginning of a CDATA marked section. + + The contents of the CDATA marked section will be reported + through the characters event.""" + + def endCDATA(self): + """Reports the end of a CDATA marked section.""" diff --git a/contrib/tools/python3/src/Lib/zipfile.py b/contrib/tools/python3/src/Lib/zipfile.py index 1e942a503e8..34d2fa4b864 100644 --- a/contrib/tools/python3/src/Lib/zipfile.py +++ b/contrib/tools/python3/src/Lib/zipfile.py @@ -16,6 +16,7 @@ import sys import threading import time import contextlib +import pathlib try: import zlib # We may need its compression method @@ -2206,13 +2207,12 @@ class CompleteDirs(ZipFile): if not isinstance(source, ZipFile): return cls(source) - # Only allow for FastPath when supplied zipfile is read-only + # Only allow for FastLookup when supplied zipfile is read-only if 'r' not in source.mode: cls = CompleteDirs - res = cls.__new__(cls) - vars(res).update(vars(source)) - return res + source.__class__ = cls + return source class FastLookup(CompleteDirs): @@ -2220,6 +2220,7 @@ class FastLookup(CompleteDirs): ZipFile subclass to ensure implicit dirs exist and are resolved rapidly. """ + def namelist(self): with contextlib.suppress(AttributeError): return self.__names @@ -2251,7 +2252,7 @@ class Path: >>> 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 = 'abcde.zip' + >>> zf.filename = 'mem/abcde.zip' Path accepts the zipfile object itself or a filename @@ -2263,9 +2264,9 @@ class Path: >>> a, b = root.iterdir() >>> a - Path('abcde.zip', 'a.txt') + Path('mem/abcde.zip', 'a.txt') >>> b - Path('abcde.zip', 'b/') + Path('mem/abcde.zip', 'b/') name property: @@ -2276,7 +2277,7 @@ class Path: >>> c = b / 'c.txt' >>> c - Path('abcde.zip', 'b/c.txt') + Path('mem/abcde.zip', 'b/c.txt') >>> c.name 'c.txt' @@ -2294,36 +2295,68 @@ class Path: Coercion to string: - >>> str(c) - 'abcde.zip/b/c.txt' + >>> 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, **kwargs): + 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(). """ - pwd = kwargs.pop('pwd', None) + 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 + else: + kwargs["encoding"] = io.text_encoding(kwargs.get("encoding")) return io.TextIOWrapper(stream, *args, **kwargs) @property def name(self): - return posixpath.basename(self.at.rstrip("/")) + return pathlib.Path(self.at).name or self.filename.name + + @property + def filename(self): + return pathlib.Path(self.root.filename).joinpath(self.at) def read_text(self, *args, **kwargs): + kwargs["encoding"] = io.text_encoding(kwargs.get("encoding")) with self.open('r', *args, **kwargs) as strm: return strm.read() @@ -2335,13 +2368,13 @@ class Path: return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") def _next(self, at): - return Path(self.root, at) + return self.__class__(self.root, at) def is_dir(self): return not self.at or self.at.endswith("/") def is_file(self): - return not self.is_dir() + return self.exists() and not self.is_dir() def exists(self): return self.at in self.root._name_set() @@ -2358,14 +2391,16 @@ class Path: def __repr__(self): return self.__repr.format(self=self) - def joinpath(self, add): - next = posixpath.join(self.at, add) + 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 += '/' diff --git a/contrib/tools/python3/src/Lib/zipimport.py b/contrib/tools/python3/src/Lib/zipimport.py index 5ef0a17c2a5..25eaee9c0f2 100644 --- a/contrib/tools/python3/src/Lib/zipimport.py +++ b/contrib/tools/python3/src/Lib/zipimport.py @@ -22,6 +22,7 @@ import _io # for open import marshal # for loads import sys # for modules import time # for mktime +import _warnings # For warn() __all__ = ['ZipImportError', 'zipimporter'] @@ -42,7 +43,7 @@ END_CENTRAL_DIR_SIZE = 22 STRING_END_ARCHIVE = b'PK\x05\x06' MAX_COMMENT_LEN = (1 << 16) - 1 -class zipimporter: +class zipimporter(_bootstrap_external._LoaderBasics): """zipimporter(archivepath) -> zipimporter object Create a new zipimporter instance. 'archivepath' must be a path to @@ -115,7 +116,12 @@ class zipimporter: 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. @@ -146,15 +152,46 @@ class 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. + + Returns None if the module cannot be found. + """ + module_info = _get_module_info(self, fullname) + if module_info is not None: + return _bootstrap.spec_from_loader(fullname, self, is_package=module_info) + else: + # 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. + path = f'{self.archive}{path_sep}{modpath}' + spec = _bootstrap.ModuleSpec(name=fullname, loader=None, + is_package=True) + spec.submodule_search_locations.append(path) + return spec + else: + return None def get_code(self, fullname): """get_code(fullname) -> code object. Return the code object for the specified module. Raise ZipImportError - if the module couldn't be found. + if the module couldn't be imported. """ code, ispackage, modpath = _get_module_code(self, fullname) return code @@ -184,7 +221,8 @@ class zipimporter: def get_filename(self, fullname): """get_filename(fullname) -> filename string. - Return the filename for the specified module. + Return the filename for the specified module or raise ZipImportError + if it couldn't be imported. """ # Deciding the filename requires working out where the code # would come from if the module was actually loaded @@ -236,8 +274,13 @@ class zipimporter: Load the module specified by 'fullname'. 'fullname' must be the fully qualified (dotted) module name. It returns the imported - module, or raises ZipImportError if it wasn't found. + module, or raises ZipImportError if it could not be imported. + + Deprecated since Python 3.10. Use exec_module() instead. """ + msg = ("zipimport.zipimporter.load_module() is deprecated and slated for " + "removal in Python 3.12; use exec_module() instead") + _warnings.warn(msg, DeprecationWarning) code, ispackage, modpath = _get_module_code(self, fullname) mod = sys.modules.get(fullname) if mod is None or not isinstance(mod, _module_type): @@ -280,11 +323,18 @@ class zipimporter: return None except ZipImportError: return None - if not _ZipImportResourceReader._registered: - from importlib.abc import ResourceReader - ResourceReader.register(_ZipImportResourceReader) - _ZipImportResourceReader._registered = True - return _ZipImportResourceReader(self, fullname) + from importlib.readers import ZipReader + return ZipReader(self, fullname) + + + def invalidate_caches(self): + """Reload the file data of the archive path.""" + try: + self._files = _read_directory(self.archive) + _zip_directory_cache[self.archive] = self._files + except ZipImportError: + _zip_directory_cache.pop(self.archive, None) + self._files = {} def __repr__(self): @@ -580,20 +630,15 @@ def _eq_mtime(t1, t2): # Given the contents of a .py[co] file, unmarshal the data -# and return the code object. Return None if it the magic word doesn't -# match, or if the recorded .py[co] metadata does not match the source, -# (we do this instead of raising an exception as we fall back -# to .py if available and we don't want to mask other errors). +# and return the code object. Raises ImportError it the magic word doesn't +# match, or if the recorded .py[co] metadata does not match the source. def _unmarshal_code(self, pathname, fullpath, fullname, data): exc_details = { 'name': fullname, 'path': fullpath, } - try: - flags = _bootstrap_external._classify_pyc(data, fullname, exc_details) - except ImportError: - return None + flags = _bootstrap_external._classify_pyc(data, fullname, exc_details) hash_based = flags & 0b1 != 0 if hash_based: @@ -607,11 +652,8 @@ def _unmarshal_code(self, pathname, fullpath, fullname, data): source_bytes, ) - try: - _bootstrap_external._validate_hash_pyc( - data, source_hash, fullname, exc_details) - except ImportError: - return None + _bootstrap_external._validate_hash_pyc( + data, source_hash, fullname, exc_details) else: source_mtime, source_size = \ _get_mtime_and_size_of_source(self, fullpath) @@ -697,6 +739,7 @@ def _get_pyc_source(self, path): # 'fullname'. def _get_module_code(self, fullname): path = _get_module_path(self, fullname) + import_error = None for suffix, isbytecode, ispackage in _zip_searchorder: fullpath = path + suffix _bootstrap._verbose_message('trying {}{}{}', self.archive, path_sep, fullpath, verbosity=2) @@ -707,8 +750,12 @@ def _get_module_code(self, fullname): else: modpath = toc_entry[0] data = _get_data(self.archive, toc_entry) + code = None if isbytecode: - code = _unmarshal_code(self, modpath, fullpath, fullname, data) + try: + code = _unmarshal_code(self, modpath, fullpath, fullname, data) + except ImportError as exc: + import_error = exc else: code = _compile_source(modpath, data) if code is None: @@ -718,75 +765,8 @@ def _get_module_code(self, fullname): modpath = toc_entry[0] return code, ispackage, modpath else: - raise ZipImportError(f"can't find module {fullname!r}", name=fullname) - - -class _ZipImportResourceReader: - """Private class used to support ZipImport.get_resource_reader(). - - This class is allowed to reference all the innards and private parts of - the zipimporter. - """ - _registered = False - - def __init__(self, zipimporter, fullname): - self.zipimporter = zipimporter - self.fullname = fullname - - def open_resource(self, resource): - fullname_as_path = self.fullname.replace('.', '/') - path = f'{fullname_as_path}/{resource}' - from io import BytesIO - try: - return BytesIO(self.zipimporter.get_data(path)) - except OSError: - raise FileNotFoundError(path) - - def resource_path(self, resource): - # All resources are in the zip file, so there is no path to the file. - # Raising FileNotFoundError tells the higher level API to extract the - # binary data and create a temporary file. - raise FileNotFoundError - - def is_resource(self, name): - # Maybe we could do better, but if we can get the data, it's a - # resource. Otherwise it isn't. - fullname_as_path = self.fullname.replace('.', '/') - path = f'{fullname_as_path}/{name}' - try: - self.zipimporter.get_data(path) - except OSError: - return False - return True - - def contents(self): - # This is a bit convoluted, because fullname will be a module path, - # but _files is a list of file names relative to the top of the - # archive's namespace. We want to compare file paths to find all the - # names of things inside the module represented by fullname. So we - # turn the module path of fullname into a file path relative to the - # top of the archive, and then we iterate through _files looking for - # names inside that "directory". - from pathlib import Path - fullname_path = Path(self.zipimporter.get_filename(self.fullname)) - relative_path = fullname_path.relative_to(self.zipimporter.archive) - # Don't forget that fullname names a package, so its path will include - # __init__.py, which we want to ignore. - assert relative_path.name == '__init__.py' - package_path = relative_path.parent - subdirs_seen = set() - for filename in self.zipimporter._files: - try: - relative = Path(filename).relative_to(package_path) - except ValueError: - continue - # If the path of the file (which is relative to the top of the zip - # namespace), relative to the package given when the resource - # reader was created, has a parent, then it's a name in a - # subdirectory and thus we skip it. - parent_name = relative.parent.name - if len(parent_name) == 0: - yield relative.name - elif parent_name not in subdirs_seen: - subdirs_seen.add(parent_name) - yield parent_name + if import_error: + msg = f"module load failed: {import_error}" + raise ZipImportError(msg, name=fullname) from import_error + else: + raise ZipImportError(f"can't find module {fullname!r}", name=fullname) diff --git a/contrib/tools/python3/src/Lib/zoneinfo/_common.py b/contrib/tools/python3/src/Lib/zoneinfo/_common.py index 41c898f37e4..4c24f01bd7b 100644 --- a/contrib/tools/python3/src/Lib/zoneinfo/_common.py +++ b/contrib/tools/python3/src/Lib/zoneinfo/_common.py @@ -136,8 +136,7 @@ class _TZifHeader: ] def __init__(self, *args): - assert len(self.__slots__) == len(args) - for attr, val in zip(self.__slots__, args): + for attr, val in zip(self.__slots__, args, strict=True): setattr(self, attr, val) @classmethod diff --git a/contrib/tools/python3/src/Modules/_abc.c b/contrib/tools/python3/src/Modules/_abc.c index 709b52ff96b..8aa68359039 100644 --- a/contrib/tools/python3/src/Modules/_abc.c +++ b/contrib/tools/python3/src/Modules/_abc.c @@ -1,6 +1,7 @@ /* ABCMeta implementation */ #include "Python.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "clinic/_abc.c.h" /*[clinic input] @@ -14,6 +15,7 @@ PyDoc_STRVAR(_abc__doc__, _Py_IDENTIFIER(__abstractmethods__); _Py_IDENTIFIER(__class__); _Py_IDENTIFIER(__dict__); +_Py_IDENTIFIER(__abc_tpflags__); _Py_IDENTIFIER(__bases__); _Py_IDENTIFIER(_abc_impl); _Py_IDENTIFIER(__subclasscheck__); @@ -27,7 +29,7 @@ typedef struct { static inline _abcmodule_state* get_abc_state(PyObject *module) { - void *state = PyModule_GetState(module); + void *state = _PyModule_GetState(module); assert(state != NULL); return (_abcmodule_state *)state; } @@ -416,6 +418,8 @@ error: return ret; } +#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING) + /*[clinic input] _abc._abc_init @@ -445,9 +449,64 @@ _abc__abc_init(PyObject *module, PyObject *self) return NULL; } Py_DECREF(data); + /* If __abc_tpflags__ & COLLECTION_FLAGS is set, then set the corresponding bit(s) + * in the new class. + * Used by collections.abc.Sequence and collections.abc.Mapping to indicate + * their special status w.r.t. pattern matching. */ + if (PyType_Check(self)) { + PyTypeObject *cls = (PyTypeObject *)self; + PyObject *flags = _PyDict_GetItemIdWithError(cls->tp_dict, &PyId___abc_tpflags__); + if (flags == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + } + else { + if (PyLong_CheckExact(flags)) { + long val = PyLong_AsLong(flags); + if (val == -1 && PyErr_Occurred()) { + return NULL; + } + if ((val & COLLECTION_FLAGS) == COLLECTION_FLAGS) { + PyErr_SetString(PyExc_TypeError, "__abc_tpflags__ cannot be both Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING"); + return NULL; + } + ((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS); + } + if (_PyDict_DelItemId(cls->tp_dict, &PyId___abc_tpflags__) < 0) { + return NULL; + } + } + } Py_RETURN_NONE; } +static void +set_collection_flag_recursive(PyTypeObject *child, unsigned long flag) +{ + assert(flag == Py_TPFLAGS_MAPPING || flag == Py_TPFLAGS_SEQUENCE); + if (PyType_HasFeature(child, Py_TPFLAGS_IMMUTABLETYPE) || + (child->tp_flags & COLLECTION_FLAGS) == flag) + { + return; + } + child->tp_flags &= ~COLLECTION_FLAGS; + child->tp_flags |= flag; + PyObject *grandchildren = child->tp_subclasses; + if (grandchildren == NULL) { + return; + } + assert(PyDict_CheckExact(grandchildren)); + Py_ssize_t i = 0; + while (PyDict_Next(grandchildren, &i, NULL, &grandchildren)) { + assert(PyWeakref_CheckRef(grandchildren)); + PyObject *grandchild = PyWeakref_GET_OBJECT(grandchildren); + if (PyType_Check(grandchild)) { + set_collection_flag_recursive((PyTypeObject *)grandchild, flag); + } + } +} + /*[clinic input] _abc._abc_register @@ -498,6 +557,13 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) /* Invalidate negative cache */ get_abc_state(module)->abc_invalidation_counter++; + /* Set Py_TPFLAGS_SEQUENCE or Py_TPFLAGS_MAPPING flag */ + if (PyType_Check(self)) { + unsigned long collection_flag = ((PyTypeObject *)self)->tp_flags & COLLECTION_FLAGS; + if (collection_flag) { + set_collection_flag_recursive((PyTypeObject *)subclass, collection_flag); + } + } Py_INCREF(subclass); return subclass; } @@ -891,14 +957,14 @@ static PyModuleDef_Slot _abcmodule_slots[] = { static struct PyModuleDef _abcmodule = { PyModuleDef_HEAD_INIT, - "_abc", - _abc__doc__, - sizeof(_abcmodule_state), - _abcmodule_methods, - _abcmodule_slots, - _abcmodule_traverse, - _abcmodule_clear, - _abcmodule_free, + .m_name = "_abc", + .m_doc = _abc__doc__, + .m_size = sizeof(_abcmodule_state), + .m_methods = _abcmodule_methods, + .m_slots = _abcmodule_slots, + .m_traverse = _abcmodule_traverse, + .m_clear = _abcmodule_clear, + .m_free = _abcmodule_free, }; PyMODINIT_FUNC diff --git a/contrib/tools/python3/src/Modules/_asynciomodule.c b/contrib/tools/python3/src/Modules/_asynciomodule.c index b64069a25a7..392e0e7c735 100644 --- a/contrib/tools/python3/src/Modules/_asynciomodule.c +++ b/contrib/tools/python3/src/Modules/_asynciomodule.c @@ -16,7 +16,6 @@ _Py_IDENTIFIER(add_done_callback); _Py_IDENTIFIER(call_soon); _Py_IDENTIFIER(cancel); _Py_IDENTIFIER(get_event_loop); -_Py_IDENTIFIER(send); _Py_IDENTIFIER(throw); @@ -94,11 +93,6 @@ typedef struct { PyObject *sw_arg; } TaskStepMethWrapper; -typedef struct { - PyObject_HEAD - TaskObj *ww_task; -} TaskWakeupMethWrapper; - typedef struct { PyObject_HEAD PyObject *rl_loop; @@ -325,7 +319,7 @@ set_running_loop(PyObject *loop) static PyObject * -get_event_loop(void) +get_event_loop(int stacklevel) { PyObject *loop; PyObject *policy; @@ -337,6 +331,13 @@ get_event_loop(void) return loop; } + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "There is no current event loop", + stacklevel)) + { + return NULL; + } + policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy); if (policy == NULL) { return NULL; @@ -495,7 +496,7 @@ future_init(FutureObj *fut, PyObject *loop) fut->fut_blocking = 0; if (loop == Py_None) { - loop = get_event_loop(); + loop = get_event_loop(1); if (loop == NULL) { return -1; } @@ -714,6 +715,7 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) else { fut->fut_callbacks = PyList_New(1); if (fut->fut_callbacks == NULL) { + Py_DECREF(tup); return NULL; } @@ -1477,7 +1479,8 @@ finally: static PyAsyncMethods FutureType_as_async = { (unaryfunc)future_new_iter, /* am_await */ 0, /* am_aiter */ - 0 /* am_anext */ + 0, /* am_anext */ + 0, /* am_send */ }; static PyMethodDef FutureType_methods[] = { @@ -1595,37 +1598,61 @@ FutureIter_dealloc(futureiterobject *it) } } -static PyObject * -FutureIter_iternext(futureiterobject *it) +static PySendResult +FutureIter_am_send(futureiterobject *it, + PyObject *Py_UNUSED(arg), + PyObject **result) { + /* arg is unused, see the comment on FutureIter_send for clarification */ + PyObject *res; FutureObj *fut = it->future; + *result = NULL; if (fut == NULL) { - return NULL; + return PYGEN_ERROR; } if (fut->fut_state == STATE_PENDING) { if (!fut->fut_blocking) { fut->fut_blocking = 1; Py_INCREF(fut); - return (PyObject *)fut; + *result = (PyObject *)fut; + return PYGEN_NEXT; } PyErr_SetString(PyExc_RuntimeError, "await wasn't used with future"); - return NULL; + return PYGEN_ERROR; } it->future = NULL; res = _asyncio_Future_result_impl(fut); if (res != NULL) { - /* The result of the Future is not an exception. */ - (void)_PyGen_SetStopIterationValue(res); - Py_DECREF(res); + Py_DECREF(fut); + *result = res; + return PYGEN_RETURN; } Py_DECREF(fut); - return NULL; + return PYGEN_ERROR; +} + +static PyObject * +FutureIter_iternext(futureiterobject *it) +{ + PyObject *result; + switch (FutureIter_am_send(it, Py_None, &result)) { + case PYGEN_RETURN: + (void)_PyGen_SetStopIterationValue(result); + Py_DECREF(result); + return NULL; + case PYGEN_NEXT: + return result; + case PYGEN_ERROR: + return NULL; + default: + Py_UNREACHABLE(); + } } static PyObject * @@ -1714,12 +1741,21 @@ 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 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, @@ -1863,93 +1899,15 @@ TaskStepMethWrapper_new(TaskObj *task, PyObject *arg) return (PyObject*) o; } -/* ----- Task._wakeup wrapper */ - -static PyObject * -TaskWakeupMethWrapper_call(TaskWakeupMethWrapper *o, - PyObject *args, PyObject *kwds) -{ - PyObject *fut; - - if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) { - PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments"); - return NULL; - } - if (!PyArg_ParseTuple(args, "O", &fut)) { - return NULL; - } - - return task_wakeup(o->ww_task, fut); -} - -static int -TaskWakeupMethWrapper_clear(TaskWakeupMethWrapper *o) -{ - Py_CLEAR(o->ww_task); - return 0; -} - -static int -TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o, - visitproc visit, void *arg) -{ - Py_VISIT(o->ww_task); - return 0; -} - -static void -TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) -{ - PyObject_GC_UnTrack(o); - (void)TaskWakeupMethWrapper_clear(o); - Py_TYPE(o)->tp_free(o); -} - -static PyObject * -TaskWakeupMethWrapper_get___self__(TaskWakeupMethWrapper *o, void *Py_UNUSED(ignored)) -{ - if (o->ww_task) { - Py_INCREF(o->ww_task); - return (PyObject*)o->ww_task; - } - Py_RETURN_NONE; -} - -static PyGetSetDef TaskWakeupMethWrapper_getsetlist[] = { - {"__self__", (getter)TaskWakeupMethWrapper_get___self__, NULL, NULL}, - {NULL} /* Sentinel */ -}; +/* ----- Task._wakeup implementation */ -static PyTypeObject TaskWakeupMethWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "TaskWakeupMethWrapper", - .tp_basicsize = sizeof(TaskWakeupMethWrapper), - .tp_itemsize = 0, - .tp_dealloc = (destructor)TaskWakeupMethWrapper_dealloc, - .tp_call = (ternaryfunc)TaskWakeupMethWrapper_call, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)TaskWakeupMethWrapper_traverse, - .tp_clear = (inquiry)TaskWakeupMethWrapper_clear, - .tp_getset = TaskWakeupMethWrapper_getsetlist, +static PyMethodDef TaskWakeupDef = { + "task_wakeup", + (PyCFunction)task_wakeup, + METH_O, + NULL }; -static PyObject * -TaskWakeupMethWrapper_new(TaskObj *task) -{ - TaskWakeupMethWrapper *o; - o = PyObject_GC_New(TaskWakeupMethWrapper, &TaskWakeupMethWrapper_Type); - if (o == NULL) { - return NULL; - } - - Py_INCREF(task); - o->ww_task = task; - - PyObject_GC_Track(o); - return (PyObject*) o; -} - /* ----- Task introspection helpers */ static int @@ -2606,6 +2564,20 @@ task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) Py_RETURN_NONE; } +static inline int +gen_status_from_result(PyObject **result) +{ + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + + assert(PyErr_Occurred()); + return PYGEN_ERROR; +} + static PyObject * task_step_impl(TaskObj *task, PyObject *exc) { @@ -2664,26 +2636,23 @@ task_step_impl(TaskObj *task, PyObject *exc) return NULL; } + int gen_status = PYGEN_ERROR; if (exc == NULL) { - if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { - result = _PyGen_Send((PyGenObject*)coro, Py_None); - } - else { - result = _PyObject_CallMethodIdOneArg(coro, &PyId_send, Py_None); - } + gen_status = PyIter_Send(coro, Py_None, &result); } else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); + gen_status = gen_status_from_result(&result); if (clear_exc) { /* We created 'exc' during this call */ Py_DECREF(exc); } } - if (result == NULL) { + if (gen_status == PYGEN_RETURN || gen_status == PYGEN_ERROR) { PyObject *et, *ev, *tb; - if (_PyGen_FetchStopIterationValue(&o) == 0) { + if (result != NULL) { /* The error is StopIteration and that means that the underlying coroutine has resolved */ @@ -2694,10 +2663,10 @@ task_step_impl(TaskObj *task, PyObject *exc) res = future_cancel((FutureObj*)task, task->task_cancel_msg); } else { - res = future_set_result((FutureObj*)task, o); + res = future_set_result((FutureObj*)task, result); } - Py_DECREF(o); + Py_DECREF(result); if (res == NULL) { return NULL; @@ -2778,7 +2747,7 @@ task_step_impl(TaskObj *task, PyObject *exc) fut->fut_blocking = 0; /* result.add_done_callback(task._wakeup) */ - wrapper = TaskWakeupMethWrapper_new(task); + wrapper = PyCFunction_New(&TaskWakeupDef, (PyObject *)task); if (wrapper == NULL) { goto fail; } @@ -2859,7 +2828,7 @@ task_step_impl(TaskObj *task, PyObject *exc) goto fail; } - wrapper = TaskWakeupMethWrapper_new(task); + wrapper = PyCFunction_New(&TaskWakeupDef, (PyObject *)task); if (wrapper == NULL) { goto fail; } @@ -3101,7 +3070,19 @@ static PyObject * _asyncio_get_event_loop_impl(PyObject *module) /*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/ { - return get_event_loop(); + return get_event_loop(1); +} + +/*[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); } /*[clinic input] @@ -3399,6 +3380,7 @@ PyDoc_STRVAR(module_doc, "Accelerator module for asyncio"); static PyMethodDef asyncio_methods[] = { _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 @@ -3434,9 +3416,6 @@ PyInit__asyncio(void) if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) { return NULL; } - if (PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) { - return NULL; - } if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) { return NULL; } diff --git a/contrib/tools/python3/src/Modules/_bisectmodule.c b/contrib/tools/python3/src/Modules/_bisectmodule.c index 82d800d9a87..26c4b9bfb26 100644 --- a/contrib/tools/python3/src/Modules/_bisectmodule.c +++ b/contrib/tools/python3/src/Modules/_bisectmodule.c @@ -16,7 +16,8 @@ module _bisect _Py_IDENTIFIER(insert); static inline Py_ssize_t -internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) +internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi, + PyObject* key) { PyObject *litem; Py_ssize_t mid; @@ -39,6 +40,14 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t litem = PySequence_GetItem(list, mid); if (litem == NULL) return -1; + if (key != Py_None) { + PyObject *newitem = PyObject_CallOneArg(key, litem); + if (newitem == NULL) { + Py_DECREF(litem); + return -1; + } + Py_SETREF(litem, newitem); + } res = PyObject_RichCompareBool(item, litem, Py_LT); Py_DECREF(litem); if (res < 0) @@ -58,12 +67,14 @@ _bisect.bisect_right -> Py_ssize_t x: object lo: Py_ssize_t = 0 hi: Py_ssize_t(c_default='-1', accept={int, NoneType}) = None + * + key: object = None Return the index where to insert item x in list a, assuming a is sorted. The return value i is such that all e in a[:i] have e <= x, and all e in -a[i:] have e > x. So if x already appears in the list, i points just -beyond the rightmost x already there +a[i:] have e > x. So if x already appears in the list, a.insert(i, x) will +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. @@ -71,10 +82,10 @@ slice of a to be searched. static Py_ssize_t _bisect_bisect_right_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi) -/*[clinic end generated code: output=419e150cf1d2a235 input=e72212b282c83375]*/ + Py_ssize_t lo, Py_ssize_t hi, PyObject *key) +/*[clinic end generated code: output=3a4bc09cc7c8a73d input=40fcc5afa06ae593]*/ { - return internal_bisect_right(a, x, lo, hi); + return internal_bisect_right(a, x, lo, hi, key); } /*[clinic input] @@ -84,6 +95,8 @@ _bisect.insort_right x: object lo: Py_ssize_t = 0 hi: Py_ssize_t(c_default='-1', accept={int, NoneType}) = None + * + key: object = None Insert item x in list a, and keep it sorted assuming a is sorted. @@ -95,11 +108,22 @@ slice of a to be searched. static PyObject * _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi) -/*[clinic end generated code: output=c2caa3d4cd02035a input=d1c45bfa68182669]*/ + Py_ssize_t lo, Py_ssize_t hi, PyObject *key) +/*[clinic end generated code: output=ac3bf26d07aedda2 input=44e1708e26b7b802]*/ { - PyObject *result; - Py_ssize_t index = internal_bisect_right(a, x, lo, hi); + PyObject *result, *key_x; + Py_ssize_t index; + + if (key == Py_None) { + index = internal_bisect_right(a, x, lo, hi, key); + } else { + key_x = PyObject_CallOneArg(key, x); + if (x == NULL) { + return NULL; + } + index = internal_bisect_right(a, key_x, lo, hi, key); + Py_DECREF(key_x); + } if (index < 0) return NULL; if (PyList_CheckExact(a)) { @@ -117,7 +141,8 @@ _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, } static inline Py_ssize_t -internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) +internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi, + PyObject *key) { PyObject *litem; Py_ssize_t mid; @@ -140,6 +165,14 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h litem = PySequence_GetItem(list, mid); if (litem == NULL) return -1; + if (key != Py_None) { + PyObject *newitem = PyObject_CallOneArg(key, litem); + if (newitem == NULL) { + Py_DECREF(litem); + return -1; + } + Py_SETREF(litem, newitem); + } res = PyObject_RichCompareBool(litem, item, Py_LT); Py_DECREF(litem); if (res < 0) @@ -160,12 +193,14 @@ _bisect.bisect_left -> Py_ssize_t x: object lo: Py_ssize_t = 0 hi: Py_ssize_t(c_default='-1', accept={int, NoneType}) = None + * + key: object = None Return the index where to insert item x in list a, assuming a is sorted. The return value i is such that all e in a[:i] have e < x, and all e in -a[i:] have e >= x. So if x already appears in the list, i points just -before the leftmost x already there. +a[i:] have e >= x. So if x already appears in the list, a.insert(i, x) will +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. @@ -173,10 +208,10 @@ slice of a to be searched. static Py_ssize_t _bisect_bisect_left_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi) -/*[clinic end generated code: output=af82168bc2856f24 input=2bd90f34afe5609f]*/ + Py_ssize_t lo, Py_ssize_t hi, PyObject *key) +/*[clinic end generated code: output=70749d6e5cae9284 input=90dd35b50ceb05e3]*/ { - return internal_bisect_left(a, x, lo, hi); + return internal_bisect_left(a, x, lo, hi, key); } @@ -187,6 +222,8 @@ _bisect.insort_left x: object lo: Py_ssize_t = 0 hi: Py_ssize_t(c_default='-1', accept={int, NoneType}) = None + * + key: object = None Insert item x in list a, and keep it sorted assuming a is sorted. @@ -198,11 +235,22 @@ slice of a to be searched. static PyObject * _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi) -/*[clinic end generated code: output=9e8356c0844a182b input=bc4583308bce00cc]*/ + Py_ssize_t lo, Py_ssize_t hi, PyObject *key) +/*[clinic end generated code: output=b1d33e5e7ffff11e input=3ab65d8784f585b1]*/ { - PyObject *result; - Py_ssize_t index = internal_bisect_left(a, x, lo, hi); + PyObject *result, *key_x; + Py_ssize_t index; + + if (key == Py_None) { + index = internal_bisect_left(a, x, lo, hi, key); + } else { + key_x = PyObject_CallOneArg(key, x); + if (x == NULL) { + return NULL; + } + index = internal_bisect_left(a, key_x, lo, hi, key); + Py_DECREF(key_x); + } if (index < 0) return NULL; if (PyList_CheckExact(a)) { @@ -237,18 +285,14 @@ common approach.\n"); static struct PyModuleDef _bisectmodule = { PyModuleDef_HEAD_INIT, - "_bisect", - module_doc, - -1, - bisect_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_bisect", + .m_doc = module_doc, + .m_methods = bisect_methods, + .m_size = 0 }; PyMODINIT_FUNC PyInit__bisect(void) { - return PyModule_Create(&_bisectmodule); + return PyModuleDef_Init(&_bisectmodule); } diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c b/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c index 7fb1296f8b2..8b0d60d02ac 100644 --- a/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c +++ b/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c @@ -34,7 +34,7 @@ #endif -extern PyTypeObject PyBlake2_BLAKE2bType; +extern PyType_Spec blake2b_type_spec; typedef struct { PyObject_HEAD @@ -391,47 +391,24 @@ py_blake2b_dealloc(PyObject *self) PyThread_free_lock(obj->lock); obj->lock = NULL; } - PyObject_Del(self); + + PyTypeObject *type = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(type); } +static PyType_Slot blake2b_type_slots[] = { + {Py_tp_dealloc, py_blake2b_dealloc}, + {Py_tp_doc, (char *)py_blake2b_new__doc__}, + {Py_tp_methods, py_blake2b_methods}, + {Py_tp_getset, py_blake2b_getsetters}, + {Py_tp_new, py_blake2b_new}, + {0,0} +}; -PyTypeObject PyBlake2_BLAKE2bType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2b", /* tp_name */ - sizeof(BLAKE2bObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2b_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, /* tp_flags */ - py_blake2b_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2b_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2b_getsetters, /* 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 */ - py_blake2b_new, /* tp_new */ +PyType_Spec blake2b_type_spec = { + .name = "_blake2.blake2b", + .basicsize = sizeof(BLAKE2bObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, + .slots = blake2b_type_slots }; diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2module.c b/contrib/tools/python3/src/Modules/_blake2/blake2module.c index ff142c9f3ed..631de2cc0ab 100644 --- a/contrib/tools/python3/src/Modules/_blake2/blake2module.c +++ b/contrib/tools/python3/src/Modules/_blake2/blake2module.c @@ -12,62 +12,81 @@ #include "impl/blake2.h" -extern PyTypeObject PyBlake2_BLAKE2bType; -extern PyTypeObject PyBlake2_BLAKE2sType; - +extern PyType_Spec blake2b_type_spec; +extern PyType_Spec blake2s_type_spec; PyDoc_STRVAR(blake2mod__doc__, "_blake2b provides BLAKE2b for hashlib\n" ); +typedef struct { + PyTypeObject* blake2b_type; + PyTypeObject* blake2s_type; +} Blake2State; + +static inline Blake2State* +blake2_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (Blake2State *)state; +} static struct PyMethodDef blake2mod_functions[] = { {NULL, NULL} }; -static struct PyModuleDef blake2_module = { - PyModuleDef_HEAD_INIT, - "_blake2", - blake2mod__doc__, - -1, - blake2mod_functions, - NULL, - NULL, - NULL, - NULL -}; +static int +_blake2_traverse(PyObject *module, visitproc visit, void *arg) +{ + Blake2State *state = blake2_get_state(module); + Py_VISIT(state->blake2b_type); + Py_VISIT(state->blake2s_type); + return 0; +} + +static int +_blake2_clear(PyObject *module) +{ + Blake2State *state = blake2_get_state(module); + Py_CLEAR(state->blake2b_type); + Py_CLEAR(state->blake2s_type); + return 0; +} + +static void +_blake2_free(void *module) +{ + _blake2_clear((PyObject *)module); +} #define ADD_INT(d, name, value) do { \ PyObject *x = PyLong_FromLong(value); \ - if (!x) { \ - Py_DECREF(m); \ - return NULL; \ - } \ + if (!x) \ + return -1; \ if (PyDict_SetItemString(d, name, x) < 0) { \ - Py_DECREF(m); \ - return NULL; \ + Py_DECREF(x); \ + return -1; \ } \ Py_DECREF(x); \ } while(0) - -PyMODINIT_FUNC -PyInit__blake2(void) +static int +blake2_exec(PyObject *m) { - PyObject *m; - PyObject *d; + Blake2State* st = blake2_get_state(m); - m = PyModule_Create(&blake2_module); - if (m == NULL) - return NULL; + st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &blake2b_type_spec, NULL); + if (NULL == st->blake2b_type) + return -1; /* BLAKE2b */ - Py_SET_TYPE(&PyBlake2_BLAKE2bType, &PyType_Type); - if (PyModule_AddType(m, &PyBlake2_BLAKE2bType) < 0) { - return NULL; + if (PyModule_AddType(m, st->blake2b_type) < 0) { + return -1; } - d = PyBlake2_BLAKE2bType.tp_dict; + PyObject *d = st->blake2b_type->tp_dict; ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES); ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES); ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES); @@ -79,12 +98,17 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); /* BLAKE2s */ - Py_SET_TYPE(&PyBlake2_BLAKE2sType, &PyType_Type); - if (PyModule_AddType(m, &PyBlake2_BLAKE2sType) < 0) { - return NULL; + st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &blake2s_type_spec, NULL); + + if (NULL == st->blake2s_type) + return -1; + + if (PyModule_AddType(m, st->blake2s_type) < 0) { + return -1; } - d = PyBlake2_BLAKE2sType.tp_dict; + d = st->blake2s_type->tp_dict; ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES); ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES); ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES); @@ -95,5 +119,28 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); - return m; + return 0; } + +static PyModuleDef_Slot _blake2_slots[] = { + {Py_mod_exec, blake2_exec}, + {0, NULL} +}; + +static struct PyModuleDef blake2_module = { + PyModuleDef_HEAD_INIT, + "_blake2", + .m_doc = blake2mod__doc__, + .m_size = sizeof(Blake2State), + .m_methods = blake2mod_functions, + .m_slots = _blake2_slots, + .m_traverse = _blake2_traverse, + .m_clear = _blake2_clear, + .m_free = _blake2_free, +}; + +PyMODINIT_FUNC +PyInit__blake2(void) +{ + return PyModuleDef_Init(&blake2_module); +} \ No newline at end of file diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c b/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c index e3e90d0587b..7ab3917aa1a 100644 --- a/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c +++ b/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c @@ -33,8 +33,7 @@ #include "impl/blake2s-ref.c" #endif - -extern PyTypeObject PyBlake2_BLAKE2sType; +extern PyType_Spec blake2s_type_spec; typedef struct { PyObject_HEAD @@ -391,47 +390,24 @@ py_blake2s_dealloc(PyObject *self) PyThread_free_lock(obj->lock); obj->lock = NULL; } - PyObject_Del(self); + + PyTypeObject *type = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(type); } +static PyType_Slot blake2s_type_slots[] = { + {Py_tp_dealloc, py_blake2s_dealloc}, + {Py_tp_doc, (char *)py_blake2s_new__doc__}, + {Py_tp_methods, py_blake2s_methods}, + {Py_tp_getset, py_blake2s_getsetters}, + {Py_tp_new, py_blake2s_new}, + {0,0} +}; -PyTypeObject PyBlake2_BLAKE2sType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2s", /* tp_name */ - sizeof(BLAKE2sObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2s_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, /* tp_flags */ - py_blake2s_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2s_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2s_getsetters, /* 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 */ - py_blake2s_new, /* tp_new */ +PyType_Spec blake2s_type_spec = { + .name = "_blake2.blake2s", + .basicsize = sizeof(BLAKE2sObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, + .slots = blake2s_type_slots }; diff --git a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h index 07258c31c9b..4e74e0885cf 100644 --- a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h @@ -56,11 +56,6 @@ skip_optional_posonly: goto skip_optional_kwonly; } if (fastargs[1]) { - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } digest_size = _PyLong_AsInt(fastargs[1]); if (digest_size == -1 && PyErr_Occurred()) { goto exit; @@ -106,11 +101,6 @@ skip_optional_posonly: } } if (fastargs[5]) { - if (PyFloat_Check(fastargs[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fanout = _PyLong_AsInt(fastargs[5]); if (fanout == -1 && PyErr_Occurred()) { goto exit; @@ -120,11 +110,6 @@ skip_optional_posonly: } } if (fastargs[6]) { - if (PyFloat_Check(fastargs[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } depth = _PyLong_AsInt(fastargs[6]); if (depth == -1 && PyErr_Occurred()) { goto exit; @@ -150,11 +135,6 @@ skip_optional_posonly: } } if (fastargs[9]) { - if (PyFloat_Check(fastargs[9])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } node_depth = _PyLong_AsInt(fastargs[9]); if (node_depth == -1 && PyErr_Occurred()) { goto exit; @@ -164,11 +144,6 @@ skip_optional_posonly: } } if (fastargs[10]) { - if (PyFloat_Check(fastargs[10])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } inner_size = _PyLong_AsInt(fastargs[10]); if (inner_size == -1 && PyErr_Occurred()) { goto exit; @@ -272,4 +247,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=2d6d0fe9aa42a42a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=10eb47aba77f192d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h index 71c5706fb66..0f0d9835fbf 100644 --- a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h @@ -56,11 +56,6 @@ skip_optional_posonly: goto skip_optional_kwonly; } if (fastargs[1]) { - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } digest_size = _PyLong_AsInt(fastargs[1]); if (digest_size == -1 && PyErr_Occurred()) { goto exit; @@ -106,11 +101,6 @@ skip_optional_posonly: } } if (fastargs[5]) { - if (PyFloat_Check(fastargs[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fanout = _PyLong_AsInt(fastargs[5]); if (fanout == -1 && PyErr_Occurred()) { goto exit; @@ -120,11 +110,6 @@ skip_optional_posonly: } } if (fastargs[6]) { - if (PyFloat_Check(fastargs[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } depth = _PyLong_AsInt(fastargs[6]); if (depth == -1 && PyErr_Occurred()) { goto exit; @@ -150,11 +135,6 @@ skip_optional_posonly: } } if (fastargs[9]) { - if (PyFloat_Check(fastargs[9])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } node_depth = _PyLong_AsInt(fastargs[9]); if (node_depth == -1 && PyErr_Occurred()) { goto exit; @@ -164,11 +144,6 @@ skip_optional_posonly: } } if (fastargs[10]) { - if (PyFloat_Check(fastargs[10])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } inner_size = _PyLong_AsInt(fastargs[10]); if (inner_size == -1 && PyErr_Occurred()) { goto exit; @@ -272,4 +247,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=c80d8d06ce40a192 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f7ee8092ed67e9c7 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_bz2module.c b/contrib/tools/python3/src/Modules/_bz2module.c index 880632c6234..798e9efc628 100644 --- a/contrib/tools/python3/src/Modules/_bz2module.c +++ b/contrib/tools/python3/src/Modules/_bz2module.c @@ -8,6 +8,59 @@ #include #include +// Blocks output buffer wrappers +#include "pycore_blocks_output_buffer.h" + +#if OUTPUT_BUFFER_MAX_BLOCK_SIZE > UINT32_MAX + #error "The maximum block size accepted by libbzip2 is UINT32_MAX." +#endif + +/* On success, return value >= 0 + On failure, return -1 */ +static inline Py_ssize_t +OutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer, Py_ssize_t max_length, + char **next_out, uint32_t *avail_out) +{ + Py_ssize_t allocated; + + allocated = _BlocksOutputBuffer_InitAndGrow( + buffer, max_length, (void**) next_out); + *avail_out = (uint32_t) allocated; + return allocated; +} + +/* On success, return value >= 0 + On failure, return -1 */ +static inline Py_ssize_t +OutputBuffer_Grow(_BlocksOutputBuffer *buffer, + char **next_out, uint32_t *avail_out) +{ + Py_ssize_t allocated; + + allocated = _BlocksOutputBuffer_Grow( + buffer, (void**) next_out, (Py_ssize_t) *avail_out); + *avail_out = (uint32_t) allocated; + return allocated; +} + +static inline Py_ssize_t +OutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer, uint32_t avail_out) +{ + return _BlocksOutputBuffer_GetDataSize(buffer, (Py_ssize_t) avail_out); +} + +static inline PyObject * +OutputBuffer_Finish(_BlocksOutputBuffer *buffer, uint32_t avail_out) +{ + return _BlocksOutputBuffer_Finish(buffer, (Py_ssize_t) avail_out); +} + +static inline void +OutputBuffer_OnError(_BlocksOutputBuffer *buffer) +{ + _BlocksOutputBuffer_OnError(buffer); +} + #ifndef BZ_CONFIG_ERROR #define BZ2_bzCompress bzCompress @@ -28,6 +81,19 @@ #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; @@ -51,9 +117,6 @@ typedef struct { PyThread_type_lock lock; } BZ2Decompressor; -static PyTypeObject BZ2Compressor_Type; -static PyTypeObject BZ2Decompressor_Type; - /* Helper functions. */ static int @@ -105,52 +168,22 @@ catch_bz2_error(int bzerror) } } -#if BUFSIZ < 8192 -#define INITIAL_BUFFER_SIZE 8192 -#else -#define INITIAL_BUFFER_SIZE BUFSIZ -#endif - -static int -grow_buffer(PyObject **buf, Py_ssize_t max_length) -{ - /* Expand the buffer by an amount proportional to the current size, - giving us amortized linear-time behavior. Use a less-than-double - growth factor to avoid excessive allocation. */ - size_t size = PyBytes_GET_SIZE(*buf); - size_t new_size = size + (size >> 3) + 6; - - if (max_length > 0 && new_size > (size_t) max_length) - new_size = (size_t) max_length; - - if (new_size > size) { - return _PyBytes_Resize(buf, new_size); - } else { /* overflow */ - PyErr_SetString(PyExc_OverflowError, - "Unable to allocate buffer - output too large"); - return -1; - } -} - /* BZ2Compressor class. */ static PyObject * compress(BZ2Compressor *c, char *data, size_t len, int action) { - size_t data_size = 0; PyObject *result; + _BlocksOutputBuffer buffer = {.list = NULL}; - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - if (result == NULL) - return NULL; - + if (OutputBuffer_InitAndGrow(&buffer, -1, &c->bzs.next_out, &c->bzs.avail_out) < 0) { + goto error; + } c->bzs.next_in = data; c->bzs.avail_in = 0; - c->bzs.next_out = PyBytes_AS_STRING(result); - c->bzs.avail_out = INITIAL_BUFFER_SIZE; + for (;;) { - char *this_out; int bzerror; /* On a 64-bit system, len might not fit in avail_in (an unsigned int). @@ -165,21 +198,15 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) break; if (c->bzs.avail_out == 0) { - size_t buffer_left = PyBytes_GET_SIZE(result) - data_size; - if (buffer_left == 0) { - if (grow_buffer(&result, -1) < 0) - goto error; - c->bzs.next_out = PyBytes_AS_STRING(result) + data_size; - buffer_left = PyBytes_GET_SIZE(result) - data_size; + if (OutputBuffer_Grow(&buffer, &c->bzs.next_out, &c->bzs.avail_out) < 0) { + goto error; } - c->bzs.avail_out = (unsigned int)Py_MIN(buffer_left, UINT_MAX); } Py_BEGIN_ALLOW_THREADS - this_out = c->bzs.next_out; bzerror = BZ2_bzCompress(&c->bzs, action); - data_size += c->bzs.next_out - this_out; Py_END_ALLOW_THREADS + if (catch_bz2_error(bzerror)) goto error; @@ -187,13 +214,14 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) if (action == BZ_FINISH && bzerror == BZ_STREAM_END) break; } - if (data_size != (size_t)PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) < 0) - goto error; - return result; + + result = OutputBuffer_Finish(&buffer, c->bzs.avail_out); + if (result != NULL) { + return result; + } error: - Py_XDECREF(result); + OutputBuffer_OnError(&buffer); return NULL; } @@ -280,21 +308,11 @@ BZ2_Free(void* ctx, void *ptr) PyMem_RawFree(ptr); } -/*[clinic input] -_bz2.BZ2Compressor.__init__ - - 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]*/ +/* 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) -/*[clinic end generated code: output=c4e6adfd02963827 input=4e1ff7b8394b6e9a]*/ { int bzerror; @@ -325,13 +343,60 @@ error: 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; +} + static void BZ2Compressor_dealloc(BZ2Compressor *self) { BZ2_bzCompressEnd(&self->bzs); - if (self->lock != NULL) + if (self->lock != NULL) { PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + } + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); +} + +static int +BZ2Compressor_traverse(BZ2Compressor *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; } static PyMethodDef BZ2Compressor_methods[] = { @@ -340,48 +405,26 @@ static PyMethodDef BZ2Compressor_methods[] = { {NULL} }; - -static PyTypeObject BZ2Compressor_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_bz2.BZ2Compressor", /* tp_name */ - sizeof(BZ2Compressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)BZ2Compressor_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, /* tp_flags */ - _bz2_BZ2Compressor___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BZ2Compressor_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 */ - _bz2_BZ2Compressor___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ +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_traverse, BZ2Compressor_traverse}, + {0, 0} }; +static PyType_Spec bz2_compressor_type_spec = { + .name = "_bz2.BZ2Compressor", + .basicsize = sizeof(BZ2Compressor), + // Calling PyType_GetModuleState() on a subclass is not safe. + // bz2_compressor_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 = bz2_compressor_type_slots, +}; /* BZ2Decompressor class. */ @@ -395,36 +438,29 @@ decompress_buf(BZ2Decompressor *d, 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 */ - Py_ssize_t data_size = 0; PyObject *result; + _BlocksOutputBuffer buffer = {.list = NULL}; bz_stream *bzs = &d->bzs; - if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - else - result = PyBytes_FromStringAndSize(NULL, max_length); - if (result == NULL) - return NULL; + if (OutputBuffer_InitAndGrow(&buffer, max_length, &bzs->next_out, &bzs->avail_out) < 0) { + goto error; + } - bzs->next_out = PyBytes_AS_STRING(result); for (;;) { int bzret; - size_t avail; - /* On a 64-bit system, buffer length might not fit in avail_out, so we do decompression in chunks of no more than UINT_MAX bytes each. Note that the expression for `avail` is guaranteed to be positive, so the cast is safe. */ - avail = (size_t) (PyBytes_GET_SIZE(result) - data_size); - bzs->avail_out = (unsigned int)Py_MIN(avail, UINT_MAX); bzs->avail_in = (unsigned int)Py_MIN(d->bzs_avail_in_real, UINT_MAX); d->bzs_avail_in_real -= bzs->avail_in; Py_BEGIN_ALLOW_THREADS bzret = BZ2_bzDecompress(bzs); - data_size = bzs->next_out - PyBytes_AS_STRING(result); - d->bzs_avail_in_real += bzs->avail_in; Py_END_ALLOW_THREADS + + d->bzs_avail_in_real += bzs->avail_in; + if (catch_bz2_error(bzret)) goto error; if (bzret == BZ_STREAM_END) { @@ -433,22 +469,22 @@ decompress_buf(BZ2Decompressor *d, Py_ssize_t max_length) } else if (d->bzs_avail_in_real == 0) { break; } else if (bzs->avail_out == 0) { - if (data_size == max_length) + if (OutputBuffer_GetDataSize(&buffer, bzs->avail_out) == max_length) { break; - if (data_size == PyBytes_GET_SIZE(result) && - grow_buffer(&result, max_length) == -1) + } + if (OutputBuffer_Grow(&buffer, &bzs->next_out, &bzs->avail_out) < 0) { goto error; - bzs->next_out = PyBytes_AS_STRING(result) + data_size; + } } } - if (data_size != PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) == -1) - goto error; - return result; + result = OutputBuffer_Finish(&buffer, bzs->avail_out); + if (result != NULL) { + return result; + } error: - Py_XDECREF(result); + OutputBuffer_OnError(&buffer); return NULL; } @@ -601,17 +637,10 @@ _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, return result; } -/*[clinic input] -_bz2.BZ2Decompressor.__init__ - -Create a decompressor object for decompressing data incrementally. - -For one-shot decompression, use the decompress() function instead. -[clinic start generated code]*/ - +/* 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 end generated code: output=e4d2b9bb866ab8f1 input=95f6500dcda60088]*/ { int bzerror; @@ -646,16 +675,53 @@ error: 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; +} + +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) { - if(self->input_buffer != NULL) + if(self->input_buffer != NULL) { PyMem_Free(self->input_buffer); + } BZ2_bzDecompressEnd(&self->bzs); Py_CLEAR(self->unused_data); - if (self->lock != NULL) + if (self->lock != NULL) { PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + } + + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); +} + +static int +BZ2Decompressor_traverse(BZ2Decompressor *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; } static PyMethodDef BZ2Decompressor_methods[] = { @@ -682,64 +748,81 @@ static PyMemberDef BZ2Decompressor_members[] = { {NULL} }; -static PyTypeObject BZ2Decompressor_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_bz2.BZ2Decompressor", /* tp_name */ - sizeof(BZ2Decompressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)BZ2Decompressor_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, /* tp_flags */ - _bz2_BZ2Decompressor___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BZ2Decompressor_methods, /* tp_methods */ - BZ2Decompressor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _bz2_BZ2Decompressor___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ +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_members, BZ2Decompressor_members}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_traverse, BZ2Decompressor_traverse}, + {0, 0} }; +static PyType_Spec bz2_decompressor_type_spec = { + .name = "_bz2.BZ2Decompressor", + .basicsize = sizeof(BZ2Decompressor), + // Calling PyType_GetModuleState() on a subclass is not safe. + // bz2_decompressor_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 = bz2_decompressor_type_slots, +}; /* Module initialization. */ static int _bz2_exec(PyObject *module) { - if (PyModule_AddType(module, &BZ2Compressor_Type) < 0) { + _bz2_state *state = get_bz2_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, &BZ2Decompressor_Type) < 0) { + if (PyModule_AddType(module, state->bz2_compressor_type) < 0) { return -1; } + state->bz2_decompressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, + &bz2_decompressor_type_spec, NULL); + if (state->bz2_decompressor_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, state->bz2_decompressor_type) < 0) { + return -1; + } + + return 0; +} + +static int +_bz2_traverse(PyObject *module, visitproc visit, void *arg) +{ + _bz2_state *state = get_bz2_state(module); + Py_VISIT(state->bz2_compressor_type); + Py_VISIT(state->bz2_decompressor_type); + return 0; +} + +static int +_bz2_clear(PyObject *module) +{ + _bz2_state *state = get_bz2_state(module); + Py_CLEAR(state->bz2_compressor_type); + Py_CLEAR(state->bz2_decompressor_type); return 0; } +static void +_bz2_free(void *module) +{ + _bz2_clear((PyObject *)module); +} + static struct PyModuleDef_Slot _bz2_slots[] = { {Py_mod_exec, _bz2_exec}, {0, NULL} @@ -747,14 +830,12 @@ static struct PyModuleDef_Slot _bz2_slots[] = { static struct PyModuleDef _bz2module = { PyModuleDef_HEAD_INIT, - "_bz2", - NULL, - 0, - NULL, - _bz2_slots, - NULL, - NULL, - NULL + .m_name = "_bz2", + .m_size = sizeof(_bz2_state), + .m_slots = _bz2_slots, + .m_traverse = _bz2_traverse, + .m_clear = _bz2_clear, + .m_free = _bz2_free, }; PyMODINIT_FUNC diff --git a/contrib/tools/python3/src/Modules/_codecsmodule.c b/contrib/tools/python3/src/Modules/_codecsmodule.c index cbe5cc50f1c..50afc097b35 100644 --- a/contrib/tools/python3/src/Modules/_codecsmodule.c +++ b/contrib/tools/python3/src/Modules/_codecsmodule.c @@ -68,6 +68,27 @@ _codecs_register(PyObject *module, PyObject *search_function) Py_RETURN_NONE; } +/*[clinic input] +_codecs.unregister + search_function: object + / + +Unregister a codec search function and clear the registry's cache. + +If the search function is not registered, do nothing. +[clinic start generated code]*/ + +static PyObject * +_codecs_unregister(PyObject *module, PyObject *search_function) +/*[clinic end generated code: output=1f0edee9cf246399 input=dd7c004c652d345e]*/ +{ + if (PyCodec_Unregister(search_function) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + /*[clinic input] _codecs.lookup encoding: str @@ -139,25 +160,6 @@ _codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding, /* --- Helpers ------------------------------------------------------------ */ -/*[clinic input] -_codecs._forget_codec - - encoding: str - / - -Purge the named codec from the internal codec lookup cache -[clinic start generated code]*/ - -static PyObject * -_codecs__forget_codec_impl(PyObject *module, const char *encoding) -/*[clinic end generated code: output=0bde9f0a5b084aa2 input=18d5d92d0e386c38]*/ -{ - if (_PyCodec_Forget(encoding) < 0) { - return NULL; - }; - Py_RETURN_NONE; -} - static PyObject *codec_tuple(PyObject *decoded, Py_ssize_t len) @@ -998,6 +1000,7 @@ _codecs_lookup_error_impl(PyObject *module, const char *name) static PyMethodDef _codecs_functions[] = { _CODECS_REGISTER_METHODDEF + _CODECS_UNREGISTER_METHODDEF _CODECS_LOOKUP_METHODDEF _CODECS_ENCODE_METHODDEF _CODECS_DECODE_METHODDEF @@ -1041,7 +1044,6 @@ static PyMethodDef _codecs_functions[] = { _CODECS_CODE_PAGE_DECODE_METHODDEF _CODECS_REGISTER_ERROR_METHODDEF _CODECS_LOOKUP_ERROR_METHODDEF - _CODECS__FORGET_CODEC_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/contrib/tools/python3/src/Modules/_collectionsmodule.c b/contrib/tools/python3/src/Modules/_collectionsmodule.c index 2e19b83dcec..eff03c789ed 100644 --- a/contrib/tools/python3/src/Modules/_collectionsmodule.c +++ b/contrib/tools/python3/src/Modules/_collectionsmodule.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_long.h" // _PyLong_GetZero() #include "structmember.h" // PyMemberDef #ifdef STDC_HEADERS @@ -898,9 +899,20 @@ deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) { Py_ssize_t n=1; - if (!_PyArg_ParseStack(args, nargs, "|n:rotate", &n)) { + if (!_PyArg_CheckPositional("deque.rotate", nargs, 0, 1)) { return NULL; } + if (nargs) { + PyObject *index = _PyNumber_Index(args[0]); + if (index == NULL) { + return NULL; + } + n = PyLong_AsSsize_t(index); + Py_DECREF(index); + if (n == -1 && PyErr_Occurred()) { + return NULL; + } + } if (!_deque_rotate(deque, n)) Py_RETURN_NONE; @@ -1146,38 +1158,6 @@ deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) PyDoc_STRVAR(insert_doc, "D.insert(index, object) -- insert object before index"); -static PyObject * -deque_remove(dequeobject *deque, PyObject *value) -{ - Py_ssize_t i, n=Py_SIZE(deque); - - for (i=0 ; ileftblock->data[deque->leftindex]; - int cmp = PyObject_RichCompareBool(item, value, Py_EQ); - - if (Py_SIZE(deque) != n) { - PyErr_SetString(PyExc_IndexError, - "deque mutated during remove()."); - return NULL; - } - if (cmp > 0) { - PyObject *tgt = deque_popleft(deque, NULL); - assert (tgt != NULL); - if (_deque_rotate(deque, i)) - return NULL; - Py_DECREF(tgt); - Py_RETURN_NONE; - } - else if (cmp < 0) { - _deque_rotate(deque, i); - return NULL; - } - _deque_rotate(deque, -1); - } - PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque"); - return NULL; -} - PyDoc_STRVAR(remove_doc, "D.remove(value) -- remove first occurrence of value."); @@ -1245,6 +1225,48 @@ deque_del_item(dequeobject *deque, Py_ssize_t i) return rv; } +static PyObject * +deque_remove(dequeobject *deque, PyObject *value) +{ + PyObject *item; + block *b = deque->leftblock; + Py_ssize_t i, n = Py_SIZE(deque), index = deque->leftindex; + size_t start_state = deque->state; + int cmp, rv; + + for (i = 0 ; i < n; i++) { + item = b->data[index]; + Py_INCREF(item); + cmp = PyObject_RichCompareBool(item, value, Py_EQ); + Py_DECREF(item); + if (cmp < 0) { + return NULL; + } + if (start_state != deque->state) { + PyErr_SetString(PyExc_IndexError, + "deque mutated during iteration"); + return NULL; + } + if (cmp > 0) { + break; + } + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } + if (i == n) { + PyErr_Format(PyExc_ValueError, "%R is not in deque", value); + return NULL; + } + rv = deque_del_item(deque, i); + if (rv == -1) { + return NULL; + } + Py_RETURN_NONE; +} + static int deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) { @@ -1640,7 +1662,8 @@ static PyTypeObject deque_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_SEQUENCE, /* tp_flags */ deque_doc, /* tp_doc */ (traverseproc)deque_traverse, /* tp_traverse */ @@ -2296,6 +2319,7 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, PyObject *dict_get; PyObject *mapping_setitem; PyObject *dict_setitem; + PyObject *one = _PyLong_GetOne(); // borrowed reference it = PyObject_GetIter(iterable); if (it == NULL) @@ -2342,10 +2366,10 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, if (oldval == NULL) { if (PyErr_Occurred()) goto done; - if (_PyDict_SetItem_KnownHash(mapping, key, _PyLong_One, hash) < 0) + if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0) goto done; } else { - newval = PyNumber_Add(oldval, _PyLong_One); + newval = PyNumber_Add(oldval, one); if (newval == NULL) goto done; if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0) @@ -2354,19 +2378,21 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, } Py_DECREF(key); } - } else { + } + else { bound_get = _PyObject_GetAttrId(mapping, &PyId_get); if (bound_get == NULL) goto done; + PyObject *zero = _PyLong_GetZero(); // borrowed reference while (1) { key = PyIter_Next(it); if (key == NULL) break; - oldval = PyObject_CallFunctionObjArgs(bound_get, key, _PyLong_Zero, NULL); + oldval = PyObject_CallFunctionObjArgs(bound_get, key, zero, NULL); if (oldval == NULL) break; - newval = PyNumber_Add(oldval, _PyLong_One); + newval = PyNumber_Add(oldval, one); Py_DECREF(oldval); if (newval == NULL) break; diff --git a/contrib/tools/python3/src/Modules/_contextvarsmodule.c b/contrib/tools/python3/src/Modules/_contextvarsmodule.c index d6d7f375d12..d13b5962c13 100644 --- a/contrib/tools/python3/src/Modules/_contextvarsmodule.c +++ b/contrib/tools/python3/src/Modules/_contextvarsmodule.c @@ -30,30 +30,15 @@ static PyMethodDef _contextvars_methods[] = { static int _contextvars_exec(PyObject *m) { - Py_INCREF(&PyContext_Type); - if (PyModule_AddObject(m, "Context", - (PyObject *)&PyContext_Type) < 0) - { - Py_DECREF(&PyContext_Type); + if (PyModule_AddType(m, &PyContext_Type) < 0) { return -1; } - - Py_INCREF(&PyContextVar_Type); - if (PyModule_AddObject(m, "ContextVar", - (PyObject *)&PyContextVar_Type) < 0) - { - Py_DECREF(&PyContextVar_Type); + if (PyModule_AddType(m, &PyContextVar_Type) < 0) { return -1; } - - Py_INCREF(&PyContextToken_Type); - if (PyModule_AddObject(m, "Token", - (PyObject *)&PyContextToken_Type) < 0) - { - Py_DECREF(&PyContextToken_Type); + if (PyModule_AddType(m, &PyContextToken_Type) < 0) { return -1; } - return 0; } diff --git a/contrib/tools/python3/src/Modules/_csv.c b/contrib/tools/python3/src/Modules/_csv.c index 029f473ae87..72f0791a439 100644 --- a/contrib/tools/python3/src/Modules/_csv.c +++ b/contrib/tools/python3/src/Modules/_csv.c @@ -18,9 +18,14 @@ module instead. typedef struct { PyObject *error_obj; /* CSV exception */ PyObject *dialects; /* Dialect registry */ + PyTypeObject *dialect_type; + PyTypeObject *reader_type; + PyTypeObject *writer_type; long field_limit; /* max parsed field size */ } _csvstate; +static struct PyModuleDef _csvmodule; + static inline _csvstate* get_csv_state(PyObject *module) { @@ -30,31 +35,35 @@ get_csv_state(PyObject *module) } static int -_csv_clear(PyObject *m) +_csv_clear(PyObject *module) { - Py_CLEAR(get_csv_state(m)->error_obj); - Py_CLEAR(get_csv_state(m)->dialects); + _csvstate *module_state = PyModule_GetState(module); + Py_CLEAR(module_state->error_obj); + Py_CLEAR(module_state->dialects); + Py_CLEAR(module_state->dialect_type); + Py_CLEAR(module_state->reader_type); + Py_CLEAR(module_state->writer_type); return 0; } static int -_csv_traverse(PyObject *m, visitproc visit, void *arg) +_csv_traverse(PyObject *module, visitproc visit, void *arg) { - Py_VISIT(get_csv_state(m)->error_obj); - Py_VISIT(get_csv_state(m)->dialects); + _csvstate *module_state = PyModule_GetState(module); + Py_VISIT(module_state->error_obj); + Py_VISIT(module_state->dialects); + Py_VISIT(module_state->dialect_type); + Py_VISIT(module_state->reader_type); + Py_VISIT(module_state->writer_type); return 0; } static void -_csv_free(void *m) +_csv_free(void *module) { - _csv_clear((PyObject *)m); + _csv_clear((PyObject *)module); } -static struct PyModuleDef _csvmodule; - -#define _csvstate_global ((_csvstate *)PyModule_GetState(PyState_FindModule(&_csvmodule))) - typedef enum { START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD, IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD, @@ -92,8 +101,6 @@ typedef struct { } DialectObj; -static PyTypeObject Dialect_Type; - typedef struct { PyObject_HEAD @@ -110,10 +117,6 @@ typedef struct { unsigned long line_num; /* Source-file line number */ } ReaderObj; -static PyTypeObject Reader_Type; - -#define ReaderObject_Check(v) Py_IS_TYPE(v, &Reader_Type) - typedef struct { PyObject_HEAD @@ -125,34 +128,28 @@ typedef struct { Py_ssize_t rec_size; /* size of allocated record */ Py_ssize_t rec_len; /* length of record */ int num_fields; /* number of fields in record */ -} WriterObj; -static PyTypeObject Writer_Type; + PyObject *error_obj; /* cached error object */ +} WriterObj; /* * DIALECT class */ static PyObject * -get_dialect_from_registry(PyObject * name_obj) +get_dialect_from_registry(PyObject *name_obj, _csvstate *module_state) { PyObject *dialect_obj; - dialect_obj = PyDict_GetItemWithError(_csvstate_global->dialects, name_obj); + dialect_obj = PyDict_GetItemWithError(module_state->dialects, name_obj); if (dialect_obj == NULL) { if (!PyErr_Occurred()) - PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); + PyErr_Format(module_state->error_obj, "unknown dialect"); } else Py_INCREF(dialect_obj); - return dialect_obj; -} -static PyObject * -get_string(PyObject *str) -{ - Py_XINCREF(str); - return str; + return dialect_obj; } static PyObject * @@ -168,7 +165,8 @@ get_nullchar_as_None(Py_UCS4 c) static PyObject * Dialect_get_lineterminator(DialectObj *self, void *Py_UNUSED(ignored)) { - return get_string(self->lineterminator); + Py_XINCREF(self->lineterminator); + return self->lineterminator; } static PyObject * @@ -353,8 +351,11 @@ static PyGetSetDef Dialect_getsetlist[] = { static void Dialect_dealloc(DialectObj *self) { - Py_XDECREF(self->lineterminator); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear((PyObject *)self); + PyObject_GC_Del(self); + Py_DECREF(tp); } static char *dialect_kws[] = { @@ -370,6 +371,22 @@ static char *dialect_kws[] = { NULL }; +static _csvstate * +_csv_state_from_type(PyTypeObject *type, const char *name) +{ + PyObject *module = _PyType_GetModuleByDef(type, &_csvmodule); + if (module == NULL) { + return NULL; + } + _csvstate *module_state = PyModule_GetState(module); + if (module_state == NULL) { + PyErr_Format(PyExc_SystemError, + "%s: No _csv module state found", name); + return NULL; + } + return module_state; +} + static PyObject * dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { @@ -398,16 +415,21 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) &strict)) return NULL; + _csvstate *module_state = _csv_state_from_type(type, "dialect_new"); + if (module_state == NULL) { + return NULL; + } + if (dialect != NULL) { if (PyUnicode_Check(dialect)) { - dialect = get_dialect_from_registry(dialect); + dialect = get_dialect_from_registry(dialect, module_state); if (dialect == NULL) return NULL; } else Py_INCREF(dialect); /* Can we reuse this instance? */ - if (PyObject_TypeCheck(dialect, &Dialect_Type) && + if (PyObject_TypeCheck(dialect, module_state->dialect_type) && delimiter == NULL && doublequote == NULL && escapechar == NULL && @@ -421,7 +443,7 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) self = (DialectObj *)type->tp_alloc(type, 0); if (self == NULL) { - Py_XDECREF(dialect); + Py_CLEAR(dialect); return NULL; } self->lineterminator = NULL; @@ -489,76 +511,86 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) ret = (PyObject *)self; Py_INCREF(self); err: - Py_XDECREF(self); - Py_XDECREF(dialect); - Py_XDECREF(delimiter); - Py_XDECREF(doublequote); - Py_XDECREF(escapechar); - Py_XDECREF(lineterminator); - Py_XDECREF(quotechar); - Py_XDECREF(quoting); - Py_XDECREF(skipinitialspace); - Py_XDECREF(strict); + Py_CLEAR(self); + Py_CLEAR(dialect); + Py_CLEAR(delimiter); + Py_CLEAR(doublequote); + Py_CLEAR(escapechar); + Py_CLEAR(lineterminator); + Py_CLEAR(quotechar); + Py_CLEAR(quoting); + Py_CLEAR(skipinitialspace); + Py_CLEAR(strict); return ret; } +/* Since dialect is now a heap type, it inherits pickling method for + * protocol 0 and 1 from object, therefore it needs to be overridden */ + +PyDoc_STRVAR(dialect_reduce_doc, "raises an exception to avoid pickling"); + +static PyObject * +Dialect_reduce(PyObject *self, PyObject *args) { + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self))); + return NULL; +} + +static struct PyMethodDef dialect_methods[] = { + {"__reduce__", Dialect_reduce, METH_VARARGS, dialect_reduce_doc}, + {"__reduce_ex__", Dialect_reduce, METH_VARARGS, dialect_reduce_doc}, + {NULL, NULL} +}; PyDoc_STRVAR(Dialect_Type_doc, "CSV dialect\n" "\n" "The Dialect type records CSV parsing and generation options.\n"); -static PyTypeObject Dialect_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_csv.Dialect", /* tp_name */ - sizeof(DialectObj), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)Dialect_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - Dialect_Type_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - Dialect_memberlist, /* tp_members */ - Dialect_getsetlist, /* 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 */ - dialect_new, /* tp_new */ - 0, /* tp_free */ +static int +Dialect_clear(DialectObj *self) +{ + Py_CLEAR(self->lineterminator); + return 0; +} + +static int +Dialect_traverse(DialectObj *self, visitproc visit, void *arg) +{ + Py_VISIT(self->lineterminator); + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static PyType_Slot Dialect_Type_slots[] = { + {Py_tp_doc, (char*)Dialect_Type_doc}, + {Py_tp_members, Dialect_memberlist}, + {Py_tp_getset, Dialect_getsetlist}, + {Py_tp_new, dialect_new}, + {Py_tp_methods, dialect_methods}, + {Py_tp_dealloc, Dialect_dealloc}, + {Py_tp_clear, Dialect_clear}, + {Py_tp_traverse, Dialect_traverse}, + {0, NULL} +}; + +PyType_Spec Dialect_Type_spec = { + .name = "_csv.Dialect", + .basicsize = sizeof(DialectObj), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = Dialect_Type_slots, }; + /* * Return an instance of the dialect type, given a Python instance or kwarg * description of the dialect */ static PyObject * -_call_dialect(PyObject *dialect_inst, PyObject *kwargs) +_call_dialect(_csvstate *module_state, PyObject *dialect_inst, PyObject *kwargs) { - PyObject *type = (PyObject *)&Dialect_Type; + PyObject *type = (PyObject *)module_state->dialect_type; if (dialect_inst) { return PyObject_VectorcallDict(type, &dialect_inst, 1, kwargs); } @@ -616,11 +648,12 @@ parse_grow_buff(ReaderObj *self) } static int -parse_add_char(ReaderObj *self, Py_UCS4 c) +parse_add_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c) { - if (self->field_len >= _csvstate_global->field_limit) { - PyErr_Format(_csvstate_global->error_obj, "field larger than field limit (%ld)", - _csvstate_global->field_limit); + if (self->field_len >= module_state->field_limit) { + PyErr_Format(module_state->error_obj, + "field larger than field limit (%ld)", + module_state->field_limit); return -1; } if (self->field_len == self->field_size && !parse_grow_buff(self)) @@ -630,7 +663,7 @@ parse_add_char(ReaderObj *self, Py_UCS4 c) } static int -parse_process_char(ReaderObj *self, Py_UCS4 c) +parse_process_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c) { DialectObj *dialect = self->dialect; @@ -676,7 +709,7 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) /* begin new unquoted field */ if (dialect->quoting == QUOTE_NONNUMERIC) self->numeric_field = 1; - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; self->state = IN_FIELD; } @@ -684,14 +717,14 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) case ESCAPED_CHAR: if (c == '\n' || c=='\r') { - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; self->state = AFTER_ESCAPED_CRNL; break; } if (c == '\0') c = '\n'; - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; self->state = IN_FIELD; break; @@ -721,7 +754,7 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) } else { /* normal character - save in field */ - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; } break; @@ -747,7 +780,7 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) } else { /* normal character - save in field */ - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; } break; @@ -755,7 +788,7 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) case ESCAPE_IN_QUOTED_FIELD: if (c == '\0') c = '\n'; - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; self->state = IN_QUOTED_FIELD; break; @@ -765,7 +798,7 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) if (dialect->quoting != QUOTE_NONE && c == dialect->quotechar) { /* save "" as " */ - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; self->state = IN_QUOTED_FIELD; } @@ -782,13 +815,13 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) self->state = (c == '\0' ? START_RECORD : EAT_CRNL); } else if (!dialect->strict) { - if (parse_add_char(self, c) < 0) + if (parse_add_char(self, module_state, c) < 0) return -1; self->state = IN_FIELD; } else { /* illegal */ - PyErr_Format(_csvstate_global->error_obj, "'%c' expected after '%c'", + PyErr_Format(module_state->error_obj, "'%c' expected after '%c'", dialect->delimiter, dialect->quotechar); return -1; @@ -801,7 +834,8 @@ parse_process_char(ReaderObj *self, Py_UCS4 c) else if (c == '\0') self->state = START_RECORD; else { - PyErr_Format(_csvstate_global->error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?"); + PyErr_Format(module_state->error_obj, + "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?"); return -1; } break; @@ -832,6 +866,12 @@ Reader_iternext(ReaderObj *self) const void *data; PyObject *lineobj; + _csvstate *module_state = _csv_state_from_type(Py_TYPE(self), + "Reader.__next__"); + if (module_state == NULL) { + return NULL; + } + if (parse_reset(self) < 0) return NULL; do { @@ -841,7 +881,7 @@ Reader_iternext(ReaderObj *self) if (!PyErr_Occurred() && (self->field_len != 0 || self->state == IN_QUOTED_FIELD)) { if (self->dialect->strict) - PyErr_SetString(_csvstate_global->error_obj, + PyErr_SetString(module_state->error_obj, "unexpected end of data"); else if (parse_save_field(self) >= 0) break; @@ -849,10 +889,10 @@ Reader_iternext(ReaderObj *self) return NULL; } if (!PyUnicode_Check(lineobj)) { - PyErr_Format(_csvstate_global->error_obj, + PyErr_Format(module_state->error_obj, "iterator should return strings, " "not %.200s " - "(did you open the file in text mode?)", + "(the file should be opened in text mode)", Py_TYPE(lineobj)->tp_name ); Py_DECREF(lineobj); @@ -871,18 +911,18 @@ Reader_iternext(ReaderObj *self) c = PyUnicode_READ(kind, data, pos); if (c == '\0') { Py_DECREF(lineobj); - PyErr_Format(_csvstate_global->error_obj, + PyErr_Format(module_state->error_obj, "line contains NUL"); goto err; } - if (parse_process_char(self, c) < 0) { + if (parse_process_char(self, module_state, c) < 0) { Py_DECREF(lineobj); goto err; } pos++; } Py_DECREF(lineobj); - if (parse_process_char(self, 0) < 0) + if (parse_process_char(self, module_state, 0) < 0) goto err; } while (self->state != START_RECORD); @@ -895,13 +935,15 @@ err: static void Reader_dealloc(ReaderObj *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); - Py_XDECREF(self->dialect); - Py_XDECREF(self->input_iter); - Py_XDECREF(self->fields); - if (self->field != NULL) + tp->tp_clear((PyObject *)self); + if (self->field != NULL) { PyMem_Free(self->field); + self->field = NULL; + } PyObject_GC_Del(self); + Py_DECREF(tp); } static int @@ -910,6 +952,7 @@ Reader_traverse(ReaderObj *self, visitproc visit, void *arg) Py_VISIT(self->dialect); Py_VISIT(self->input_iter); Py_VISIT(self->fields); + Py_VISIT(Py_TYPE(self)); return 0; } @@ -941,47 +984,35 @@ static struct PyMemberDef Reader_memberlist[] = { }; -static PyTypeObject Reader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_csv.reader", /*tp_name*/ - sizeof(ReaderObj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)Reader_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)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*/ - Reader_Type_doc, /*tp_doc*/ - (traverseproc)Reader_traverse, /*tp_traverse*/ - (inquiry)Reader_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - PyObject_SelfIter, /*tp_iter*/ - (getiterfunc)Reader_iternext, /*tp_iternext*/ - Reader_methods, /*tp_methods*/ - Reader_memberlist, /*tp_members*/ - 0, /*tp_getset*/ +static PyType_Slot Reader_Type_slots[] = { + {Py_tp_doc, (char*)Reader_Type_doc}, + {Py_tp_traverse, Reader_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, Reader_iternext}, + {Py_tp_methods, Reader_methods}, + {Py_tp_members, Reader_memberlist}, + {Py_tp_clear, Reader_clear}, + {Py_tp_dealloc, Reader_dealloc}, + {0, NULL} +}; +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), + .slots = Reader_Type_slots }; + static PyObject * csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args) { PyObject * iterator, * dialect = NULL; - ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type); + _csvstate *module_state = get_csv_state(module); + ReaderObj * self = PyObject_GC_New( + ReaderObj, + module_state->reader_type); if (!self) return NULL; @@ -1007,7 +1038,8 @@ csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args) Py_DECREF(self); return NULL; } - self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args); + self->dialect = (DialectObj *)_call_dialect(module_state, dialect, + keyword_args); if (self->dialect == NULL) { Py_DECREF(self); return NULL; @@ -1088,12 +1120,15 @@ join_append_data(WriterObj *self, unsigned int field_kind, const void *field_dat else want_escape = 1; } + else if (c == dialect->escapechar) { + want_escape = 1; + } if (!want_escape) *quoted = 1; } if (want_escape) { if (!dialect->escapechar) { - PyErr_Format(_csvstate_global->error_obj, + PyErr_Format(self->error_obj, "need to escape, but no escapechar set"); return -1; } @@ -1211,7 +1246,7 @@ csv_writerow(WriterObj *self, PyObject *seq) iter = PyObject_GetIter(seq); if (iter == NULL) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Format(_csvstate_global->error_obj, + PyErr_Format(self->error_obj, "iterable expected, not %.200s", Py_TYPE(seq)->tp_name); } @@ -1268,7 +1303,7 @@ csv_writerow(WriterObj *self, PyObject *seq) if (self->num_fields > 0 && self->rec_len == 0) { if (dialect->quoting == QUOTE_NONE) { - PyErr_Format(_csvstate_global->error_obj, + PyErr_Format(self->error_obj, "single empty field record must be quoted"); return NULL; } @@ -1337,22 +1372,13 @@ static struct PyMemberDef Writer_memberlist[] = { { NULL } }; -static void -Writer_dealloc(WriterObj *self) -{ - PyObject_GC_UnTrack(self); - Py_XDECREF(self->dialect); - Py_XDECREF(self->write); - if (self->rec != NULL) - PyMem_Free(self->rec); - PyObject_GC_Del(self); -} - static int Writer_traverse(WriterObj *self, visitproc visit, void *arg) { Py_VISIT(self->dialect); Py_VISIT(self->write); + Py_VISIT(self->error_obj); + Py_VISIT(Py_TYPE(self)); return 0; } @@ -1361,9 +1387,23 @@ Writer_clear(WriterObj *self) { Py_CLEAR(self->dialect); Py_CLEAR(self->write); + Py_CLEAR(self->error_obj); return 0; } +static void +Writer_dealloc(WriterObj *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear((PyObject *)self); + if (self->rec != NULL) { + PyMem_Free(self->rec); + } + PyObject_GC_Del(self); + Py_DECREF(tp); +} + PyDoc_STRVAR(Writer_Type_doc, "CSV writer\n" "\n" @@ -1371,46 +1411,31 @@ PyDoc_STRVAR(Writer_Type_doc, "in CSV format from sequence input.\n" ); -static PyTypeObject Writer_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_csv.writer", /*tp_name*/ - sizeof(WriterObj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)Writer_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)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*/ - Writer_Type_doc, - (traverseproc)Writer_traverse, /*tp_traverse*/ - (inquiry)Writer_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - (getiterfunc)0, /*tp_iter*/ - (getiterfunc)0, /*tp_iternext*/ - Writer_methods, /*tp_methods*/ - Writer_memberlist, /*tp_members*/ - 0, /*tp_getset*/ +static PyType_Slot Writer_Type_slots[] = { + {Py_tp_doc, (char*)Writer_Type_doc}, + {Py_tp_traverse, Writer_traverse}, + {Py_tp_clear, Writer_clear}, + {Py_tp_dealloc, Writer_dealloc}, + {Py_tp_methods, Writer_methods}, + {Py_tp_members, Writer_memberlist}, + {0, NULL} }; +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), + .slots = Writer_Type_slots, +}; + + static PyObject * csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) { PyObject * output_file, * dialect = NULL; - WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type); + _csvstate *module_state = get_csv_state(module); + WriterObj * self = PyObject_GC_New(WriterObj, module_state->writer_type); _Py_IDENTIFIER(write); if (!self) @@ -1424,6 +1449,8 @@ csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) self->rec_len = 0; self->num_fields = 0; + self->error_obj = Py_NewRef(module_state->error_obj); + if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) { Py_DECREF(self); return NULL; @@ -1438,7 +1465,8 @@ csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) Py_DECREF(self); return NULL; } - self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args); + self->dialect = (DialectObj *)_call_dialect(module_state, dialect, + keyword_args); if (self->dialect == NULL) { Py_DECREF(self); return NULL; @@ -1453,13 +1481,14 @@ csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) static PyObject * csv_list_dialects(PyObject *module, PyObject *args) { - return PyDict_Keys(_csvstate_global->dialects); + return PyDict_Keys(get_csv_state(module)->dialects); } static PyObject * csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *name_obj, *dialect_obj = NULL; + _csvstate *module_state = get_csv_state(module); PyObject *dialect; if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj)) @@ -1471,10 +1500,10 @@ csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) } if (PyUnicode_READY(name_obj) == -1) return NULL; - dialect = _call_dialect(dialect_obj, kwargs); + dialect = _call_dialect(module_state, dialect_obj, kwargs); if (dialect == NULL) return NULL; - if (PyDict_SetItem(_csvstate_global->dialects, name_obj, dialect) < 0) { + if (PyDict_SetItem(module_state->dialects, name_obj, dialect) < 0) { Py_DECREF(dialect); return NULL; } @@ -1485,9 +1514,10 @@ csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) static PyObject * csv_unregister_dialect(PyObject *module, PyObject *name_obj) { - if (PyDict_DelItem(_csvstate_global->dialects, name_obj) < 0) { + _csvstate *module_state = get_csv_state(module); + if (PyDict_DelItem(module_state->dialects, name_obj) < 0) { if (PyErr_ExceptionMatches(PyExc_KeyError)) { - PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); + PyErr_Format(module_state->error_obj, "unknown dialect"); } return NULL; } @@ -1497,14 +1527,15 @@ csv_unregister_dialect(PyObject *module, PyObject *name_obj) static PyObject * csv_get_dialect(PyObject *module, PyObject *name_obj) { - return get_dialect_from_registry(name_obj); + return get_dialect_from_registry(name_obj, get_csv_state(module)); } static PyObject * csv_field_size_limit(PyObject *module, PyObject *args) { PyObject *new_limit = NULL; - long old_limit = _csvstate_global->field_limit; + _csvstate *module_state = get_csv_state(module); + long old_limit = module_state->field_limit; if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit)) return NULL; @@ -1514,15 +1545,25 @@ csv_field_size_limit(PyObject *module, PyObject *args) "limit must be an integer"); return NULL; } - _csvstate_global->field_limit = PyLong_AsLong(new_limit); - if (_csvstate_global->field_limit == -1 && PyErr_Occurred()) { - _csvstate_global->field_limit = old_limit; + module_state->field_limit = PyLong_AsLong(new_limit); + if (module_state->field_limit == -1 && PyErr_Occurred()) { + module_state->field_limit = old_limit; return NULL; } } return PyLong_FromLong(old_limit); } +static PyType_Slot error_slots[] = { + {0, NULL}, +}; + +PyType_Spec error_spec = { + .name = "_csv.Error", + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = error_slots, +}; + /* * MODULE */ @@ -1655,68 +1696,89 @@ static struct PyMethodDef csv_methods[] = { { NULL, NULL } }; -static struct PyModuleDef _csvmodule = { - PyModuleDef_HEAD_INIT, - "_csv", - csv_module_doc, - sizeof(_csvstate), - csv_methods, - NULL, - _csv_traverse, - _csv_clear, - _csv_free -}; - -PyMODINIT_FUNC -PyInit__csv(void) -{ - PyObject *module; +static int +csv_exec(PyObject *module) { const StyleDesc *style; + PyObject *temp; + _csvstate *module_state = get_csv_state(module); - if (PyType_Ready(&Reader_Type) < 0) - return NULL; + temp = PyType_FromModuleAndSpec(module, &Dialect_Type_spec, NULL); + module_state->dialect_type = (PyTypeObject *)temp; + if (PyModule_AddObjectRef(module, "Dialect", temp) < 0) { + return -1; + } - if (PyType_Ready(&Writer_Type) < 0) - return NULL; + temp = PyType_FromModuleAndSpec(module, &Reader_Type_spec, NULL); + module_state->reader_type = (PyTypeObject *)temp; + if (PyModule_AddObjectRef(module, "Reader", temp) < 0) { + return -1; + } - /* Create the module and add the functions */ - module = PyModule_Create(&_csvmodule); - if (module == NULL) - return NULL; + temp = PyType_FromModuleAndSpec(module, &Writer_Type_spec, NULL); + module_state->writer_type = (PyTypeObject *)temp; + if (PyModule_AddObjectRef(module, "Writer", temp) < 0) { + return -1; + } /* Add version to the module. */ if (PyModule_AddStringConstant(module, "__version__", - MODULE_VERSION) == -1) - return NULL; + MODULE_VERSION) == -1) { + return -1; + } /* Set the field limit */ - get_csv_state(module)->field_limit = 128 * 1024; - /* Do I still need to add this var to the Module Dict? */ + module_state->field_limit = 128 * 1024; /* Add _dialects dictionary */ - get_csv_state(module)->dialects = PyDict_New(); - if (get_csv_state(module)->dialects == NULL) - return NULL; - Py_INCREF(get_csv_state(module)->dialects); - if (PyModule_AddObject(module, "_dialects", get_csv_state(module)->dialects)) - return NULL; + module_state->dialects = PyDict_New(); + if (PyModule_AddObjectRef(module, "_dialects", module_state->dialects) < 0) { + return -1; + } /* Add quote styles into dictionary */ for (style = quote_styles; style->name; style++) { if (PyModule_AddIntConstant(module, style->name, style->style) == -1) - return NULL; + return -1; } - if (PyModule_AddType(module, &Dialect_Type)) { - return NULL; + /* Add the CSV exception object to the module. */ + PyObject *bases = PyTuple_Pack(1, PyExc_Exception); + if (bases == NULL) { + return -1; + } + module_state->error_obj = PyType_FromModuleAndSpec(module, &error_spec, + bases); + Py_DECREF(bases); + if (module_state->error_obj == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)module_state->error_obj) != 0) { + return -1; } - /* Add the CSV exception object to the module. */ - get_csv_state(module)->error_obj = PyErr_NewException("_csv.Error", NULL, NULL); - if (get_csv_state(module)->error_obj == NULL) - return NULL; - Py_INCREF(get_csv_state(module)->error_obj); - PyModule_AddObject(module, "Error", get_csv_state(module)->error_obj); - return module; + return 0; +} + +static PyModuleDef_Slot csv_slots[] = { + {Py_mod_exec, csv_exec}, + {0, NULL} +}; + +static struct PyModuleDef _csvmodule = { + PyModuleDef_HEAD_INIT, + "_csv", + csv_module_doc, + sizeof(_csvstate), + csv_methods, + csv_slots, + _csv_traverse, + _csv_clear, + _csv_free +}; + +PyMODINIT_FUNC +PyInit__csv(void) +{ + return PyModuleDef_Init(&_csvmodule); } diff --git a/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c b/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c index 0f7b8003f20..198bdd444b5 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c +++ b/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c @@ -117,6 +117,8 @@ bytes(cdata) #endif #include "ctypes.h" +#include "pycore_long.h" // _PyLong_GetZero() + PyObject *PyExc_ArgError = NULL; /* This dict maps ctypes types to POINTER types */ @@ -124,9 +126,13 @@ PyObject *_ctypes_ptrtype_cache = NULL; static PyTypeObject Simple_Type; -/* a callable object used for unpickling */ +/* a callable object used for unpickling: + strong reference to _ctypes._unpickle() function */ static PyObject *_unpickle; +#ifdef MS_WIN32 +PyObject *ComError; // Borrowed reference to: &PyComError_Type +#endif /****************************************************************/ @@ -493,9 +499,10 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt return NULL; /* keep this for bw compatibility */ - if (_PyDict_GetItemIdWithError(result->tp_dict, &PyId__abstract_)) + int r = _PyDict_ContainsId(result->tp_dict, &PyId__abstract_); + if (r > 0) return (PyObject *)result; - if (PyErr_Occurred()) { + if (r < 0) { Py_DECREF(result); return NULL; } @@ -1352,7 +1359,6 @@ static PyGetSetDef CharArray_getsets[] = { { NULL, NULL } }; -#ifdef CTYPES_UNICODE static PyObject * WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) { @@ -1367,8 +1373,6 @@ WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) static int WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) { - Py_ssize_t result = 0; - if (value == NULL) { PyErr_SetString(PyExc_TypeError, "can't delete attribute"); @@ -1379,29 +1383,24 @@ WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored "unicode string expected instead of %s instance", Py_TYPE(value)->tp_name); return -1; - } else - Py_INCREF(value); + } + Py_ssize_t size = self->b_size / sizeof(wchar_t); Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0); if (len < 0) { return -1; } // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, // when it is called with NULL. - if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) { + assert(len > 0); + if (len - 1 > size) { PyErr_SetString(PyExc_ValueError, "string too long"); - result = -1; - goto done; - } - result = PyUnicode_AsWideChar(value, - (wchar_t *)self->b_ptr, - self->b_size/sizeof(wchar_t)); - if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t)) - ((wchar_t *)self->b_ptr)[result] = (wchar_t)0; - done: - Py_DECREF(value); - - return result >= 0 ? 0 : -1; + return -1; + } + if (PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size) < 0) { + return -1; + } + return 0; } static PyGetSetDef WCharArray_getsets[] = { @@ -1409,7 +1408,6 @@ static PyGetSetDef WCharArray_getsets[] = { "string value"}, { NULL, NULL } }; -#endif /* The next three functions copied from Python's typeobject.c. @@ -1616,11 +1614,10 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { if (-1 == add_getset(result, CharArray_getsets)) goto error; -#ifdef CTYPES_UNICODE - } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { + } + else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { if (-1 == add_getset(result, WCharArray_getsets)) goto error; -#endif } return (PyObject *)result; @@ -3485,10 +3482,12 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags) for (i = 0; i < len; ++i) { PyObject *item = PyTuple_GET_ITEM(paramflags, i); int flag; - char *name; + PyObject *name = Py_None; PyObject *defval; PyObject *typ; - if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) { + if (!PyArg_ParseTuple(item, "i|OO", &flag, &name, &defval) || + !(name == Py_None || PyUnicode_Check(name))) + { PyErr_SetString(PyExc_TypeError, "paramflags must be a sequence of (int [,string [,value]]) tuples"); return 0; @@ -3934,8 +3933,9 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, case PARAMFLAG_FIN | PARAMFLAG_FLCID: /* ['in', 'lcid'] parameter. Always taken from defval, if given, else the integer 0. */ - if (defval == NULL) - defval = _PyLong_Zero; + if (defval == NULL) { + defval = _PyLong_GetZero(); + } Py_INCREF(defval); PyTuple_SET_ITEM(callargs, i, defval); break; @@ -4309,7 +4309,7 @@ static PyNumberMethods PyCFuncPtr_as_number = { PyTypeObject PyCFuncPtr_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCFuncPtr", + "_ctypes.CFuncPtr", sizeof(PyCFuncPtrObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */ @@ -4403,15 +4403,13 @@ _init_pos_args(PyObject *self, PyTypeObject *type, } val = PyTuple_GET_ITEM(args, i + index); if (kwds) { - if (PyDict_GetItemWithError(kwds, name)) { - PyErr_Format(PyExc_TypeError, - "duplicate values for field %R", - name); - Py_DECREF(pair); - Py_DECREF(name); - return -1; - } - else if (PyErr_Occurred()) { + res = PyDict_Contains(kwds, name); + if (res != 0) { + if (res > 0) { + PyErr_Format(PyExc_TypeError, + "duplicate values for field %R", + name); + } Py_DECREF(pair); Py_DECREF(name); return -1; @@ -4654,7 +4652,6 @@ Array_subscript(PyObject *myself, PyObject *item) PyMem_Free(dest); return np; } -#ifdef CTYPES_UNICODE if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = (wchar_t *)self->b_ptr; wchar_t *dest; @@ -4681,7 +4678,6 @@ Array_subscript(PyObject *myself, PyObject *item) PyMem_Free(dest); return np; } -#endif np = PyList_New(slicelen); if (np == NULL) @@ -5350,7 +5346,6 @@ Pointer_subscript(PyObject *myself, PyObject *item) PyMem_Free(dest); return np; } -#ifdef CTYPES_UNICODE if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = *(wchar_t **)self->b_ptr; wchar_t *dest; @@ -5371,7 +5366,6 @@ Pointer_subscript(PyObject *myself, PyObject *item) PyMem_Free(dest); return np; } -#endif np = PyList_New(len); if (np == NULL) @@ -5559,20 +5553,7 @@ static PyTypeObject PyComError_Type = { 0, /* tp_alloc */ 0, /* tp_new */ }; - - -static int -create_comerror(void) -{ - PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception; - if (PyType_Ready(&PyComError_Type) < 0) - return -1; - Py_INCREF(&PyComError_Type); - ComError = (PyObject*)&PyComError_Type; - return 0; -} - -#endif +#endif // MS_WIN32 static PyObject * string_at(const char *ptr, int size) @@ -5666,7 +5647,7 @@ cast(void *ptr, PyObject *src, PyObject *ctype) return NULL; } -#ifdef CTYPES_UNICODE + static PyObject * wstring_at(const wchar_t *ptr, int size) { @@ -5678,133 +5659,74 @@ wstring_at(const wchar_t *ptr, int size) ssize = wcslen(ptr); return PyUnicode_FromWideChar(ptr, ssize); } -#endif static struct PyModuleDef _ctypesmodule = { PyModuleDef_HEAD_INIT, - "_ctypes", - module_docs, - -1, - _ctypes_module_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_ctypes", + .m_doc = module_docs, + .m_size = -1, + .m_methods = _ctypes_module_methods, }; -PyMODINIT_FUNC -PyInit__ctypes(void) -{ - PyObject *m; - -/* Note: - ob_type is the metatype (the 'type'), defaults to PyType_Type, - tp_base is the base type, defaults to 'object' aka PyBaseObject_Type. -*/ - m = PyModule_Create(&_ctypesmodule); - if (!m) - return NULL; - - _ctypes_ptrtype_cache = PyDict_New(); - if (_ctypes_ptrtype_cache == NULL) - return NULL; - - PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache); - - _unpickle = PyObject_GetAttrString(m, "_unpickle"); - if (_unpickle == NULL) - return NULL; - - if (PyType_Ready(&PyCArg_Type) < 0) - return NULL; - - if (PyType_Ready(&PyCThunk_Type) < 0) - return NULL; +static int +_ctypes_add_types(PyObject *mod) +{ +#define TYPE_READY(TYPE) \ + if (PyType_Ready(TYPE) < 0) { \ + return -1; \ + } + +#define TYPE_READY_BASE(TYPE_EXPR, TP_BASE) \ + do { \ + PyTypeObject *type = (TYPE_EXPR); \ + type->tp_base = (TP_BASE); \ + TYPE_READY(type); \ + } while (0) + +#define MOD_ADD_TYPE(TYPE_EXPR, TP_TYPE, TP_BASE) \ + do { \ + PyTypeObject *type = (TYPE_EXPR); \ + Py_SET_TYPE(type, TP_TYPE); \ + type->tp_base = TP_BASE; \ + if (PyModule_AddType(mod, type) < 0) { \ + return -1; \ + } \ + } while (0) + + /* 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); + TYPE_READY(&PyCData_Type); /* StgDict is derived from PyDict_Type */ - PyCStgDict_Type.tp_base = &PyDict_Type; - if (PyType_Ready(&PyCStgDict_Type) < 0) - return NULL; + TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type); /************************************************* * * Metaclasses */ - - PyCStructType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCStructType_Type) < 0) - return NULL; - - UnionType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&UnionType_Type) < 0) - return NULL; - - PyCPointerType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCPointerType_Type) < 0) - return NULL; - - PyCArrayType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCArrayType_Type) < 0) - return NULL; - - PyCSimpleType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCSimpleType_Type) < 0) - return NULL; - - PyCFuncPtrType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCFuncPtrType_Type) < 0) - return NULL; + TYPE_READY_BASE(&PyCStructType_Type, &PyType_Type); + TYPE_READY_BASE(&UnionType_Type, &PyType_Type); + TYPE_READY_BASE(&PyCPointerType_Type, &PyType_Type); + TYPE_READY_BASE(&PyCArrayType_Type, &PyType_Type); + TYPE_READY_BASE(&PyCSimpleType_Type, &PyType_Type); + TYPE_READY_BASE(&PyCFuncPtrType_Type, &PyType_Type); /************************************************* * * Classes using a custom metaclass */ - if (PyType_Ready(&PyCData_Type) < 0) - return NULL; - - Py_SET_TYPE(&Struct_Type, &PyCStructType_Type); - Struct_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&Struct_Type) < 0) - return NULL; - Py_INCREF(&Struct_Type); - PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); - - Py_SET_TYPE(&Union_Type, &UnionType_Type); - Union_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&Union_Type) < 0) - return NULL; - Py_INCREF(&Union_Type); - PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); - - Py_SET_TYPE(&PyCPointer_Type, &PyCPointerType_Type); - PyCPointer_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&PyCPointer_Type) < 0) - return NULL; - Py_INCREF(&PyCPointer_Type); - PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); - - Py_SET_TYPE(&PyCArray_Type, &PyCArrayType_Type); - PyCArray_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&PyCArray_Type) < 0) - return NULL; - Py_INCREF(&PyCArray_Type); - PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); - - Py_SET_TYPE(&Simple_Type, &PyCSimpleType_Type); - Simple_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&Simple_Type) < 0) - return NULL; - Py_INCREF(&Simple_Type); - PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); - - Py_SET_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type); - PyCFuncPtr_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&PyCFuncPtr_Type) < 0) - return NULL; - Py_INCREF(&PyCFuncPtr_Type); - PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type); + MOD_ADD_TYPE(&Struct_Type, &PyCStructType_Type, &PyCData_Type); + MOD_ADD_TYPE(&Union_Type, &UnionType_Type, &PyCData_Type); + MOD_ADD_TYPE(&PyCPointer_Type, &PyCPointerType_Type, &PyCData_Type); + MOD_ADD_TYPE(&PyCArray_Type, &PyCArrayType_Type, &PyCData_Type); + MOD_ADD_TYPE(&Simple_Type, &PyCSimpleType_Type, &PyCData_Type); + MOD_ADD_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type, &PyCData_Type); /************************************************* * @@ -5812,8 +5734,7 @@ PyInit__ctypes(void) */ /* PyCField_Type is derived from PyBaseObject_Type */ - if (PyType_Ready(&PyCField_Type) < 0) - return NULL; + TYPE_READY(&PyCField_Type); /************************************************* * @@ -5821,56 +5742,118 @@ PyInit__ctypes(void) */ DictRemover_Type.tp_new = PyType_GenericNew; - if (PyType_Ready(&DictRemover_Type) < 0) - return NULL; - - if (PyType_Ready(&StructParam_Type) < 0) { - return NULL; - } + TYPE_READY(&DictRemover_Type); + TYPE_READY(&StructParam_Type); #ifdef MS_WIN32 - if (create_comerror() < 0) - return NULL; - PyModule_AddObject(m, "COMError", ComError); - - PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT)); - PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL)); + TYPE_READY_BASE(&PyComError_Type, (PyTypeObject*)PyExc_Exception); #endif - PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL)); - PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO)); - PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR)); - PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI)); - PyModule_AddStringConstant(m, "__version__", "1.1.0"); - - PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove)); - PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset)); - PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at)); - PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast)); -#ifdef CTYPES_UNICODE - PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at)); + +#undef TYPE_READY +#undef TYPE_READY_BASE +#undef MOD_ADD_TYPE + return 0; +} + + +static int +_ctypes_add_objects(PyObject *mod) +{ +#define MOD_ADD(name, expr) \ + do { \ + PyObject *obj = (expr); \ + if (obj == NULL) { \ + return -1; \ + } \ + if (PyModule_AddObjectRef(mod, name, obj) < 0) { \ + Py_DECREF(obj); \ + return -1; \ + } \ + Py_DECREF(obj); \ + } while (0) + + MOD_ADD("_pointer_type_cache", Py_NewRef(_ctypes_ptrtype_cache)); + +#ifdef MS_WIN32 + MOD_ADD("COMError", Py_NewRef(ComError)); + MOD_ADD("FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT)); + MOD_ADD("FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL)); #endif + MOD_ADD("FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL)); + MOD_ADD("FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO)); + MOD_ADD("FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR)); + MOD_ADD("FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI)); + MOD_ADD("__version__", PyUnicode_FromString("1.1.0")); + + MOD_ADD("_memmove_addr", PyLong_FromVoidPtr(memmove)); + MOD_ADD("_memset_addr", PyLong_FromVoidPtr(memset)); + MOD_ADD("_string_at_addr", PyLong_FromVoidPtr(string_at)); + MOD_ADD("_cast_addr", PyLong_FromVoidPtr(cast)); + MOD_ADD("_wstring_at_addr", PyLong_FromVoidPtr(wstring_at)); /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */ #if !HAVE_DECL_RTLD_LOCAL -#define RTLD_LOCAL 0 +# define RTLD_LOCAL 0 #endif /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as - RTLD_LOCAL. -*/ + RTLD_LOCAL. */ #if !HAVE_DECL_RTLD_GLOBAL -#define RTLD_GLOBAL RTLD_LOCAL +# define RTLD_GLOBAL RTLD_LOCAL #endif + MOD_ADD("RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL)); + MOD_ADD("RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL)); + MOD_ADD("ArgumentError", Py_NewRef(PyExc_ArgError)); + return 0; +#undef MOD_ADD +} - PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL)); - PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL)); + +static int +_ctypes_mod_exec(PyObject *mod) +{ + _unpickle = PyObject_GetAttrString(mod, "_unpickle"); + if (_unpickle == NULL) { + return -1; + } + + _ctypes_ptrtype_cache = PyDict_New(); + if (_ctypes_ptrtype_cache == NULL) { + return -1; + } PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); - if (PyExc_ArgError) { - Py_INCREF(PyExc_ArgError); - PyModule_AddObject(m, "ArgumentError", PyExc_ArgError); + if (!PyExc_ArgError) { + return -1; + } + + if (_ctypes_add_types(mod) < 0) { + return -1; + } +#ifdef MS_WIN32 + ComError = (PyObject*)&PyComError_Type; +#endif + + if (_ctypes_add_objects(mod) < 0) { + return -1; + } + return 0; +} + + +PyMODINIT_FUNC +PyInit__ctypes(void) +{ + PyObject *mod = PyModule_Create(&_ctypesmodule); + if (!mod) { + return NULL; + } + + if (_ctypes_mod_exec(mod) < 0) { + Py_DECREF(mod); + return NULL; } - return m; + return mod; } /* diff --git a/contrib/tools/python3/src/Modules/_ctypes/callbacks.c b/contrib/tools/python3/src/Modules/_ctypes/callbacks.c index 0dc82428171..1afbd617c72 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/callbacks.c +++ b/contrib/tools/python3/src/Modules/_ctypes/callbacks.c @@ -112,8 +112,9 @@ TryAddRef(StgDictObject *dict, CDataObject *obj) IUnknown *punk; _Py_IDENTIFIER(_needs_com_addref_); - if (!_PyDict_GetItemIdWithError((PyObject *)dict, &PyId__needs_com_addref_)) { - if (PyErr_Occurred()) { + int r = _PyDict_ContainsId((PyObject *)dict, &PyId__needs_com_addref_); + if (r <= 0) { + if (r < 0) { PrintError("getting _needs_com_addref_"); } return; diff --git a/contrib/tools/python3/src/Modules/_ctypes/callproc.c b/contrib/tools/python3/src/Modules/_ctypes/callproc.c index 287bec47aa2..ce148e0ecd5 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/callproc.c +++ b/contrib/tools/python3/src/Modules/_ctypes/callproc.c @@ -255,8 +255,6 @@ set_last_error(PyObject *self, PyObject *args) return set_error_internal(self, args, 1); } -PyObject *ComError; - static WCHAR *FormatError(DWORD code) { WCHAR *lpMsgBuf; @@ -478,7 +476,7 @@ static void PyCArg_dealloc(PyCArgObject *self) { Py_XDECREF(self->obj); - PyObject_Del(self); + PyObject_Free(self); } static int @@ -703,7 +701,6 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) return 0; } -#ifdef CTYPES_UNICODE if (PyUnicode_Check(obj)) { pa->ffi_type = &ffi_type_pointer; pa->value.p = PyUnicode_AsWideCharString(obj, NULL); @@ -716,7 +713,6 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) } return 0; } -#endif { _Py_IDENTIFIER(_as_parameter_); @@ -1350,7 +1346,6 @@ module. load_flags are as defined for LoadLibraryEx in the\n\ Windows API.\n"; static PyObject *load_library(PyObject *self, PyObject *args) { - const WCHAR *name; PyObject *nameobj; int load_flags = 0; HMODULE hMod; @@ -1359,17 +1354,14 @@ static PyObject *load_library(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags)) return NULL; -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - name = _PyUnicode_AsUnicode(nameobj); -_Py_COMP_DIAG_POP - if (!name) - return NULL; - if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) { return NULL; } + WCHAR *name = PyUnicode_AsWideCharString(nameobj, NULL); + if (!name) + return NULL; + Py_BEGIN_ALLOW_THREADS /* bpo-36085: Limit DLL search directories to avoid pre-loading * attacks and enable use of the AddDllDirectory function. @@ -1378,6 +1370,7 @@ _Py_COMP_DIAG_POP err = hMod ? 0 : GetLastError(); Py_END_ALLOW_THREADS + PyMem_Free(name); if (err == ERROR_MOD_NOT_FOUND) { PyErr_Format(PyExc_FileNotFoundError, ("Could not find module '%.500S' (or one of its " diff --git a/contrib/tools/python3/src/Modules/_ctypes/cfield.c b/contrib/tools/python3/src/Modules/_ctypes/cfield.c index 26477776664..eed06289f00 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/cfield.c +++ b/contrib/tools/python3/src/Modules/_ctypes/cfield.c @@ -1,5 +1,5 @@ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() #include #ifdef MS_WIN32 @@ -126,13 +126,11 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index, getfunc = fd->getfunc; setfunc = fd->setfunc; } -#ifdef CTYPES_UNICODE if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { struct fielddesc *fd = _ctypes_get_fielddesc("U"); getfunc = fd->getfunc; setfunc = fd->setfunc; } -#endif } } @@ -355,14 +353,7 @@ PyTypeObject PyCField_Type = { static int get_long(PyObject *v, long *p) { - long x; - - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongMask(v); + long x = PyLong_AsUnsignedLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; *p = x; @@ -374,14 +365,7 @@ get_long(PyObject *v, long *p) static int get_ulong(PyObject *v, unsigned long *p) { - unsigned long x; - - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongMask(v); + unsigned long x = PyLong_AsUnsignedLongMask(v); if (x == (unsigned long)-1 && PyErr_Occurred()) return -1; *p = x; @@ -393,13 +377,7 @@ get_ulong(PyObject *v, unsigned long *p) static int get_longlong(PyObject *v, long long *p) { - long long x; - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongLongMask(v); + long long x = PyLong_AsUnsignedLongLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; *p = x; @@ -411,13 +389,7 @@ get_longlong(PyObject *v, long long *p) static int get_ulonglong(PyObject *v, unsigned long long *p) { - unsigned long long x; - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongLongMask(v); + unsigned long long x = PyLong_AsUnsignedLongLongMask(v); if (x == (unsigned long long)-1 && PyErr_Occurred()) return -1; *p = x; @@ -1164,7 +1136,6 @@ c_get(void *ptr, Py_ssize_t size) return PyBytes_FromStringAndSize((char *)ptr, 1); } -#ifdef CTYPES_UNICODE /* u - a single wchar_t character */ static PyObject * u_set(void *ptr, PyObject *value, Py_ssize_t size) @@ -1250,11 +1221,8 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) "string too long (%zd, maximum length %zd)", size, length); return NULL; - } else if (size < length-1) - /* copy terminating NUL character if there is space */ - size += 1; - - if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, size) == -1) { + } + if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, length) == -1) { return NULL; } @@ -1262,7 +1230,6 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) return value; } -#endif static PyObject * s_get(void *ptr, Py_ssize_t size) @@ -1293,7 +1260,9 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) } data = PyBytes_AS_STRING(value); - size = strlen(data); /* XXX Why not Py_SIZE(value)? */ + // bpo-39593: Use strlen() to truncate the string at the first null character. + size = strlen(data); + if (size < length) { /* This will copy the terminating NUL character * if there is space for it. @@ -1349,7 +1318,6 @@ z_get(void *ptr, Py_ssize_t size) } } -#ifdef CTYPES_UNICODE static PyObject * Z_set(void *ptr, PyObject *value, Py_ssize_t size) { @@ -1402,7 +1370,7 @@ Z_get(void *ptr, Py_ssize_t size) Py_RETURN_NONE; } } -#endif + #ifdef MS_WIN32 static PyObject * @@ -1536,11 +1504,9 @@ static struct fielddesc formattable[] = { #endif { 'P', P_set, P_get, &ffi_type_pointer}, { 'z', z_set, z_get, &ffi_type_pointer}, -#ifdef CTYPES_UNICODE { 'u', u_set, u_get, NULL}, /* ffi_type set later */ { 'U', U_set, U_get, &ffi_type_pointer}, { 'Z', Z_set, Z_get, &ffi_type_pointer}, -#endif #ifdef MS_WIN32 { 'X', BSTR_set, BSTR_get, &ffi_type_pointer}, #endif @@ -1573,14 +1539,12 @@ _ctypes_get_fielddesc(const char *fmt) if (!initialized) { initialized = 1; -#ifdef CTYPES_UNICODE if (sizeof(wchar_t) == sizeof(short)) _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; else if (sizeof(wchar_t) == sizeof(int)) _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint; else if (sizeof(wchar_t) == sizeof(long)) _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong; -#endif } for (; table->code; ++table) { diff --git a/contrib/tools/python3/src/Modules/_ctypes/ctypes.h b/contrib/tools/python3/src/Modules/_ctypes/ctypes.h index 0f422113a89..9600ddc7413 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/ctypes.h +++ b/contrib/tools/python3/src/Modules/_ctypes/ctypes.h @@ -343,10 +343,6 @@ extern PyObject *PyExc_ArgError; extern char *_ctypes_conversion_encoding; extern char *_ctypes_conversion_errors; -#if defined(HAVE_WCHAR_H) -# define CTYPES_UNICODE -#endif - extern void _ctypes_free_closure(void *); extern void *_ctypes_alloc_closure(void); diff --git a/contrib/tools/python3/src/Modules/_ctypes/stgdict.c b/contrib/tools/python3/src/Modules/_ctypes/stgdict.c index bbef2921e6f..3951ce9565d 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/stgdict.c +++ b/contrib/tools/python3/src/Modules/_ctypes/stgdict.c @@ -539,9 +539,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: if (dict->getfunc != _ctypes_get_fielddesc("c")->getfunc -#ifdef CTYPES_UNICODE && dict->getfunc != _ctypes_get_fielddesc("u")->getfunc -#endif ) break; /* else fall through */ diff --git a/contrib/tools/python3/src/Modules/_datetimemodule.c b/contrib/tools/python3/src/Modules/_datetimemodule.c index 96023754056..e54a01b44c5 100644 --- a/contrib/tools/python3/src/Modules/_datetimemodule.c +++ b/contrib/tools/python3/src/Modules/_datetimemodule.c @@ -8,6 +8,8 @@ #define _PY_DATETIME_IMPL #include "Python.h" +#include "pycore_long.h" // _PyLong_GetOne() +#include "pycore_object.h" // _PyObject_Init() #include "datetime.h" #include "structmember.h" // PyMemberDef @@ -114,14 +116,9 @@ class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCa #define SET_TD_SECONDS(o, v) ((o)->seconds = (v)) #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v)) -/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns - * p->hastzinfo. - */ -#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo) -#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \ - ((PyDateTime_Time *)(p))->tzinfo : Py_None) -#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \ - ((PyDateTime_DateTime *)(p))->tzinfo : Py_None) +#define HASTZINFO _PyDateTime_HAS_TZINFO +#define GET_TIME_TZINFO PyDateTime_TIME_GET_TZINFO +#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO /* M is a char or int claiming to be a valid month. The macro is equivalent * to the two-sided Python test * 1 <= M <= 12 @@ -638,30 +635,24 @@ normalize_datetime(int *year, int *month, int *day, static PyObject * time_alloc(PyTypeObject *type, Py_ssize_t aware) { - PyObject *self; - - self = (PyObject *) - PyObject_MALLOC(aware ? - sizeof(PyDateTime_Time) : - sizeof(_PyDateTime_BaseTime)); - if (self == NULL) - return (PyObject *)PyErr_NoMemory(); - (void)PyObject_INIT(self, type); + size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime); + PyObject *self = (PyObject *)PyObject_Malloc(size); + if (self == NULL) { + return PyErr_NoMemory(); + } + _PyObject_Init(self, type); return self; } static PyObject * datetime_alloc(PyTypeObject *type, Py_ssize_t aware) { - PyObject *self; - - self = (PyObject *) - PyObject_MALLOC(aware ? - sizeof(PyDateTime_DateTime) : - sizeof(_PyDateTime_BaseDateTime)); - if (self == NULL) - return (PyObject *)PyErr_NoMemory(); - (void)PyObject_INIT(self, type); + size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime); + PyObject *self = (PyObject *)PyObject_Malloc(size); + if (self == NULL) { + return PyErr_NoMemory(); + } + _PyObject_Init(self, type); return self; } @@ -2458,7 +2449,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) goto Done if (us) { - y = accum("microseconds", x, us, _PyLong_One, &leftover_us); + y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us); CLEANUP; } if (ms) { @@ -2497,7 +2488,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) * is odd. Note that x is odd when it's last bit is 1. The * code below uses bitwise and operation to check the last * bit. */ - temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */ + temp = PyNumber_And(x, _PyLong_GetOne()); /* temp <- x & 1 */ if (temp == NULL) { Py_DECREF(x); goto Done; @@ -6482,53 +6473,48 @@ static PyMethodDef module_methods[] = { {NULL, NULL} }; -/* C API. Clients get at this via PyDateTime_IMPORT, defined in - * datetime.h. +/* Get a new C API by calling this function. + * Clients get at C API via PyDateTime_IMPORT, defined in datetime.h. */ -static PyDateTime_CAPI CAPI = { - &PyDateTime_DateType, - &PyDateTime_DateTimeType, - &PyDateTime_TimeType, - &PyDateTime_DeltaType, - &PyDateTime_TZInfoType, - NULL, // PyDatetime_TimeZone_UTC not initialized yet - new_date_ex, - new_datetime_ex, - new_time_ex, - new_delta_ex, - new_timezone, - datetime_fromtimestamp, - datetime_date_fromtimestamp_capi, - new_datetime_ex2, - new_time_ex2 -}; - - - -static struct PyModuleDef datetimemodule = { - PyModuleDef_HEAD_INIT, - "_datetime", - "Fast implementation of the datetime type.", - -1, - module_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__datetime(void) +static inline PyDateTime_CAPI * +get_datetime_capi(void) { - PyObject *m; /* a module object */ - PyObject *d; /* its dict */ - PyObject *x; - PyObject *delta; - - m = PyModule_Create(&datetimemodule); - if (m == NULL) + PyDateTime_CAPI *capi = PyMem_Malloc(sizeof(PyDateTime_CAPI)); + if (capi == NULL) { + PyErr_NoMemory(); return NULL; + } + capi->DateType = &PyDateTime_DateType; + capi->DateTimeType = &PyDateTime_DateTimeType; + capi->TimeType = &PyDateTime_TimeType; + capi->DeltaType = &PyDateTime_DeltaType; + capi->TZInfoType = &PyDateTime_TZInfoType; + capi->Date_FromDate = new_date_ex; + capi->DateTime_FromDateAndTime = new_datetime_ex; + capi->Time_FromTime = new_time_ex; + capi->Delta_FromDelta = new_delta_ex; + capi->TimeZone_FromTimeZone = new_timezone; + capi->DateTime_FromTimestamp = datetime_fromtimestamp; + capi->Date_FromTimestamp = datetime_date_fromtimestamp_capi; + capi->DateTime_FromDateAndTimeAndFold = new_datetime_ex2; + capi->Time_FromTimeAndFold = new_time_ex2; + // Make sure this function is called after PyDateTime_TimeZone_UTC has + // been initialized. + assert(PyDateTime_TimeZone_UTC != NULL); + capi->TimeZone_UTC = PyDateTime_TimeZone_UTC; // borrowed ref + return capi; +} +static void +datetime_destructor(PyObject *op) +{ + void *ptr = PyCapsule_GetPointer(op, PyDateTime_CAPSULE_NAME); + PyMem_Free(ptr); +} + +static int +_datetime_exec(PyObject *module) +{ // `&...` is not a constant expression according to a strict reading // of C standards. Fill tp_base at run-time rather than statically. // See https://bugs.python.org/issue40777 @@ -6546,136 +6532,124 @@ PyInit__datetime(void) }; for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { - if (PyModule_AddType(m, types[i]) < 0) { - return NULL; + if (PyModule_AddType(module, types[i]) < 0) { + return -1; } } if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) { - return NULL; + return -1; } - Py_INCREF(&PyDateTime_IsoCalendarDateType); - /* timedelta values */ - d = PyDateTime_DeltaType.tp_dict; +#define DATETIME_ADD_MACRO(dict, c, value_expr) \ + do { \ + PyObject *value = (value_expr); \ + if (value == NULL) { \ + return -1; \ + } \ + if (PyDict_SetItemString(dict, c, value) < 0) { \ + Py_DECREF(value); \ + return -1; \ + } \ + Py_DECREF(value); \ + } while(0) - x = new_delta(0, 0, 1, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); + /* timedelta values */ + PyObject *d = PyDateTime_DeltaType.tp_dict; + DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); + DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0)); + DATETIME_ADD_MACRO(d, "max", + new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0)); /* date values */ d = PyDateTime_DateType.tp_dict; - - x = new_date(1, 1, 1); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_date(MAXYEAR, 12, 31); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(1, 0, 0, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); + DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1)); + DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31)); + DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0)); /* time values */ d = PyDateTime_TimeType.tp_dict; - - x = new_time(0, 0, 0, 0, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_time(23, 59, 59, 999999, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(0, 0, 1, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); + DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0)); + DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0)); + DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); /* datetime values */ d = PyDateTime_DateTimeType.tp_dict; - - x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(0, 0, 1, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); + DATETIME_ADD_MACRO(d, "min", + new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0)); + DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59, + 999999, Py_None, 0)); + DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); /* timezone values */ d = PyDateTime_TimeZoneType.tp_dict; + PyObject *delta = new_delta(0, 0, 0, 0); + if (delta == NULL) { + return -1; + } - delta = new_delta(0, 0, 0, 0); - if (delta == NULL) - return NULL; - x = create_timezone(delta, NULL); + PyObject *x = create_timezone(delta, NULL); Py_DECREF(delta); - if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0) - return NULL; + if (x == NULL) { + return -1; + } + if (PyDict_SetItemString(d, "utc", x) < 0) { + Py_DECREF(x); + return -1; + } + PyDateTime_TimeZone_UTC = x; - CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC; /* 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.*/ delta = new_delta(-1, 60, 0, 1); /* -23:59 */ - if (delta == NULL) - return NULL; + if (delta == NULL) { + return -1; + } + x = create_timezone(delta, NULL); Py_DECREF(delta); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); + DATETIME_ADD_MACRO(d, "min", x); delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */ - if (delta == NULL) - return NULL; + if (delta == NULL) { + return -1; + } + x = create_timezone(delta, NULL); Py_DECREF(delta); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); + DATETIME_ADD_MACRO(d, "max", x); /* Epoch */ PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, PyDateTime_TimeZone_UTC, 0); - if (PyDateTime_Epoch == NULL) - return NULL; + if (PyDateTime_Epoch == NULL) { + return -1; + } /* module initialization */ - PyModule_AddIntMacro(m, MINYEAR); - PyModule_AddIntMacro(m, MAXYEAR); + if (PyModule_AddIntMacro(module, MINYEAR) < 0) { + return -1; + } + if (PyModule_AddIntMacro(module, MAXYEAR) < 0) { + return -1; + } - x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL); - if (x == NULL) - return NULL; - PyModule_AddObject(m, "datetime_CAPI", x); + PyDateTime_CAPI *capi = get_datetime_capi(); + if (capi == NULL) { + return -1; + } + x = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, datetime_destructor); + if (x == NULL) { + PyMem_Free(capi); + return -1; + } + + if (PyModule_AddObject(module, "datetime_CAPI", x) < 0) { + Py_DECREF(x); + return -1; + } /* A 4-year cycle has an extra leap day over what we'd get from * pasting together 4 single years. @@ -6700,8 +6674,9 @@ PyInit__datetime(void) us_per_minute = PyLong_FromLong(60000000); 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 NULL; + us_per_minute == NULL || seconds_per_day == NULL) { + return -1; + } /* The rest are too big for 32-bit ints, but even * us_per_week fits in 40 bits, so doubles should be exact. @@ -6709,9 +6684,33 @@ PyInit__datetime(void) us_per_hour = PyLong_FromDouble(3600000000.0); us_per_day = PyLong_FromDouble(86400000000.0); us_per_week = PyLong_FromDouble(604800000000.0); - if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) + if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) { + return -1; + } + return 0; +} + +static struct PyModuleDef datetimemodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_datetime", + .m_doc = "Fast implementation of the datetime type.", + .m_size = -1, + .m_methods = module_methods, +}; + +PyMODINIT_FUNC +PyInit__datetime(void) +{ + PyObject *mod = PyModule_Create(&datetimemodule); + if (mod == NULL) return NULL; - return m; + + if (_datetime_exec(mod) < 0) { + Py_DECREF(mod); + return NULL; + } + + return mod; } /* --------------------------------------------------------------------------- diff --git a/contrib/tools/python3/src/Modules/_decimal/_decimal.c b/contrib/tools/python3/src/Modules/_decimal/_decimal.c index d80d7915507..e2979a577c9 100644 --- a/contrib/tools/python3/src/Modules/_decimal/_decimal.c +++ b/contrib/tools/python3/src/Modules/_decimal/_decimal.c @@ -1762,7 +1762,7 @@ ctxmanager_dealloc(PyDecContextManagerObject *self) { Py_XDECREF(self->local); Py_XDECREF(self->global); - PyObject_Del(self); + PyObject_Free(self); } static PyObject * @@ -3183,6 +3183,31 @@ dotsep_as_utf8(const char *s) return utf8; } +static int +dict_get_item_string(PyObject *dict, const char *key, PyObject **valueobj, const char **valuestr) +{ + *valueobj = NULL; + PyObject *keyobj = PyUnicode_FromString(key); + if (keyobj == NULL) { + return -1; + } + PyObject *value = PyDict_GetItemWithError(dict, keyobj); + Py_DECREF(keyobj); + if (value == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + value = PyUnicode_AsUTF8String(value); + if (value == NULL) { + return -1; + } + *valueobj = value; + *valuestr = PyBytes_AS_STRING(value); + return 0; +} + /* Formatted representation of a PyDecObject. */ static PyObject * dec_format(PyObject *dec, PyObject *args) @@ -3253,23 +3278,11 @@ dec_format(PyObject *dec, PyObject *args) "optional argument must be a dict"); goto finish; } - if ((dot = PyDict_GetItemString(override, "decimal_point"))) { - if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) { - goto finish; - } - spec.dot = PyBytes_AS_STRING(dot); - } - if ((sep = PyDict_GetItemString(override, "thousands_sep"))) { - if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) { - goto finish; - } - spec.sep = PyBytes_AS_STRING(sep); - } - if ((grouping = PyDict_GetItemString(override, "grouping"))) { - if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) { - goto finish; - } - spec.grouping = PyBytes_AS_STRING(grouping); + if (dict_get_item_string(override, "decimal_point", &dot, &spec.dot) || + dict_get_item_string(override, "thousands_sep", &sep, &spec.sep) || + dict_get_item_string(override, "grouping", &grouping, &spec.grouping)) + { + goto finish; } if (mpd_validate_lconv(&spec) < 0) { PyErr_SetString(PyExc_ValueError, @@ -3279,7 +3292,7 @@ dec_format(PyObject *dec, PyObject *args) } else { size_t n = strlen(spec.dot); - if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) { + if (n > 1 || (n == 1 && !isascii((unsigned char)spec.dot[0]))) { /* fix locale dependent non-ascii characters */ dot = dotsep_as_utf8(spec.dot); if (dot == NULL) { @@ -3288,7 +3301,7 @@ dec_format(PyObject *dec, PyObject *args) spec.dot = PyBytes_AS_STRING(dot); } n = strlen(spec.sep); - if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) { + if (n > 1 || (n == 1 && !isascii((unsigned char)spec.sep[0]))) { /* fix locale dependent non-ascii characters */ sep = dotsep_as_utf8(spec.sep); if (sep == NULL) { @@ -4522,7 +4535,6 @@ _dec_hash(PyDecObject *v) #error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS" #endif const Py_hash_t py_hash_inf = 314159; - const Py_hash_t py_hash_nan = 0; mpd_uint_t ten_data[1] = {10}; mpd_t ten = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 2, 1, 1, ten_data}; @@ -4541,7 +4553,7 @@ _dec_hash(PyDecObject *v) return -1; } else if (mpd_isnan(MPD(v))) { - return py_hash_nan; + return _Py_HashPointer(v); } else { return py_hash_inf * mpd_arith_sign(MPD(v)); @@ -5925,5 +5937,3 @@ error: return NULL; /* GCOV_NOT_REACHED */ } - - diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/bench.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/bench.c new file mode 100644 index 00000000000..09138f4ce9c --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/bench.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include "mpdecimal.h" + +#include +#include +#include +#include + + +static void +err_exit(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(1); +} + +static mpd_t * +new_mpd(void) +{ + mpd_t *x = mpd_qnew(); + if (x == NULL) { + err_exit("out of memory"); + } + + return x; +} + +/* Nonsense version of escape-time algorithm for calculating a mandelbrot + * set. Just for benchmarking. */ +static void +color_point(mpd_t *x0, mpd_t *y0, long maxiter, mpd_context_t *ctx) +{ + mpd_t *x, *y, *sq_x, *sq_y; + mpd_t *two; + + x = new_mpd(); + y = new_mpd(); + mpd_set_u32(x, 0, ctx); + mpd_set_u32(y, 0, ctx); + + sq_x = new_mpd(); + sq_y = new_mpd(); + mpd_set_u32(sq_x, 0, ctx); + mpd_set_u32(sq_y, 0, ctx); + + two = new_mpd(); + mpd_set_u32(two, 2, ctx); + + for (long i = 0; i < maxiter; i++) { + mpd_mul(y, x, y, ctx); + mpd_mul(y, y, two, ctx); + mpd_add(y, y, y0, ctx); + + mpd_sub(x, sq_x, sq_y, ctx); + mpd_add(x, x, x0, ctx); + + mpd_mul(sq_x, x, x, ctx); + mpd_mul(sq_y, y, y, ctx); + } + + mpd_copy(x0, x, ctx); + + mpd_del(two); + mpd_del(sq_y); + mpd_del(sq_x); + mpd_del(y); + mpd_del(x); +} + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *x0, *y0; + uint32_t prec = 19; + long iter = 10000000; + clock_t start_clock, end_clock; + + if (argc != 3) { + err_exit("usage: bench prec iter\n"); + } + prec = strtoul(argv[1], NULL, 10); + iter = strtol(argv[2], NULL, 10); + + mpd_init(&ctx, prec); + /* no more MPD_MINALLOC changes after here */ + + x0 = new_mpd(); + y0 = new_mpd(); + mpd_set_string(x0, "0.222", &ctx); + mpd_set_string(y0, "0.333", &ctx); + if (ctx.status & MPD_Errors) { + mpd_del(y0); + mpd_del(x0); + err_exit("unexpected error during conversion"); + } + + start_clock = clock(); + color_point(x0, y0, iter, &ctx); + end_clock = clock(); + + mpd_print(x0); + fprintf(stderr, "time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + mpd_del(y0); + mpd_del(x0); + + return 0; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/bench_full.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/bench_full.c new file mode 100644 index 00000000000..6ab73917e1c --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/bench_full.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include "mpdecimal.h" + +#include +#include +#include +#include + + +static void +err_exit(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(1); +} + +static mpd_t * +new_mpd(void) +{ + mpd_t *x = mpd_qnew(); + if (x == NULL) { + err_exit("out of memory"); + } + + return x; +} + +/* + * Example from: http://en.wikipedia.org/wiki/Mandelbrot_set + * + * Escape time algorithm for drawing the set: + * + * Point x0, y0 is deemed to be in the Mandelbrot set if the return + * value is maxiter. Lower return values indicate how quickly points + * escaped and can be used for coloring. + */ +static int +color_point(const mpd_t *x0, const mpd_t *y0, const long maxiter, mpd_context_t *ctx) +{ + mpd_t *x, *y, *sq_x, *sq_y; + mpd_t *two, *four, *c; + long i; + + x = new_mpd(); + y = new_mpd(); + mpd_set_u32(x, 0, ctx); + mpd_set_u32(y, 0, ctx); + + sq_x = new_mpd(); + sq_y = new_mpd(); + mpd_set_u32(sq_x, 0, ctx); + mpd_set_u32(sq_y, 0, ctx); + + two = new_mpd(); + four = new_mpd(); + mpd_set_u32(two, 2, ctx); + mpd_set_u32(four, 4, ctx); + + c = new_mpd(); + mpd_set_u32(c, 0, ctx); + + for (i = 0; i < maxiter && mpd_cmp(c, four, ctx) <= 0; i++) { + mpd_mul(y, x, y, ctx); + mpd_mul(y, y, two, ctx); + mpd_add(y, y, y0, ctx); + + mpd_sub(x, sq_x, sq_y, ctx); + mpd_add(x, x, x0, ctx); + + mpd_mul(sq_x, x, x, ctx); + mpd_mul(sq_y, y, y, ctx); + mpd_add(c, sq_x, sq_y, ctx); + } + + mpd_del(c); + mpd_del(four); + mpd_del(two); + mpd_del(sq_y); + mpd_del(sq_x); + mpd_del(y); + mpd_del(x); + + return i; +} + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *x0, *y0; + mpd_t *sqrt_2, *xstep, *ystep; + mpd_ssize_t prec = 19; + + long iter = 1000; + int points[40][80]; + int i, j; + clock_t start_clock, end_clock; + + + if (argc != 3) { + fprintf(stderr, "usage: ./bench prec iter\n"); + exit(1); + } + prec = strtoll(argv[1], NULL, 10); + iter = strtol(argv[2], NULL, 10); + + mpd_init(&ctx, prec); + /* no more MPD_MINALLOC changes after here */ + + sqrt_2 = new_mpd(); + xstep = new_mpd(); + ystep = new_mpd(); + x0 = new_mpd(); + y0 = new_mpd(); + + mpd_set_u32(sqrt_2, 2, &ctx); + mpd_sqrt(sqrt_2, sqrt_2, &ctx); + mpd_div_u32(xstep, sqrt_2, 40, &ctx); + mpd_div_u32(ystep, sqrt_2, 20, &ctx); + + start_clock = clock(); + mpd_copy(y0, sqrt_2, &ctx); + for (i = 0; i < 40; i++) { + mpd_copy(x0, sqrt_2, &ctx); + mpd_set_negative(x0); + for (j = 0; j < 80; j++) { + points[i][j] = color_point(x0, y0, iter, &ctx); + mpd_add(x0, x0, xstep, &ctx); + } + mpd_sub(y0, y0, ystep, &ctx); + } + end_clock = clock(); + +#ifdef BENCH_VERBOSE + for (i = 0; i < 40; i++) { + for (j = 0; j < 80; j++) { + if (points[i][j] == iter) { + putchar('*'); + } + else if (points[i][j] >= 10) { + putchar('+'); + } + else if (points[i][j] >= 5) { + putchar('.'); + } + else { + putchar(' '); + } + } + putchar('\n'); + } + putchar('\n'); +#else + (void)points; /* suppress gcc warning */ +#endif + + printf("time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + mpd_del(y0); + mpd_del(x0); + mpd_del(ystep); + mpd_del(xstep); + mpd_del(sqrt_2); + + return 0; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c index 4c4de622bc6..ed074fa81c6 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c @@ -27,6 +27,7 @@ #include "mpdecimal.h" +#include "basearith.h" #include "constants.h" @@ -111,7 +112,7 @@ #error "CONFIG_64 or CONFIG_32 must be defined." #endif -const char *mpd_round_string[MPD_ROUND_GUARD] = { +const char * const mpd_round_string[MPD_ROUND_GUARD] = { "ROUND_UP", /* round away from 0 */ "ROUND_DOWN", /* round toward 0 (truncate) */ "ROUND_CEILING", /* round toward +infinity */ @@ -123,7 +124,7 @@ const char *mpd_round_string[MPD_ROUND_GUARD] = { "ROUND_TRUNC", /* truncate, but set infinity */ }; -const char *mpd_clamp_string[MPD_CLAMP_GUARD] = { +const char * const mpd_clamp_string[MPD_CLAMP_GUARD] = { "CLAMP_DEFAULT", "CLAMP_IEEE_754" }; diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c index 9cbc2050959..172794b67d8 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c @@ -235,12 +235,12 @@ mpd_qsetround(mpd_context_t *ctx, int round) } int -mpd_qsettraps(mpd_context_t *ctx, uint32_t traps) +mpd_qsettraps(mpd_context_t *ctx, uint32_t flags) { - if (traps > MPD_Max_status) { + if (flags > MPD_Max_status) { return 0; } - ctx->traps = traps; + ctx->traps = flags; return 1; } diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c index 613274ee0c5..babcce41bf6 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c @@ -33,8 +33,8 @@ #include "constants.h" #include "crt.h" #include "numbertheory.h" -#include "umodarith.h" #include "typearith.h" +#include "umodarith.h" /* Bignum: Chinese Remainder Theorem, extends the maximum transform length. */ @@ -62,17 +62,17 @@ static inline void _crt_add3(mpd_uint_t w[3], mpd_uint_t v[3]) { mpd_uint_t carry; - mpd_uint_t s; - s = w[0] + v[0]; - carry = (s < w[0]); - w[0] = s; + w[0] = w[0] + v[0]; + carry = (w[0] < v[0]); + + w[1] = w[1] + v[1]; + if (w[1] < v[1]) w[2]++; - s = w[1] + (v[1] + carry); - carry = (s < w[1]); - w[1] = s; + w[1] = w[1] + carry; + if (w[1] < carry) w[2]++; - w[2] = w[2] + (v[2] + carry); + w[2] += v[2]; } /* Divide 3 words in u by v, store result in w, return remainder. */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h index 15a347d4cb3..ed66753c251 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h @@ -37,7 +37,7 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) -void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t nmemb); +void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t rsize); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/compare.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/compare.c new file mode 100644 index 00000000000..9051773e116 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/compare.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a, *b; + mpd_t *result; + char *rstring; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 3) { + fprintf(stderr, "compare: usage: ./compare x y\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + result = mpd_new(&ctx); + a = mpd_new(&ctx); + b = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + mpd_set_string(b, argv[2], &ctx); + + start_clock = clock(); + mpd_compare(result, a, b, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + rstring = mpd_to_sci(result, 1); + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s\n", rstring, status_str); + + mpd_del(a); + mpd_del(b); + mpd_del(result); + mpd_free(rstring); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/div.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/div.c new file mode 100644 index 00000000000..b76037d2a64 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/div.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a, *b; + mpd_t *result; + char *rstring; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 3) { + fprintf(stderr, "div: usage: ./div x y\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + result = mpd_new(&ctx); + a = mpd_new(&ctx); + b = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + mpd_set_string(b, argv[2], &ctx); + + start_clock = clock(); + mpd_div(result, a, b, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + rstring = mpd_to_sci(result, 1); + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s\n", rstring, status_str); + + mpd_del(a); + mpd_del(b); + mpd_del(result); + mpd_free(rstring); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/divmod.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/divmod.c new file mode 100644 index 00000000000..1f2b48306d6 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/divmod.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a, *b; + mpd_t *q, *r; + char *qs, *rs; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 3) { + fprintf(stderr, "divmod: usage: ./divmod x y\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + q = mpd_new(&ctx); + r = mpd_new(&ctx); + a = mpd_new(&ctx); + b = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + mpd_set_string(b, argv[2], &ctx); + + start_clock = clock(); + mpd_divmod(q, r, a, b, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + qs = mpd_to_sci(q, 1); + rs = mpd_to_sci(r, 1); + + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s %s\n", qs, rs, status_str); + + mpd_del(q); + mpd_del(r); + mpd_del(a); + mpd_del(b); + mpd_free(qs); + mpd_free(rs); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/multiply.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/multiply.c new file mode 100644 index 00000000000..7f2687d15f8 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/multiply.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a, *b; + mpd_t *result; + char *rstring; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 3) { + fprintf(stderr, "multiply: usage: ./multiply x y\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + result = mpd_new(&ctx); + a = mpd_new(&ctx); + b = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + mpd_set_string(b, argv[2], &ctx); + + start_clock = clock(); + mpd_mul(result, a, b, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + rstring = mpd_to_sci(result, 1); + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s\n", rstring, status_str); + + mpd_del(a); + mpd_del(b); + mpd_del(result); + mpd_free(rstring); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/pow.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/pow.c new file mode 100644 index 00000000000..628c1434273 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/pow.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a, *b; + mpd_t *result; + char *rstring; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 3) { + fprintf(stderr, "pow: usage: ./pow x y\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + result = mpd_new(&ctx); + a = mpd_new(&ctx); + b = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + mpd_set_string(b, argv[2], &ctx); + + start_clock = clock(); + mpd_pow(result, a, b, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + rstring = mpd_to_sci(result, 1); + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s\n", rstring, status_str); + + mpd_del(a); + mpd_del(b); + mpd_del(result); + mpd_free(rstring); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/powmod.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/powmod.c new file mode 100644 index 00000000000..b422fdbbb95 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/powmod.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a, *b, *c; + mpd_t *result; + char *rstring; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 4) { + fprintf(stderr, "powmod: usage: ./powmod x y z\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + result = mpd_new(&ctx); + a = mpd_new(&ctx); + b = mpd_new(&ctx); + c = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + mpd_set_string(b, argv[2], &ctx); + mpd_set_string(c, argv[3], &ctx); + + start_clock = clock(); + mpd_powmod(result, a, b, c, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + rstring = mpd_to_sci(result, 1); + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s\n", rstring, status_str); + + mpd_del(a); + mpd_del(b); + mpd_del(c); + mpd_del(result); + mpd_free(rstring); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/shift.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/shift.c new file mode 100644 index 00000000000..6d54e108ca8 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/shift.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a, *b; + mpd_t *result; + char *rstring; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 3) { + fprintf(stderr, "shift: usage: ./shift x y\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + result = mpd_new(&ctx); + a = mpd_new(&ctx); + b = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + mpd_set_string(b, argv[2], &ctx); + + start_clock = clock(); + mpd_shift(result, a, b, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + rstring = mpd_to_sci(result, 1); + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s\n", rstring, status_str); + + mpd_del(a); + mpd_del(b); + mpd_del(result); + mpd_free(rstring); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/sqrt.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/sqrt.c new file mode 100644 index 00000000000..d8272789b18 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/examples/sqrt.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + mpd_context_t ctx; + mpd_t *a; + mpd_t *result; + char *rstring; + char status_str[MPD_MAX_FLAG_STRING]; + clock_t start_clock, end_clock; + + if (argc != 2) { + fprintf(stderr, "sqrt: usage: ./sqrt x\n"); + exit(1); + } + + mpd_init(&ctx, 38); + ctx.traps = 0; + + result = mpd_new(&ctx); + a = mpd_new(&ctx); + mpd_set_string(a, argv[1], &ctx); + + start_clock = clock(); + mpd_sqrt(result, a, &ctx); + end_clock = clock(); + fprintf(stderr, "time: %f\n\n", + (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); + + rstring = mpd_to_sci(result, 1); + mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); + printf("%s %s\n", rstring, status_str); + + mpd_del(a); + mpd_del(result); + mpd_free(rstring); + + return 0; +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/io.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/io.c index 03f2acfc1a7..ecebe82e1f5 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/io.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/io.c @@ -37,17 +37,17 @@ #include #include -#include "typearith.h" #include "mpd_io.h" +#include "typearith.h" /* This file contains functions for decimal <-> string conversions, including PEP-3101 formatting for numeric types. */ -/* Disable warning that is part of -Wextra since gcc 7.0. */ #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && __GNUC__ >= 7 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" + #pragma GCC diagnostic ignored "-Wmisleading-indentation" #endif @@ -155,13 +155,13 @@ scan_dpoint_exp(const char *s, const char **dpoint, const char **exp, s++; break; default: - if (!isdigit((uchar)*s)) + if (!isdigit((unsigned char)*s)) return NULL; if (coeff == NULL && *exp == NULL) { if (*s == '0') { - if (!isdigit((uchar)*(s+1))) + if (!isdigit((unsigned char)*(s+1))) if (!(*(s+1) == '.' && - isdigit((uchar)*(s+2)))) + isdigit((unsigned char)*(s+2)))) coeff = s; } else { @@ -187,7 +187,7 @@ scan_payload(const char *s, const char **end) s++; coeff = s; - while (isdigit((uchar)*s)) + while (isdigit((unsigned char)*s)) s++; *end = s; @@ -689,8 +689,8 @@ mpd_to_eng_size(char **res, const mpd_t *dec, int fmt) static int _mpd_copy_utf8(char dest[5], const char *s) { - const uchar *cp = (const uchar *)s; - uchar lb, ub; + const unsigned char *cp = (const unsigned char *)s; + unsigned char lb, ub; int count, i; @@ -843,7 +843,7 @@ mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps) } /* minimum width */ - if (isdigit((uchar)*cp)) { + if (isdigit((unsigned char)*cp)) { if (*cp == '0') { return 0; } @@ -865,7 +865,7 @@ mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps) /* fraction digits or significant digits */ if (*cp == '.') { cp++; - if (!isdigit((uchar)*cp)) { + if (!isdigit((unsigned char)*cp)) { return 0; } errno = 0; @@ -1105,9 +1105,9 @@ _mpd_apply_lconv(mpd_mbstr_t *result, const mpd_spec_t *spec, uint32_t *status) sign = dp++; } /* integer part */ - assert(isdigit((uchar)*dp)); + assert(isdigit((unsigned char)*dp)); intpart = dp++; - while (isdigit((uchar)*dp)) { + while (isdigit((unsigned char)*dp)) { dp++; } n_int = (mpd_ssize_t)(dp-intpart); @@ -1262,8 +1262,8 @@ mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, return NULL; } - if (isupper((uchar)type)) { - type = (char)tolower((uchar)type); + if (isupper((unsigned char)type)) { + type = (char)tolower((unsigned char)type); flags |= MPD_FMT_UPPER; } if (spec->sign == ' ') { diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.c index eb5ee7a807b..5871d5c0f53 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.c @@ -61,13 +61,6 @@ mpd_callocfunc_em(size_t nmemb, size_t size) size_t req; mpd_size_t overflow; -#if MPD_SIZE_MAX < SIZE_MAX - /* full_coverage test only */ - if (nmemb > MPD_SIZE_MAX || size > MPD_SIZE_MAX) { - return NULL; - } -#endif - req = mul_size_t_overflow((mpd_size_t)nmemb, (mpd_size_t)size, &overflow); if (overflow) { diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h index 186808457b2..22650044218 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h @@ -39,12 +39,12 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) -int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); -int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); -int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); +int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t nwords, uint32_t *status); +int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status); +int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t nwords, uint32_t *status); -int mpd_switch_to_dyn_cxx(mpd_t *result, mpd_ssize_t size); -int mpd_realloc_dyn_cxx(mpd_t *result, mpd_ssize_t size); +int mpd_switch_to_dyn_cxx(mpd_t *result, mpd_ssize_t nwords); +int mpd_realloc_dyn_cxx(mpd_t *result, mpd_ssize_t nwords); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c index 28b639ccb40..f1626df46ed 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c @@ -64,7 +64,7 @@ #if defined(_MSC_VER) #define ALWAYS_INLINE __forceinline -#elif defined(__IBMC__) || defined(LEGACY_COMPILER) +#elif defined (__IBMC__) || defined(LEGACY_COMPILER) #define ALWAYS_INLINE #undef inline #define inline @@ -4843,7 +4843,7 @@ _mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status) { mpd_context_t varcontext, maxcontext; - mpd_t *z = (mpd_t *) result; + mpd_t *z = result; MPD_NEW_STATIC(v,0,0,0,0); MPD_NEW_STATIC(vtmp,0,0,0,0); MPD_NEW_STATIC(tmp,0,0,0,0); @@ -6368,7 +6368,7 @@ _mpd_qpow_int(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t workctx; MPD_NEW_STATIC(tbase,0,0,0,0); MPD_NEW_STATIC(texp,0,0,0,0); - mpd_ssize_t n; + mpd_uint_t n; mpd_workcontext(&workctx, ctx); @@ -8090,7 +8090,6 @@ mpd_sizeinbase(const mpd_t *a, uint32_t base) } digits = a->digits+a->exp; - assert(digits > 0); #ifdef CONFIG_64 /* ceil(2711437152599294 / log10(2)) + 4 == 2**53 */ @@ -8656,3 +8655,355 @@ mpd_qimport_u32(mpd_t *result, mpd_qresize(result, result->len, status); mpd_qfinalize(result, ctx, status); } + + +/******************************************************************************/ +/* From triple */ +/******************************************************************************/ + +#if defined(CONFIG_64) && defined(__SIZEOF_INT128__) +static mpd_ssize_t +_set_coeff(uint64_t data[3], uint64_t hi, uint64_t lo) +{ + __uint128_t d = ((__uint128_t)hi << 64) + lo; + __uint128_t q, r; + + q = d / MPD_RADIX; + r = d % MPD_RADIX; + data[0] = (uint64_t)r; + d = q; + + q = d / MPD_RADIX; + r = d % MPD_RADIX; + data[1] = (uint64_t)r; + d = q; + + q = d / MPD_RADIX; + r = d % MPD_RADIX; + data[2] = (uint64_t)r; + + if (q != 0) { + abort(); /* GCOV_NOT_REACHED */ + } + + return data[2] != 0 ? 3 : (data[1] != 0 ? 2 : 1); +} +#else +static size_t +_uint_from_u16(mpd_uint_t *w, mpd_ssize_t wlen, const uint16_t *u, size_t ulen) +{ + const mpd_uint_t ubase = 1U<<16; + mpd_ssize_t n = 0; + mpd_uint_t carry; + + assert(wlen > 0 && ulen > 0); + + w[n++] = u[--ulen]; + while (--ulen != SIZE_MAX) { + carry = _mpd_shortmul_c(w, w, n, ubase); + if (carry) { + if (n >= wlen) { + abort(); /* GCOV_NOT_REACHED */ + } + w[n++] = carry; + } + carry = _mpd_shortadd(w, n, u[ulen]); + if (carry) { + if (n >= wlen) { + abort(); /* GCOV_NOT_REACHED */ + } + w[n++] = carry; + } + } + + return n; +} + +static mpd_ssize_t +_set_coeff(mpd_uint_t *data, mpd_ssize_t len, uint64_t hi, uint64_t lo) +{ + uint16_t u16[8] = {0}; + + u16[7] = (uint16_t)((hi & 0xFFFF000000000000ULL) >> 48); + u16[6] = (uint16_t)((hi & 0x0000FFFF00000000ULL) >> 32); + u16[5] = (uint16_t)((hi & 0x00000000FFFF0000ULL) >> 16); + u16[4] = (uint16_t) (hi & 0x000000000000FFFFULL); + + u16[3] = (uint16_t)((lo & 0xFFFF000000000000ULL) >> 48); + u16[2] = (uint16_t)((lo & 0x0000FFFF00000000ULL) >> 32); + u16[1] = (uint16_t)((lo & 0x00000000FFFF0000ULL) >> 16); + u16[0] = (uint16_t) (lo & 0x000000000000FFFFULL); + + return (mpd_ssize_t)_uint_from_u16(data, len, u16, 8); +} +#endif + +static int +_set_uint128_coeff_exp(mpd_t *result, uint64_t hi, uint64_t lo, mpd_ssize_t exp) +{ + mpd_uint_t data[5] = {0}; + uint32_t status = 0; + mpd_ssize_t len; + +#if defined(CONFIG_64) && defined(__SIZEOF_INT128__) + len = _set_coeff(data, hi, lo); +#else + len = _set_coeff(data, 5, hi, lo); +#endif + + if (!mpd_qresize(result, len, &status)) { + return -1; + } + + for (mpd_ssize_t i = 0; i < len; i++) { + result->data[i] = data[i]; + } + + result->exp = exp; + result->len = len; + mpd_setdigits(result); + + return 0; +} + +int +mpd_from_uint128_triple(mpd_t *result, const mpd_uint128_triple_t *triple, uint32_t *status) +{ + static const mpd_context_t maxcontext = { + .prec=MPD_MAX_PREC, + .emax=MPD_MAX_EMAX, + .emin=MPD_MIN_EMIN, + .round=MPD_ROUND_HALF_EVEN, + .traps=MPD_Traps, + .status=0, + .newtrap=0, + .clamp=0, + .allcr=1, + }; + const enum mpd_triple_class tag = triple->tag; + const uint8_t sign = triple->sign; + const uint64_t hi = triple->hi; + const uint64_t lo = triple->lo; + mpd_ssize_t exp; + +#ifdef CONFIG_32 + if (triple->exp < MPD_SSIZE_MIN || triple->exp > MPD_SSIZE_MAX) { + goto conversion_error; + } +#endif + exp = (mpd_ssize_t)triple->exp; + + switch (tag) { + case MPD_TRIPLE_QNAN: case MPD_TRIPLE_SNAN: { + if (sign > 1 || exp != 0) { + goto conversion_error; + } + + const uint8_t flags = tag == MPD_TRIPLE_QNAN ? MPD_NAN : MPD_SNAN; + mpd_setspecial(result, sign, flags); + + if (hi == 0 && lo == 0) { /* no payload */ + return 0; + } + + if (_set_uint128_coeff_exp(result, hi, lo, exp) < 0) { + goto malloc_error; + } + + return 0; + } + + case MPD_TRIPLE_INF: { + if (sign > 1 || hi != 0 || lo != 0 || exp != 0) { + goto conversion_error; + } + + mpd_setspecial(result, sign, MPD_INF); + + return 0; + } + + case MPD_TRIPLE_NORMAL: { + if (sign > 1) { + goto conversion_error; + } + + const uint8_t flags = sign ? MPD_NEG : MPD_POS; + mpd_set_flags(result, flags); + + if (exp > MPD_EXP_INF) { + exp = MPD_EXP_INF; + } + if (exp == MPD_SSIZE_MIN) { + exp = MPD_SSIZE_MIN+1; + } + + if (_set_uint128_coeff_exp(result, hi, lo, exp) < 0) { + goto malloc_error; + } + + uint32_t workstatus = 0; + mpd_qfinalize(result, &maxcontext, &workstatus); + if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + goto conversion_error; + } + + return 0; + } + + default: + goto conversion_error; + } + +conversion_error: + mpd_seterror(result, MPD_Conversion_syntax, status); + return -1; + +malloc_error: + mpd_seterror(result, MPD_Malloc_error, status); + return -1; +} + + +/******************************************************************************/ +/* As triple */ +/******************************************************************************/ + +#if defined(CONFIG_64) && defined(__SIZEOF_INT128__) +static void +_get_coeff(uint64_t *hi, uint64_t *lo, const mpd_t *a) +{ + __uint128_t u128 = 0; + + switch (a->len) { + case 3: + u128 = a->data[2]; /* fall through */ + case 2: + u128 = u128 * MPD_RADIX + a->data[1]; /* fall through */ + case 1: + u128 = u128 * MPD_RADIX + a->data[0]; + break; + default: + abort(); /* GCOV_NOT_REACHED */ + } + + *hi = u128 >> 64; + *lo = (uint64_t)u128; +} +#else +static size_t +_uint_to_u16(uint16_t w[8], mpd_uint_t *u, mpd_ssize_t ulen) +{ + const mpd_uint_t wbase = 1U<<16; + size_t n = 0; + + assert(ulen > 0); + + do { + if (n >= 8) { + abort(); /* GCOV_NOT_REACHED */ + } + w[n++] = (uint16_t)_mpd_shortdiv(u, u, ulen, wbase); + /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */ + ulen = _mpd_real_size(u, ulen); + + } while (u[ulen-1] != 0); + + return n; +} + +static void +_get_coeff(uint64_t *hi, uint64_t *lo, const mpd_t *a) +{ + uint16_t u16[8] = {0}; + mpd_uint_t data[5] = {0}; + + switch (a->len) { + case 5: + data[4] = a->data[4]; /* fall through */ + case 4: + data[3] = a->data[3]; /* fall through */ + case 3: + data[2] = a->data[2]; /* fall through */ + case 2: + data[1] = a->data[1]; /* fall through */ + case 1: + data[0] = a->data[0]; + break; + default: + abort(); /* GCOV_NOT_REACHED */ + } + + _uint_to_u16(u16, data, a->len); + + *hi = (uint64_t)u16[7] << 48; + *hi |= (uint64_t)u16[6] << 32; + *hi |= (uint64_t)u16[5] << 16; + *hi |= (uint64_t)u16[4]; + + *lo = (uint64_t)u16[3] << 48; + *lo |= (uint64_t)u16[2] << 32; + *lo |= (uint64_t)u16[1] << 16; + *lo |= (uint64_t)u16[0]; +} +#endif + +static enum mpd_triple_class +_coeff_as_uint128(uint64_t *hi, uint64_t *lo, const mpd_t *a) +{ +#ifdef CONFIG_64 + static mpd_uint_t uint128_max_data[3] = { 3374607431768211455ULL, 4028236692093846346ULL, 3ULL }; + static const mpd_t uint128_max = { MPD_STATIC|MPD_CONST_DATA, 0, 39, 3, 3, uint128_max_data }; +#else + static mpd_uint_t uint128_max_data[5] = { 768211455U, 374607431U, 938463463U, 282366920U, 340U }; + static const mpd_t uint128_max = { MPD_STATIC|MPD_CONST_DATA, 0, 39, 5, 5, uint128_max_data }; +#endif + enum mpd_triple_class ret = MPD_TRIPLE_NORMAL; + uint32_t status = 0; + mpd_t coeff; + + *hi = *lo = 0ULL; + + if (mpd_isspecial(a)) { + if (mpd_isinfinite(a)) { + return MPD_TRIPLE_INF; + } + + ret = mpd_isqnan(a) ? MPD_TRIPLE_QNAN : MPD_TRIPLE_SNAN; + if (a->len == 0) { /* no payload */ + return ret; + } + } + else if (mpd_iszero(a)) { + return ret; + } + + _mpd_copy_shared(&coeff, a); + mpd_set_flags(&coeff, 0); + coeff.exp = 0; + + if (mpd_qcmp(&coeff, &uint128_max, &status) > 0) { + return MPD_TRIPLE_ERROR; + } + + _get_coeff(hi, lo, &coeff); + return ret; +} + +mpd_uint128_triple_t +mpd_as_uint128_triple(const mpd_t *a) +{ + mpd_uint128_triple_t triple = { MPD_TRIPLE_ERROR, 0, 0, 0, 0 }; + + triple.tag = _coeff_as_uint128(&triple.hi, &triple.lo, a); + if (triple.tag == MPD_TRIPLE_ERROR) { + return triple; + } + + triple.sign = !!mpd_isnegative(a); + if (triple.tag == MPD_TRIPLE_NORMAL) { + triple.exp = a->exp; + } + + return triple; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h index f66f6e59207..8a5aa26b7b6 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h @@ -40,6 +40,7 @@ #include #include #include + #define MPD_UINT8_C(x) (static_cast(x)) extern "C" { #else #include @@ -47,6 +48,7 @@ extern "C" { #include #include #include + #define MPD_UINT8_C(x) ((uint8_t)x) #endif @@ -62,7 +64,6 @@ extern "C" { #endif #if defined(_MSC_VER) - #include "vccompat.h" #define EXTINLINE extern inline #else #define EXTINLINE @@ -74,25 +75,15 @@ extern "C" { MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) -#if !defined(LEGACY_COMPILER) - #if !defined(UINT64_MAX) - /* The following #error is just a warning. If the compiler indeed does - * not have uint64_t, it is perfectly safe to comment out the #error. */ - #error "Warning: Compiler without uint64_t. Comment out this line." - #define LEGACY_COMPILER - #endif -#endif - - /******************************************************************************/ /* Version */ /******************************************************************************/ #define MPD_MAJOR_VERSION 2 #define MPD_MINOR_VERSION 5 -#define MPD_MICRO_VERSION 0 +#define MPD_MICRO_VERSION 1 -#define MPD_VERSION "2.5.0" +#define MPD_VERSION "2.5.1" #define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ (MPD_MINOR_VERSION << 16) | \ @@ -162,6 +153,7 @@ typedef int64_t mpd_ssize_t; #define MPD_EXP_INF 2000000000000000001LL #define MPD_EXP_CLAMP (-4000000000000000001LL) #define MPD_MAXIMPORT 105263157894736842L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */ +#define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ /* conversion specifiers */ #define PRI_mpd_uint_t PRIu64 @@ -203,9 +195,10 @@ typedef int32_t mpd_ssize_t; #define MPD_MAX_EMAX 425000000L /* ELIMIT-1 */ #define MPD_MIN_EMIN (-425000000L) /* -EMAX */ #define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1)) -#define MPD_EXP_INF 1000000001L /* allows for emax=999999999 in the tests */ -#define MPD_EXP_CLAMP (-2000000001L) /* allows for emin=-999999999 in the tests */ -#define MPD_MAXIMPORT 94444445L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */ +#define MPD_EXP_INF 1000000001L /* allows for emax=999999999 in the tests */ +#define MPD_EXP_CLAMP (-2000000001L) /* allows for emin=-999999999 in the tests */ +#define MPD_MAXIMPORT 94444445L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */ +#define MPD_IEEE_CONTEXT_MAX_BITS 256 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ /* conversion specifiers */ #define PRI_mpd_uint_t PRIu32 @@ -242,8 +235,8 @@ enum { enum { MPD_CLAMP_DEFAULT, MPD_CLAMP_IEEE_754, MPD_CLAMP_GUARD }; -extern const char *mpd_round_string[MPD_ROUND_GUARD]; -extern const char *mpd_clamp_string[MPD_CLAMP_GUARD]; +extern const char * const mpd_round_string[MPD_ROUND_GUARD]; +extern const char * const mpd_clamp_string[MPD_CLAMP_GUARD]; typedef struct mpd_context_t { @@ -300,7 +293,6 @@ typedef struct mpd_context_t { #define MPD_Insufficient_storage MPD_Malloc_error /* IEEE 754 interchange format contexts */ -#define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ #define MPD_DECIMAL32 32 #define MPD_DECIMAL64 64 #define MPD_DECIMAL128 128 @@ -345,16 +337,16 @@ void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags); /******************************************************************************/ /* mpd_t flags */ -#define MPD_POS ((uint8_t)0) -#define MPD_NEG ((uint8_t)1) -#define MPD_INF ((uint8_t)2) -#define MPD_NAN ((uint8_t)4) -#define MPD_SNAN ((uint8_t)8) +#define MPD_POS MPD_UINT8_C(0) +#define MPD_NEG MPD_UINT8_C(1) +#define MPD_INF MPD_UINT8_C(2) +#define MPD_NAN MPD_UINT8_C(4) +#define MPD_SNAN MPD_UINT8_C(8) #define MPD_SPECIAL (MPD_INF|MPD_NAN|MPD_SNAN) -#define MPD_STATIC ((uint8_t)16) -#define MPD_STATIC_DATA ((uint8_t)32) -#define MPD_SHARED_DATA ((uint8_t)64) -#define MPD_CONST_DATA ((uint8_t)128) +#define MPD_STATIC MPD_UINT8_C(16) +#define MPD_STATIC_DATA MPD_UINT8_C(32) +#define MPD_SHARED_DATA MPD_UINT8_C(64) +#define MPD_CONST_DATA MPD_UINT8_C(128) #define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA) /* mpd_t */ @@ -368,7 +360,29 @@ typedef struct mpd_t { } mpd_t; -typedef unsigned char uchar; +/******************************************************************************/ +/* Triple */ +/******************************************************************************/ + +/* status cases for getting a triple */ +enum mpd_triple_class { + MPD_TRIPLE_NORMAL, + MPD_TRIPLE_INF, + MPD_TRIPLE_QNAN, + MPD_TRIPLE_SNAN, + MPD_TRIPLE_ERROR, +}; + +typedef struct { + enum mpd_triple_class tag; + uint8_t sign; + uint64_t hi; + uint64_t lo; + int64_t exp; +} mpd_uint128_triple_t; + +int mpd_from_uint128_triple(mpd_t *result, const mpd_uint128_triple_t *triple, uint32_t *status); +mpd_uint128_triple_t mpd_as_uint128_triple(const mpd_t *a); /******************************************************************************/ @@ -417,7 +431,7 @@ void mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status); /* set to NaN with error flags */ void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status); /* set a special with sign and type */ -void mpd_setspecial(mpd_t *dec, uint8_t sign, uint8_t type); +void mpd_setspecial(mpd_t *result, uint8_t sign, uint8_t type); /* set coefficient to zero or all nines */ void mpd_zerocoeff(mpd_t *result); void mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status); @@ -810,16 +824,16 @@ void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size); mpd_t *mpd_qnew(void); mpd_t *mpd_new(mpd_context_t *ctx); -mpd_t *mpd_qnew_size(mpd_ssize_t size); +mpd_t *mpd_qnew_size(mpd_ssize_t nwords); EXTINLINE void mpd_del(mpd_t *dec); EXTINLINE void mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len); -EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t size, uint32_t *status); -EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); +EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status); +EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status); EXTINLINE void mpd_minalloc(mpd_t *result); -int mpd_resize(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx); -int mpd_resize_zero(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx); +int mpd_resize(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx); +int mpd_resize_zero(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpsignal.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpsignal.c new file mode 100644 index 00000000000..fc2af48f4f3 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpsignal.c @@ -0,0 +1,967 @@ +/* + * Copyright (c) 2008-2020 Stefan Krah. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. + */ + + +#include "mpdecimal.h" + +#include +#include + + +/* Signaling wrappers for the quiet functions in mpdecimal.c. */ + + +char * +mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx) +{ + char *ret; + uint32_t status = 0; + ret = mpd_qformat(dec, fmt, ctx, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} + +void +mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, + uint8_t srcsign, uint32_t base, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qimport_u16(result, srcdata, srclen, srcsign, base, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, + uint8_t srcsign, uint32_t base, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qimport_u32(result, srcdata, srclen, srcsign, base, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +size_t +mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, + mpd_context_t *ctx) +{ + size_t n; + uint32_t status = 0; + n = mpd_qexport_u16(rdata, rlen, base, src, &status); + mpd_addstatus_raise(ctx, status); + return n; +} + +size_t +mpd_export_u32(uint32_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, + mpd_context_t *ctx) +{ + size_t n; + uint32_t status = 0; + n = mpd_qexport_u32(rdata, rlen, base, src, &status); + mpd_addstatus_raise(ctx, status); + return n; +} + +void +mpd_finalize(mpd_t *result, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qfinalize(result, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +int +mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (mpd_qcheck_nan(result, a, ctx, &status)) { + mpd_addstatus_raise(ctx, status); + return 1; + } + return 0; +} + +int +mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (mpd_qcheck_nans(result, a, b, ctx, &status)) { + mpd_addstatus_raise(ctx, status); + return 1; + } + return 0; +} + +void +mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qset_string(result, s, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmaxcoeff(result, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +/* set static mpd from signed integer */ +void +mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsset_ssize(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsset_i32(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifdef CONFIG_64 +void +mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsset_i64(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +/* set static mpd from unsigned integer */ +void +mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsset_uint(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsset_u32(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifdef CONFIG_64 +void +mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsset_u64(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +/* set mpd from signed integer */ +void +mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qset_ssize(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qset_i32(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qset_i64(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +/* set mpd from unsigned integer */ +void +mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qset_uint(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qset_u32(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qset_u64(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +/* convert mpd to signed integer */ +mpd_ssize_t +mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_ssize_t ret; + + ret = mpd_qget_ssize(a, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} + +int32_t +mpd_get_i32(const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + int32_t ret; + + ret = mpd_qget_i32(a, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} + +#ifndef LEGACY_COMPILER +int64_t +mpd_get_i64(const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + int64_t ret; + + ret = mpd_qget_i64(a, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} +#endif + +mpd_uint_t +mpd_get_uint(const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_uint_t ret; + + ret = mpd_qget_uint(a, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} + +mpd_uint_t +mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_uint_t ret; + + ret = mpd_qabs_uint(a, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} + +uint32_t +mpd_get_u32(const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + uint32_t ret; + + ret = mpd_qget_u32(a, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} + +#ifndef LEGACY_COMPILER +uint64_t +mpd_get_u64(const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + uint64_t ret; + + ret = mpd_qget_u64(a, &status); + mpd_addstatus_raise(ctx, status); + return ret; +} +#endif + +void +mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qand(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (!mpd_qcopy(result, a, &status)) { + mpd_addstatus_raise(ctx, status); + } +} + +void +mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + mpd_copy(result, a, ctx); +} + +void +mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (!mpd_qcopy_abs(result, a, &status)) { + mpd_addstatus_raise(ctx, status); + } +} + +void +mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (!mpd_qcopy_negate(result, a, &status)) { + mpd_addstatus_raise(ctx, status); + } +} + +void +mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (!mpd_qcopy_sign(result, a, b, &status)) { + mpd_addstatus_raise(ctx, status); + } +} + +void +mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qinvert(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qlogb(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qor(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qrotate(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qscaleb(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qshiftl(result, a, n, &status); + mpd_addstatus_raise(ctx, status); +} + +mpd_uint_t +mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_uint_t rnd; + + rnd = mpd_qshiftr(result, a, n, &status); + mpd_addstatus_raise(ctx, status); + return rnd; +} + +void +mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qshiftn(result, a, n, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qshift(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qxor(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qabs(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +int +mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + int c; + c = mpd_qcmp(a, b, &status); + mpd_addstatus_raise(ctx, status); + return c; +} + +int +mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + int c; + c = mpd_qcompare(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); + return c; +} + +int +mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + int c; + c = mpd_qcompare_signal(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); + return c; +} + +void +mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qadd(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsub(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qadd_ssize(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qadd_i32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qadd_i64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qadd_uint(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qadd_u32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qadd_u64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsub_ssize(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsub_i32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsub_i64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsub_uint(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsub_u32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsub_u64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdiv(q, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdiv_ssize(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdiv_i32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdiv_i64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdiv_uint(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdiv_u32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdiv_u64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdivmod(q, r, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qdivint(q, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qexp(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, + mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qfma(result, a, b, c, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qln(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qlog10(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmax(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmax_mag(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmin(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmin_mag(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qminus(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmul(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmul_ssize(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmul_i32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmul_i64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmul_uint(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmul_u32(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +#ifndef LEGACY_COMPILER +void +mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qmul_u64(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} +#endif + +void +mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qnext_minus(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qnext_plus(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qnext_toward(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qplus(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qpow(result, base, exp, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, + mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qpowmod(result, base, exp, mod, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qquantize(result, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qrescale(result, a, exp, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qreduce(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qrem(r, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qrem_near(r, a, b, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qround_to_intx(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qround_to_int(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qtrunc(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qfloor(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qceil(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qsqrt(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} + +void +mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx) +{ + uint32_t status = 0; + mpd_qinvroot(result, a, ctx, &status); + mpd_addstatus_raise(ctx, status); +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h index 47961788d76..dd3776453d0 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h @@ -638,10 +638,10 @@ add_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow) static inline mpd_size_t mul_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow) { - mpd_uint_t lo; + mpd_uint_t hi, lo; - _mpd_mul_words((mpd_uint_t *)overflow, &lo, (mpd_uint_t)a, - (mpd_uint_t)b); + _mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b); + *overflow = (mpd_size_t)hi; return lo; } diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h deleted file mode 100644 index e2e1c42cc02..00000000000 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2008-2020 Stefan Krah. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "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. - */ - - -#ifndef LIBMPDEC_VCCOMPAT_H_ -#define LIBMPDEC_VCCOMPAT_H_ - - -/* Visual C fixes: no snprintf ... */ -#ifdef _MSC_VER - #ifndef __cplusplus - #undef inline - #define inline __inline - #endif - #undef random - #define random rand - #undef srandom - #define srandom srand - #undef snprintf - #define snprintf sprintf_s - #define HAVE_SNPRINTF - #undef strncasecmp - #define strncasecmp _strnicmp - #undef strcasecmp - #define strcasecmp _stricmp - #undef strtoll - #define strtoll _strtoi64 - #define strdup _strdup -#endif - - -#endif /* LIBMPDEC_VCCOMPAT_H_ */ diff --git a/contrib/tools/python3/src/Modules/_elementtree.c b/contrib/tools/python3/src/Modules/_elementtree.c index 8d1b56b35d2..8637bae0ae1 100644 --- a/contrib/tools/python3/src/Modules/_elementtree.c +++ b/contrib/tools/python3/src/Modules/_elementtree.c @@ -2037,7 +2037,7 @@ element_attrib_setter(ElementObject *self, PyObject *value, void *closure) if (!PyDict_Check(value)) { PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.200s", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return -1; } if (!self->extra) { diff --git a/contrib/tools/python3/src/Modules/_functoolsmodule.c b/contrib/tools/python3/src/Modules/_functoolsmodule.c index 42764a181d2..fa145216809 100644 --- a/contrib/tools/python3/src/Modules/_functoolsmodule.c +++ b/contrib/tools/python3/src/Modules/_functoolsmodule.c @@ -1,7 +1,9 @@ #include "Python.h" +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyObject_GC_TRACK #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tupleobject.h" +#include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef /* _functools module written and maintained @@ -11,6 +13,23 @@ All rights reserved. */ +typedef struct _functools_state { + /* this object is used delimit args and keywords in the cache keys */ + PyObject *kwd_mark; + PyTypeObject *partial_type; + PyTypeObject *keyobject_type; + PyTypeObject *lru_list_elem_type; +} _functools_state; + +static inline _functools_state * +get_functools_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (_functools_state *)state; +} + + /* partial object **********************************************************/ typedef struct { @@ -23,9 +42,20 @@ typedef struct { vectorcallfunc vectorcall; } partialobject; -static PyTypeObject partial_type; - static void partial_setvectorcall(partialobject *pto); +static struct PyModuleDef _functools_module; +static PyObject * +partial_call(partialobject *pto, PyObject *args, PyObject *kwargs); + +static inline _functools_state * +get_functools_state_by_type(PyTypeObject *type) +{ + PyObject *module = _PyType_GetModuleByDef(type, &_functools_module); + if (module == NULL) { + return NULL; + } + return get_functools_state(module); +} static PyObject * partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) @@ -41,7 +71,11 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) pargs = pkw = NULL; func = PyTuple_GET_ITEM(args, 0); - if (Py_IS_TYPE(func, &partial_type) && type == &partial_type) { + if (Py_TYPE(func)->tp_call == (ternaryfunc)partial_call) { + // The type of "func" might not be exactly the same type object + // as "type", but if it is called using partial_call, it must have the + // same memory layout (fn, args and kw members). + // We can use its underlying function directly and merge the arguments. partialobject *part = (partialobject *)func; if (part->dict == NULL) { pargs = part->args; @@ -113,18 +147,39 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) return (PyObject *)pto; } +static int +partial_clear(partialobject *pto) +{ + Py_CLEAR(pto->fn); + Py_CLEAR(pto->args); + Py_CLEAR(pto->kw); + Py_CLEAR(pto->dict); + return 0; +} + +static int +partial_traverse(partialobject *pto, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(pto)); + Py_VISIT(pto->fn); + Py_VISIT(pto->args); + Py_VISIT(pto->kw); + Py_VISIT(pto->dict); + return 0; +} + static void partial_dealloc(partialobject *pto) { + PyTypeObject *tp = Py_TYPE(pto); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(pto); - if (pto->weakreflist != NULL) + if (pto->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) pto); - Py_XDECREF(pto->fn); - Py_XDECREF(pto->args); - Py_XDECREF(pto->kw); - Py_XDECREF(pto->dict); - Py_TYPE(pto)->tp_free(pto); + } + (void)partial_clear(pto); + tp->tp_free(pto); + Py_DECREF(tp); } @@ -271,16 +326,6 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) return res; } -static int -partial_traverse(partialobject *pto, visitproc visit, void *arg) -{ - Py_VISIT(pto->fn); - Py_VISIT(pto->args); - Py_VISIT(pto->kw); - Py_VISIT(pto->dict); - return 0; -} - PyDoc_STRVAR(partial_doc, "partial(func, *args, **keywords) - new function with partial application\n\ of the given arguments and keywords.\n"); @@ -293,6 +338,12 @@ static PyMemberDef partial_memberlist[] = { "tuple of arguments to future partial calls"}, {"keywords", T_OBJECT, OFF(kw), READONLY, "dictionary of keyword arguments to future partial calls"}, + {"__weaklistoffset__", T_PYSSIZET, + offsetof(partialobject, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, + offsetof(partialobject, dict), READONLY}, + {"__vectorcalloffset__", T_PYSSIZET, + offsetof(partialobject, vectorcall), READONLY}, {NULL} /* Sentinel */ }; @@ -419,49 +470,30 @@ static PyMethodDef partial_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject partial_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "functools.partial", /* tp_name */ - sizeof(partialobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)partial_dealloc, /* tp_dealloc */ - offsetof(partialobject, vectorcall),/* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)partial_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)partial_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ - partial_doc, /* tp_doc */ - (traverseproc)partial_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(partialobject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - partial_methods, /* tp_methods */ - partial_memberlist, /* tp_members */ - partial_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(partialobject, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - partial_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot partial_type_slots[] = { + {Py_tp_dealloc, partial_dealloc}, + {Py_tp_repr, partial_repr}, + {Py_tp_call, partial_call}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_setattro, PyObject_GenericSetAttr}, + {Py_tp_doc, (void *)partial_doc}, + {Py_tp_traverse, partial_traverse}, + {Py_tp_clear, partial_clear}, + {Py_tp_methods, partial_methods}, + {Py_tp_members, partial_memberlist}, + {Py_tp_getset, partial_getsetlist}, + {Py_tp_new, partial_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec partial_type_spec = { + .name = "functools.partial", + .basicsize = sizeof(partialobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_IMMUTABLETYPE, + .slots = partial_type_slots }; @@ -473,29 +505,30 @@ typedef struct { PyObject *object; } keyobject; +static int +keyobject_clear(keyobject *ko) +{ + Py_CLEAR(ko->cmp); + Py_CLEAR(ko->object); + return 0; +} + static void keyobject_dealloc(keyobject *ko) { - Py_DECREF(ko->cmp); - Py_XDECREF(ko->object); - PyObject_FREE(ko); + PyTypeObject *tp = Py_TYPE(ko); + PyObject_GC_UnTrack(ko); + (void)keyobject_clear(ko); + tp->tp_free(ko); + Py_DECREF(tp); } static int keyobject_traverse(keyobject *ko, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(ko)); Py_VISIT(ko->cmp); - if (ko->object) - Py_VISIT(ko->object); - return 0; -} - -static int -keyobject_clear(keyobject *ko) -{ - Py_CLEAR(ko->cmp); - if (ko->object) - Py_CLEAR(ko->object); + Py_VISIT(ko->object); return 0; } @@ -512,38 +545,23 @@ keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds); static PyObject * keyobject_richcompare(PyObject *ko, PyObject *other, int op); -static PyTypeObject keyobject_type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "functools.KeyWrapper", /* tp_name */ - sizeof(keyobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)keyobject_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 */ - (ternaryfunc)keyobject_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)keyobject_traverse, /* tp_traverse */ - (inquiry)keyobject_clear, /* tp_clear */ - keyobject_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - keyobject_members, /* tp_members */ - 0, /* tp_getset */ +static PyType_Slot keyobject_type_slots[] = { + {Py_tp_dealloc, keyobject_dealloc}, + {Py_tp_call, keyobject_call}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, keyobject_traverse}, + {Py_tp_clear, keyobject_clear}, + {Py_tp_richcompare, keyobject_richcompare}, + {Py_tp_members, keyobject_members}, + {0, 0} +}; + +static PyType_Spec keyobject_type_spec = { + .name = "functools.KeyWrapper", + .basicsize = sizeof(keyobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = keyobject_type_slots }; static PyObject * @@ -555,13 +573,16 @@ keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds) if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:K", kwargs, &object)) return NULL; - result = PyObject_New(keyobject, &keyobject_type); - if (!result) + + result = PyObject_GC_New(keyobject, Py_TYPE(ko)); + if (result == NULL) { return NULL; + } Py_INCREF(ko->cmp); result->cmp = ko->cmp; Py_INCREF(object); result->object = object; + PyObject_GC_Track(result); return (PyObject *)result; } @@ -575,7 +596,7 @@ keyobject_richcompare(PyObject *ko, PyObject *other, int op) PyObject *answer; PyObject* stack[2]; - if (!Py_IS_TYPE(other, &keyobject_type)) { + if (!Py_IS_TYPE(other, Py_TYPE(ko))) { PyErr_Format(PyExc_TypeError, "other argument must be K instance"); return NULL; } @@ -598,7 +619,7 @@ keyobject_richcompare(PyObject *ko, PyObject *other, int op) return NULL; } - answer = PyObject_RichCompare(res, _PyLong_Zero, op); + answer = PyObject_RichCompare(res, _PyLong_GetZero(), op); Py_DECREF(res); return answer; } @@ -609,15 +630,19 @@ functools_cmp_to_key(PyObject *self, PyObject *args, PyObject *kwds) 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; - object = PyObject_New(keyobject, &keyobject_type); + + state = get_functools_state(self); + object = PyObject_GC_New(keyobject, state->keyobject_type); if (!object) return NULL; Py_INCREF(cmp); object->cmp = cmp; object->object = NULL; + PyObject_GC_Track(object); return (PyObject *)object; } @@ -686,7 +711,7 @@ functools_reduce(PyObject *self, PyObject *args) if (result == NULL) PyErr_SetString(PyExc_TypeError, - "reduce() of empty sequence with no initial value"); + "reduce() of empty iterable with no initial value"); Py_DECREF(it); return result; @@ -699,14 +724,14 @@ Fail: } PyDoc_STRVAR(functools_reduce_doc, -"reduce(function, sequence[, initial]) -> value\n\ +"reduce(function, iterable[, initial]) -> value\n\ \n\ -Apply a function of two arguments cumulatively to the items of a sequence,\n\ -from left to right, so as to reduce the sequence to a single value.\n\ -For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ +Apply a function of two arguments cumulatively to the items of a sequence\n\ +or iterable, from left to right, so as to reduce the iterable to a single\n\ +value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ ((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\ -of the sequence in the calculation, and serves as a default when the\n\ -sequence is empty."); +of the iterable in the calculation, and serves as a default when the\n\ +iterable is empty."); /* lru_cache object **********************************************************/ @@ -729,10 +754,6 @@ sequence is empty."); */ - -/* this object is used delimit args and keywords in the cache keys */ -static PyObject *kwd_mark = NULL; - struct lru_list_elem; struct lru_cache_object; @@ -746,33 +767,24 @@ typedef struct lru_list_elem { static void lru_list_elem_dealloc(lru_list_elem *link) { + PyTypeObject *tp = Py_TYPE(link); Py_XDECREF(link->key); Py_XDECREF(link->result); - PyObject_Del(link); + tp->tp_free(link); + Py_DECREF(tp); } -static PyTypeObject lru_list_elem_type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "functools._lru_list_elem", /* tp_name */ - sizeof(lru_list_elem), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)lru_list_elem_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, /* tp_flags */ +static PyType_Slot lru_list_elem_type_slots[] = { + {Py_tp_dealloc, lru_list_elem_dealloc}, + {0, 0} +}; + +static PyType_Spec lru_list_elem_type_spec = { + .name = "functools._lru_list_elem", + .basicsize = sizeof(lru_list_elem), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE, + .slots = lru_list_elem_type_slots }; @@ -787,15 +799,17 @@ typedef struct lru_cache_object { PyObject *func; Py_ssize_t maxsize; Py_ssize_t misses; + /* the kwd_mark is used delimit args and keywords in the cache keys */ + PyObject *kwd_mark; + PyTypeObject *lru_list_elem_type; PyObject *cache_info_type; PyObject *dict; PyObject *weakreflist; } lru_cache_object; -static PyTypeObject lru_cache_type; - static PyObject * -lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) +lru_cache_make_key(PyObject *kwd_mark, PyObject *args, + PyObject *kwds, int typed) { PyObject *key, *keyword, *value; Py_ssize_t key_size, pos, key_pos, kwds_size; @@ -879,7 +893,7 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd { PyObject *result; Py_hash_t hash; - PyObject *key = lru_cache_make_key(args, kwds, self->typed); + PyObject *key = lru_cache_make_key(self->kwd_mark, args, kwds, self->typed); if (!key) return NULL; hash = PyObject_Hash(key); @@ -980,7 +994,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds PyObject *key, *result, *testresult; Py_hash_t hash; - key = lru_cache_make_key(args, kwds, self->typed); + key = lru_cache_make_key(self->kwd_mark, args, kwds, self->typed); if (!key) return NULL; hash = PyObject_Hash(key); @@ -1035,7 +1049,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds { /* Cache is not full, so put the result in a new link */ link = (lru_list_elem *)PyObject_New(lru_list_elem, - &lru_list_elem_type); + self->lru_list_elem_type); if (link == NULL) { Py_DECREF(key); Py_DECREF(result); @@ -1146,6 +1160,7 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) lru_cache_object *obj; Py_ssize_t maxsize; PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *); + _functools_state *state; static char *keywords[] = {"user_function", "maxsize", "typed", "cache_info_type", NULL}; @@ -1161,6 +1176,11 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) return NULL; } + state = get_functools_state_by_type(type); + if (state == NULL) { + return NULL; + } + /* select the caching function, and make/inc maxsize_O */ if (maxsize_O == Py_None) { wrapper = infinite_lru_cache_wrapper; @@ -1200,6 +1220,10 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) obj->func = 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->dict = NULL; @@ -1229,22 +1253,33 @@ lru_cache_clear_list(lru_list_elem *link) } } +static int +lru_cache_tp_clear(lru_cache_object *self) +{ + lru_list_elem *list = lru_cache_unlink_list(self); + Py_CLEAR(self->cache); + Py_CLEAR(self->func); + Py_CLEAR(self->kwd_mark); + Py_CLEAR(self->lru_list_elem_type); + Py_CLEAR(self->cache_info_type); + Py_CLEAR(self->dict); + lru_cache_clear_list(list); + return 0; +} + static void lru_cache_dealloc(lru_cache_object *obj) { - lru_list_elem *list; + PyTypeObject *tp = Py_TYPE(obj); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(obj); - if (obj->weakreflist != NULL) + if (obj->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)obj); + } - list = lru_cache_unlink_list(obj); - Py_XDECREF(obj->cache); - Py_XDECREF(obj->func); - Py_XDECREF(obj->cache_info_type); - Py_XDECREF(obj->dict); - lru_cache_clear_list(list); - Py_TYPE(obj)->tp_free(obj); + (void)lru_cache_tp_clear(obj); + tp->tp_free(obj); + Py_DECREF(tp); } static PyObject * @@ -1309,32 +1344,24 @@ lru_cache_deepcopy(PyObject *self, PyObject *unused) static int lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); lru_list_elem *link = self->root.next; while (link != &self->root) { lru_list_elem *next = link->next; Py_VISIT(link->key); Py_VISIT(link->result); + Py_VISIT(Py_TYPE(link)); link = next; } - Py_VISIT(self->func); Py_VISIT(self->cache); + Py_VISIT(self->func); + Py_VISIT(self->kwd_mark); + Py_VISIT(self->lru_list_elem_type); Py_VISIT(self->cache_info_type); Py_VISIT(self->dict); return 0; } -static int -lru_cache_tp_clear(lru_cache_object *self) -{ - lru_list_elem *list = lru_cache_unlink_list(self); - Py_CLEAR(self->func); - Py_CLEAR(self->cache); - Py_CLEAR(self->cache_info_type); - Py_CLEAR(self->dict); - lru_cache_clear_list(list); - return 0; -} - PyDoc_STRVAR(lru_cache_doc, "Create a cached callable that wraps another function.\n\ @@ -1366,51 +1393,37 @@ static PyGetSetDef lru_cache_getsetlist[] = { {NULL} }; -static PyTypeObject lru_cache_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "functools._lru_cache_wrapper", /* tp_name */ - sizeof(lru_cache_object), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)lru_cache_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 */ - (ternaryfunc)lru_cache_call, /* 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 | Py_TPFLAGS_METHOD_DESCRIPTOR, - /* tp_flags */ - lru_cache_doc, /* tp_doc */ - (traverseproc)lru_cache_tp_traverse,/* tp_traverse */ - (inquiry)lru_cache_tp_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(lru_cache_object, weakreflist), - /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - lru_cache_methods, /* tp_methods */ - 0, /* tp_members */ - lru_cache_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - lru_cache_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(lru_cache_object, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - lru_cache_new, /* tp_new */ +static PyMemberDef lru_cache_memberlist[] = { + {"__dictoffset__", T_PYSSIZET, + offsetof(lru_cache_object, dict), READONLY}, + {"__weaklistoffset__", T_PYSSIZET, + offsetof(lru_cache_object, weakreflist), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot lru_cache_type_slots[] = { + {Py_tp_dealloc, lru_cache_dealloc}, + {Py_tp_call, lru_cache_call}, + {Py_tp_doc, (void *)lru_cache_doc}, + {Py_tp_traverse, lru_cache_tp_traverse}, + {Py_tp_clear, lru_cache_tp_clear}, + {Py_tp_methods, lru_cache_methods}, + {Py_tp_members, lru_cache_memberlist}, + {Py_tp_getset, lru_cache_getsetlist}, + {Py_tp_descr_get, lru_cache_descr_get}, + {Py_tp_new, lru_cache_new}, + {0, 0} }; +static PyType_Spec lru_cache_type_spec = { + .name = "functools._lru_cache_wrapper", + .basicsize = sizeof(lru_cache_object), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_IMMUTABLETYPE, + .slots = lru_cache_type_slots +}; + + /* module level code ********************************************************/ PyDoc_STRVAR(_functools_doc, @@ -1423,38 +1436,83 @@ static PyMethodDef _functools_methods[] = { {NULL, NULL} /* sentinel */ }; -static void -_functools_free(void *m) -{ - // FIXME: Do not clear kwd_mark to avoid NULL pointer dereferencing if we have - // other modules instances that could use it. Will fix when PEP-573 land - // and we could move kwd_mark to a per-module state. - // Py_CLEAR(kwd_mark); -} - static int _functools_exec(PyObject *module) { - PyTypeObject *typelist[] = { - &partial_type, - &lru_cache_type - }; - - if (!kwd_mark) { - kwd_mark = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); - if (!kwd_mark) { - return -1; - } + _functools_state *state = get_functools_state(module); + state->kwd_mark = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); + if (state->kwd_mark == NULL) { + return -1; } - for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { - if (PyModule_AddType(module, typelist[i]) < 0) { - return -1; - } + state->partial_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, + &partial_type_spec, NULL); + if (state->partial_type == NULL) { + return -1; } + if (PyModule_AddType(module, state->partial_type) < 0) { + return -1; + } + + PyObject *lru_cache_type = PyType_FromModuleAndSpec(module, + &lru_cache_type_spec, NULL); + if (lru_cache_type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)lru_cache_type) < 0) { + Py_DECREF(lru_cache_type); + return -1; + } + Py_DECREF(lru_cache_type); + + state->keyobject_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, + &keyobject_type_spec, NULL); + if (state->keyobject_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->keyobject_type) < 0) { + return -1; + } + + state->lru_list_elem_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &lru_list_elem_type_spec, NULL); + if (state->lru_list_elem_type == NULL) { + return -1; + } + // lru_list_elem is used only in _lru_cache_wrapper. + // So we don't expose it in module namespace. + + return 0; +} + +static int +_functools_traverse(PyObject *module, visitproc visit, void *arg) +{ + _functools_state *state = get_functools_state(module); + Py_VISIT(state->kwd_mark); + Py_VISIT(state->partial_type); + Py_VISIT(state->keyobject_type); + Py_VISIT(state->lru_list_elem_type); + return 0; +} + +static int +_functools_clear(PyObject *module) +{ + _functools_state *state = get_functools_state(module); + Py_CLEAR(state->kwd_mark); + Py_CLEAR(state->partial_type); + Py_CLEAR(state->keyobject_type); + Py_CLEAR(state->lru_list_elem_type); return 0; } +static void +_functools_free(void *module) +{ + _functools_clear((PyObject *)module); +} + static struct PyModuleDef_Slot _functools_slots[] = { {Py_mod_exec, _functools_exec}, {0, NULL} @@ -1462,14 +1520,14 @@ static struct PyModuleDef_Slot _functools_slots[] = { static struct PyModuleDef _functools_module = { PyModuleDef_HEAD_INIT, - "_functools", - _functools_doc, - 0, - _functools_methods, - _functools_slots, - NULL, - NULL, - _functools_free, + .m_name = "_functools", + .m_doc = _functools_doc, + .m_size = sizeof(_functools_state), + .m_methods = _functools_methods, + .m_slots = _functools_slots, + .m_traverse = _functools_traverse, + .m_clear = _functools_clear, + .m_free = _functools_free, }; PyMODINIT_FUNC diff --git a/contrib/tools/python3/src/Modules/_hashopenssl.c b/contrib/tools/python3/src/Modules/_hashopenssl.c index 4db058c0627..65538f63f7b 100644 --- a/contrib/tools/python3/src/Modules/_hashopenssl.c +++ b/contrib/tools/python3/src/Modules/_hashopenssl.c @@ -43,51 +43,12 @@ # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" #endif -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) -/* OpenSSL < 1.1.0 */ -#define EVP_MD_CTX_new EVP_MD_CTX_create -#define EVP_MD_CTX_free EVP_MD_CTX_destroy - -HMAC_CTX * -HMAC_CTX_new(void) -{ - HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); - if (ctx != NULL) { - memset(ctx, 0, sizeof(HMAC_CTX)); - HMAC_CTX_init(ctx); - } - return ctx; -} - -void -HMAC_CTX_free(HMAC_CTX *ctx) -{ - if (ctx != NULL) { - HMAC_CTX_cleanup(ctx); - OPENSSL_free(ctx); - } -} - -const EVP_MD * -HMAC_CTX_get_md(const HMAC_CTX *ctx) -{ - return ctx->md; -} -#endif - #define MUNCH_SIZE INT_MAX -#ifdef NID_sha3_224 +#define PY_OPENSSL_HAS_SCRYPT 1 #define PY_OPENSSL_HAS_SHA3 1 -#endif - -#if defined(EVP_MD_FLAG_XOF) && defined(NID_shake128) #define PY_OPENSSL_HAS_SHAKE 1 -#endif - -#if defined(NID_blake2b512) && !defined(OPENSSL_NO_BLAKE2) #define PY_OPENSSL_HAS_BLAKE2 1 -#endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L #define PY_EVP_MD EVP_MD @@ -159,27 +120,19 @@ static const py_hashentry_t py_hashes[] = { PY_HASH_ENTRY(Py_hash_sha384, "SHA384", SN_sha384, NID_sha384), PY_HASH_ENTRY(Py_hash_sha512, "SHA512", SN_sha512, NID_sha512), /* truncated sha2 */ -#ifdef NID_sha512_224 PY_HASH_ENTRY(Py_hash_sha512_224, "SHA512_224", SN_sha512_224, NID_sha512_224), PY_HASH_ENTRY(Py_hash_sha512_256, "SHA512_256", SN_sha512_256, NID_sha512_256), -#endif /* sha3 */ -#ifdef PY_OPENSSL_HAS_SHA3 PY_HASH_ENTRY(Py_hash_sha3_224, NULL, SN_sha3_224, NID_sha3_224), PY_HASH_ENTRY(Py_hash_sha3_256, NULL, SN_sha3_256, NID_sha3_256), PY_HASH_ENTRY(Py_hash_sha3_384, NULL, SN_sha3_384, NID_sha3_384), PY_HASH_ENTRY(Py_hash_sha3_512, NULL, SN_sha3_512, NID_sha3_512), -#endif /* sha3 shake */ -#ifdef PY_OPENSSL_HAS_SHAKE PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128), PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256), -#endif /* blake2 digest */ -#ifdef PY_OPENSSL_HAS_BLAKE2 PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256), PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512), -#endif PY_HASH_ENTRY(NULL, NULL, NULL, 0), }; @@ -259,6 +212,8 @@ typedef struct { #ifdef PY_OPENSSL_HAS_SHAKE PyTypeObject *EVPXOFtype; #endif + PyObject *constructs; + PyObject *unsupported_digestmod_error; _Py_hashtable_t *hashtable; } _hashlibstate; @@ -334,15 +289,6 @@ _setException(PyObject *exc, const char* altmsg, ...) } /* LCOV_EXCL_STOP */ -/* {Py_tp_new, NULL} doesn't block __new__ */ -static PyObject * -_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyErr_Format(PyExc_TypeError, - "cannot create '%.100s' instances", _PyType_Name(type)); - return NULL; -} - static PyObject* py_digest_name(const EVP_MD *md) { @@ -420,6 +366,48 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) return digest; } +/* Get digest EVP from object + * + * * string + * * _hashopenssl builtin function + * + * on error returns NULL with exception set. + */ +static PY_EVP_MD* +py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type py_ht) { + PY_EVP_MD* evp; + PyObject *name_obj = NULL; + const char *name; + + if (PyUnicode_Check(digestmod)) { + name_obj = digestmod; + } else { + _hashlibstate *state = get_hashlib_state(module); + // borrowed ref + name_obj = PyDict_GetItem(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); + return NULL; + } + + name = PyUnicode_AsUTF8(name_obj); + if (name == NULL) { + return NULL; + } + + evp = py_digest_by_name(module, name, py_ht); + if (evp == NULL) { + return NULL; + } + + return evp; +} + static EVPobject * newEVPobject(PyTypeObject *type) { @@ -469,7 +457,7 @@ EVP_dealloc(EVPobject *self) if (self->lock != NULL) PyThread_free_lock(self->lock); EVP_MD_CTX_free(self->ctx); - PyObject_Del(self); + PyObject_Free(self); Py_DECREF(tp); } @@ -702,7 +690,6 @@ static PyType_Slot EVPtype_slots[] = { {Py_tp_doc, (char *)hashtype_doc}, {Py_tp_methods, EVP_methods}, {Py_tp_getset, EVP_getseters}, - {Py_tp_new, _disabled_new}, {0, 0}, }; @@ -710,7 +697,7 @@ static PyType_Spec EVPtype_spec = { "_hashlib.HASH", /*tp_name*/ sizeof(EVPobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, EVPtype_slots }; @@ -852,7 +839,6 @@ static PyType_Slot EVPXOFtype_slots[] = { {Py_tp_doc, (char *)hashxoftype_doc}, {Py_tp_methods, EVPXOF_methods}, {Py_tp_getset, EVPXOF_getseters}, - {Py_tp_new, _disabled_new}, {0, 0}, }; @@ -860,7 +846,7 @@ static PyType_Spec EVPXOFtype_spec = { "_hashlib.HASHXOF", /*tp_name*/ sizeof(EVPobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, EVPXOFtype_slots }; @@ -887,12 +873,9 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, goto exit; } -#ifdef PY_OPENSSL_HAS_SHAKE if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) { type = get_hashlib_state(module)->EVPXOFtype; - } else -#endif - { + } else { type = get_hashlib_state(module)->EVPtype; } @@ -1238,7 +1221,6 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, PY_EVP_MD *digest = py_digest_by_name(module, hash_name, Py_ht_pbkdf2); if (digest == NULL) { - PyErr_SetString(PyExc_ValueError, "unsupported hash type"); goto end; } @@ -1311,8 +1293,7 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, return key_obj; } -#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) -#define PY_SCRYPT 1 +#ifdef PY_OPENSSL_HAS_SCRYPT /* XXX: Parameters salt, n, r and p should be required keyword-only parameters. They are optional in the Argument Clinic declaration only due to a @@ -1433,7 +1414,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, } return key_obj; } -#endif +#endif /* PY_OPENSSL_HAS_SCRYPT */ /* Fast HMAC for hmac.digest() */ @@ -1443,25 +1424,21 @@ _hashlib.hmac_digest as _hashlib_hmac_singleshot key: Py_buffer msg: Py_buffer - digest: str + digest: object Single-shot HMAC. [clinic start generated code]*/ static PyObject * _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, - Py_buffer *msg, const char *digest) -/*[clinic end generated code: output=15658ede5ab98185 input=019dffc571909a46]*/ + Py_buffer *msg, PyObject *digest) +/*[clinic end generated code: output=82f19965d12706ac input=0a0790cc3db45c2e]*/ { unsigned char md[EVP_MAX_MD_SIZE] = {0}; unsigned int md_len = 0; unsigned char *result; PY_EVP_MD *evp; - evp = py_digest_by_name(module, digest, Py_ht_mac); - if (evp == NULL) { - return NULL; - } if (key->len > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "key is too long."); @@ -1473,7 +1450,7 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, return NULL; } - evp = py_digest_by_name(module, digest, Py_ht_mac); + evp = py_digest_by_digestmod(module, digest, Py_ht_mac); if (evp == NULL) { return NULL; } @@ -1505,15 +1482,15 @@ _hashlib.hmac_new key: Py_buffer msg as msg_obj: object(c_default="NULL") = b'' - digestmod: str(c_default="NULL") = None + digestmod: object(c_default="NULL") = None Return a new hmac object. [clinic start generated code]*/ static PyObject * _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, - const char *digestmod) -/*[clinic end generated code: output=9a35673be0cbea1b input=a0878868eb190134]*/ + PyObject *digestmod) +/*[clinic end generated code: output=c20d9e4d9ed6d219 input=5f4071dcc7f34362]*/ { PyTypeObject *type = get_hashlib_state(module)->HMACtype; PY_EVP_MD *digest; @@ -1527,14 +1504,14 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, return NULL; } - if ((digestmod == NULL) || !strlen(digestmod)) { + if (digestmod == NULL) { PyErr_SetString( PyExc_TypeError, "Missing required parameter 'digestmod'."); return NULL; } - digest = py_digest_by_name(module, digestmod, Py_ht_mac); - if (!digest) { + digest = py_digest_by_digestmod(module, digestmod, Py_ht_mac); + if (digest == NULL) { return NULL; } @@ -1573,7 +1550,7 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, error: if (ctx) HMAC_CTX_free(ctx); - if (self) PyObject_Del(self); + if (self) PyObject_Free(self); return NULL; } @@ -1668,7 +1645,7 @@ _hmac_dealloc(HMACobject *self) PyThread_free_lock(self->lock); } HMAC_CTX_free(self->ctx); - PyObject_Del(self); + PyObject_Free(self); Py_DECREF(tp); } @@ -1839,14 +1816,13 @@ static PyType_Slot HMACtype_slots[] = { {Py_tp_dealloc,(destructor)_hmac_dealloc}, {Py_tp_methods, HMAC_methods}, {Py_tp_getset, HMAC_getset}, - {Py_tp_new, _disabled_new}, {0, NULL} }; PyType_Spec HMACtype_spec = { "_hashlib.HMAC", /* name */ sizeof(HMACobject), /* basicsize */ - .flags = Py_TPFLAGS_DEFAULT, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = HMACtype_slots, }; @@ -1860,21 +1836,15 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -_openssl_hash_name_mapper(EVP_MD *md, void *arg) -#else _openssl_hash_name_mapper(const EVP_MD *md, const char *from, const char *to, void *arg) -#endif { _InternalNameMapperState *state = (_InternalNameMapperState *)arg; PyObject *py_name; assert(state != NULL); - // ignore all undefined providers - if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) { + if (md == NULL) return; - } py_name = py_digest_name(md); if (py_name == NULL) { @@ -1900,12 +1870,7 @@ hashlib_md_meth_names(PyObject *module) return -1; } -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - // get algorithms from all activated providers in default context - EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state); -#else EVP_MD_do_all(&_openssl_hash_name_mapper, &state); -#endif if (state.error) { Py_DECREF(state.set); @@ -1920,12 +1885,6 @@ hashlib_md_meth_names(PyObject *module) return 0; } -/* LibreSSL doesn't support FIPS: - https://marc.info/?l=openbsd-misc&m=139819485423701&w=2 - - Ted Unangst wrote: "I figured I should mention our current libressl policy - wrt FIPS mode. It's gone and it's not coming back." */ -#ifndef LIBRESSL_VERSION_NUMBER /*[clinic input] _hashlib.get_fips_mode -> int @@ -1963,7 +1922,6 @@ _hashlib_get_fips_mode_impl(PyObject *module) return result; #endif } -#endif // !LIBRESSL_VERSION_NUMBER static int @@ -2117,6 +2075,8 @@ hashlib_traverse(PyObject *m, visitproc visit, void *arg) #ifdef PY_OPENSSL_HAS_SHAKE Py_VISIT(state->EVPXOFtype); #endif + Py_VISIT(state->constructs); + Py_VISIT(state->unsupported_digestmod_error); return 0; } @@ -2129,10 +2089,14 @@ hashlib_clear(PyObject *m) #ifdef PY_OPENSSL_HAS_SHAKE Py_CLEAR(state->EVPXOFtype); #endif + Py_CLEAR(state->constructs); + Py_CLEAR(state->unsupported_digestmod_error); + if (state->hashtable != NULL) { _Py_hashtable_destroy(state->hashtable); state->hashtable = NULL; } + return 0; } @@ -2143,17 +2107,6 @@ hashlib_free(void *m) } /* Py_mod_exec functions */ -static int -hashlib_openssl_legacy_init(PyObject *module) -{ -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - /* Load all digest algorithms and initialize cpuid */ - OPENSSL_add_all_algorithms_noconf(); - ERR_load_crypto_strings(); -#endif - return 0; -} - static int hashlib_init_hashtable(PyObject *module) { @@ -2187,21 +2140,14 @@ hashlib_init_evpxoftype(PyObject *module) { #ifdef PY_OPENSSL_HAS_SHAKE _hashlibstate *state = get_hashlib_state(module); - PyObject *bases; if (state->EVPtype == NULL) { return -1; } - bases = PyTuple_Pack(1, state->EVPtype); - if (bases == NULL) { - return -1; - } - state->EVPXOFtype = (PyTypeObject *)PyType_FromSpecWithBases( - &EVPXOFtype_spec, bases + &EVPXOFtype_spec, (PyObject *)state->EVPtype ); - Py_DECREF(bases); if (state->EVPXOFtype == NULL) { return -1; } @@ -2227,18 +2173,89 @@ hashlib_init_hmactype(PyObject *module) return 0; } -#if 0 +static int +hashlib_init_constructors(PyObject *module) +{ + /* Create dict from builtin openssl_hash functions to name + * {_hashlib.openssl_sha256: "sha256", ...} + */ + PyModuleDef *mdef; + PyMethodDef *fdef; + PyObject *proxy; + PyObject *func, *name_obj; + _hashlibstate *state = get_hashlib_state(module); + + mdef = PyModule_GetDef(module); + if (mdef == NULL) { + return -1; + } + + state->constructs = PyDict_New(); + if (state->constructs == NULL) { + return -1; + } + + for (fdef = mdef->m_methods; fdef->ml_name != NULL; fdef++) { + if (strncmp(fdef->ml_name, "openssl_", 8)) { + continue; + } + name_obj = PyUnicode_FromString(fdef->ml_name + 8); + if (name_obj == NULL) { + return -1; + } + func = PyObject_GetAttrString(module, fdef->ml_name); + if (func == NULL) { + Py_DECREF(name_obj); + return -1; + } + int rc = PyDict_SetItem(state->constructs, func, name_obj); + Py_DECREF(func); + Py_DECREF(name_obj); + if (rc < 0) { + return -1; + } + } + + proxy = PyDictProxy_New(state->constructs); + if (proxy == NULL) { + return -1; + } + + int rc = PyModule_AddObjectRef(module, "_constructors", proxy); + Py_DECREF(proxy); + if (rc < 0) { + return -1; + } + return 0; +} + +static int +hashlib_exception(PyObject *module) +{ + _hashlibstate *state = get_hashlib_state(module); + state->unsupported_digestmod_error = PyErr_NewException( + "_hashlib.UnsupportedDigestmodError", PyExc_ValueError, NULL); + if (state->unsupported_digestmod_error == NULL) { + return -1; + } + if (PyModule_AddObjectRef(module, "UnsupportedDigestmodError", + state->unsupported_digestmod_error) < 0) { + return -1; + } + return 0; +} + + static PyModuleDef_Slot hashlib_slots[] = { - /* OpenSSL 1.0.2 and LibreSSL */ - {Py_mod_exec, hashlib_openssl_legacy_init}, {Py_mod_exec, hashlib_init_hashtable}, {Py_mod_exec, hashlib_init_evptype}, {Py_mod_exec, hashlib_init_evpxoftype}, {Py_mod_exec, hashlib_init_hmactype}, {Py_mod_exec, hashlib_md_meth_names}, + {Py_mod_exec, hashlib_init_constructors}, + {Py_mod_exec, hashlib_exception}, {0, NULL} }; -#endif static struct PyModuleDef _hashlibmodule = { PyModuleDef_HEAD_INIT, @@ -2246,7 +2263,7 @@ static struct PyModuleDef _hashlibmodule = { .m_doc = "OpenSSL interface for hashlib module", .m_size = sizeof(_hashlibstate), .m_methods = EVP_functions, - .m_slots = NULL, + .m_slots = hashlib_slots, .m_traverse = hashlib_traverse, .m_clear = hashlib_clear, .m_free = hashlib_free @@ -2255,41 +2272,5 @@ static struct PyModuleDef _hashlibmodule = { PyMODINIT_FUNC PyInit__hashlib(void) { - PyObject *m = PyState_FindModule(&_hashlibmodule); - if (m != NULL) { - Py_INCREF(m); - return m; - } - - m = PyModule_Create(&_hashlibmodule); - if (m == NULL) { - return NULL; - } - - if (hashlib_openssl_legacy_init(m) < 0) { - Py_DECREF(m); - return NULL; - } - if (hashlib_init_hashtable(m) < 0) { - Py_DECREF(m); - return NULL; - } - if (hashlib_init_evptype(m) < 0) { - Py_DECREF(m); - return NULL; - } - if (hashlib_init_evpxoftype(m) < 0) { - Py_DECREF(m); - return NULL; - } - if (hashlib_init_hmactype(m) < 0) { - Py_DECREF(m); - return NULL; - } - if (hashlib_md_meth_names(m) == -1) { - Py_DECREF(m); - return NULL; - } - - return m; + return PyModuleDef_Init(&_hashlibmodule); } diff --git a/contrib/tools/python3/src/Modules/_heapqmodule.c b/contrib/tools/python3/src/Modules/_heapqmodule.c index 4e85e046d38..20468c28f24 100644 --- a/contrib/tools/python3/src/Modules/_heapqmodule.c +++ b/contrib/tools/python3/src/Modules/_heapqmodule.c @@ -7,9 +7,11 @@ annotated by François Pinard, and converted to C by Raymond Hettinger. */ #include "Python.h" +#include "pycore_list.h" // _PyList_ITEMS() #include "clinic/_heapqmodule.c.h" + /*[clinic input] module _heapq [clinic start generated code]*/ @@ -113,7 +115,7 @@ siftup(PyListObject *heap, Py_ssize_t pos) /*[clinic input] _heapq.heappush - heap: object + heap: object(subclass_of='&PyList_Type') item: object / @@ -122,13 +124,8 @@ Push item onto heap, maintaining the heap invariant. static PyObject * _heapq_heappush_impl(PyObject *module, PyObject *heap, PyObject *item) -/*[clinic end generated code: output=912c094f47663935 input=7913545cb5118842]*/ +/*[clinic end generated code: output=912c094f47663935 input=7c69611f3698aceb]*/ { - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - if (PyList_Append(heap, item)) return NULL; @@ -143,11 +140,6 @@ heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) PyObject *lastelt, *returnitem; Py_ssize_t n; - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - /* raises IndexError if the heap is empty */ n = PyList_GET_SIZE(heap); if (n == 0) { @@ -177,15 +169,15 @@ heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) /*[clinic input] _heapq.heappop - heap: object + heap: object(subclass_of='&PyList_Type') / Pop the smallest item off the heap, maintaining the heap invariant. [clinic start generated code]*/ static PyObject * -_heapq_heappop(PyObject *module, PyObject *heap) -/*[clinic end generated code: output=e1bbbc9866bce179 input=9bd36317b806033d]*/ +_heapq_heappop_impl(PyObject *module, PyObject *heap) +/*[clinic end generated code: output=96dfe82d37d9af76 input=91487987a583c856]*/ { return heappop_internal(heap, siftup); } @@ -195,11 +187,6 @@ heapreplace_internal(PyObject *heap, PyObject *item, int siftup_func(PyListObjec { PyObject *returnitem; - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - if (PyList_GET_SIZE(heap) == 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; @@ -219,7 +206,7 @@ heapreplace_internal(PyObject *heap, PyObject *item, int siftup_func(PyListObjec /*[clinic input] _heapq.heapreplace - heap: object + heap: object(subclass_of='&PyList_Type') item: object / @@ -236,7 +223,7 @@ this routine unless written as part of a conditional replacement: static PyObject * _heapq_heapreplace_impl(PyObject *module, PyObject *heap, PyObject *item) -/*[clinic end generated code: output=82ea55be8fbe24b4 input=e57ae8f4ecfc88e3]*/ +/*[clinic end generated code: output=82ea55be8fbe24b4 input=719202ac02ba10c8]*/ { return heapreplace_internal(heap, item, siftup); } @@ -244,7 +231,7 @@ _heapq_heapreplace_impl(PyObject *module, PyObject *heap, PyObject *item) /*[clinic input] _heapq.heappushpop - heap: object + heap: object(subclass_of='&PyList_Type') item: object / @@ -256,16 +243,11 @@ a separate call to heappop(). static PyObject * _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) -/*[clinic end generated code: output=67231dc98ed5774f input=eb48c90ba77b2214]*/ +/*[clinic end generated code: output=67231dc98ed5774f input=5dc701f1eb4a4aa7]*/ { PyObject *returnitem; int cmp; - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - if (PyList_GET_SIZE(heap) == 0) { Py_INCREF(item); return item; @@ -367,11 +349,6 @@ heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) { Py_ssize_t i, n; - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - /* For heaps likely to be bigger than L1 cache, we use the cache friendly heapify function. For smaller heaps that fit entirely in cache, we prefer the simpler algorithm with less branching. @@ -396,15 +373,15 @@ heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) /*[clinic input] _heapq.heapify - heap: object + heap: object(subclass_of='&PyList_Type') / Transform list into a heap, in-place, in O(len(heap)) time. [clinic start generated code]*/ static PyObject * -_heapq_heapify(PyObject *module, PyObject *heap) -/*[clinic end generated code: output=11483f23627c4616 input=872c87504b8de970]*/ +_heapq_heapify_impl(PyObject *module, PyObject *heap) +/*[clinic end generated code: output=e63a636fcf83d6d0 input=53bb7a2166febb73]*/ { return heapify_internal(heap, siftup); } @@ -508,15 +485,15 @@ siftup_max(PyListObject *heap, Py_ssize_t pos) /*[clinic input] _heapq._heappop_max - heap: object + heap: object(subclass_of='&PyList_Type') / Maxheap variant of heappop. [clinic start generated code]*/ static PyObject * -_heapq__heappop_max(PyObject *module, PyObject *heap) -/*[clinic end generated code: output=acd30acf6384b13c input=62ede3ba9117f541]*/ +_heapq__heappop_max_impl(PyObject *module, PyObject *heap) +/*[clinic end generated code: output=9e77aadd4e6a8760 input=362c06e1c7484793]*/ { return heappop_internal(heap, siftup_max); } @@ -524,7 +501,7 @@ _heapq__heappop_max(PyObject *module, PyObject *heap) /*[clinic input] _heapq._heapreplace_max - heap: object + heap: object(subclass_of='&PyList_Type') item: object / @@ -534,7 +511,7 @@ Maxheap variant of heapreplace. static PyObject * _heapq__heapreplace_max_impl(PyObject *module, PyObject *heap, PyObject *item) -/*[clinic end generated code: output=8ad7545e4a5e8adb input=6d8f25131e0f0e5f]*/ +/*[clinic end generated code: output=8ad7545e4a5e8adb input=f2dd27cbadb948d7]*/ { return heapreplace_internal(heap, item, siftup_max); } @@ -542,15 +519,15 @@ _heapq__heapreplace_max_impl(PyObject *module, PyObject *heap, /*[clinic input] _heapq._heapify_max - heap: object + heap: object(subclass_of='&PyList_Type') / Maxheap variant of heapify. [clinic start generated code]*/ static PyObject * -_heapq__heapify_max(PyObject *module, PyObject *heap) -/*[clinic end generated code: output=1c6bb6b60d6a2133 input=cdfcc6835b14110d]*/ +_heapq__heapify_max_impl(PyObject *module, PyObject *heap) +/*[clinic end generated code: output=2cb028beb4a8b65e input=c1f765ee69f124b8]*/ { return heapify_internal(heap, siftup_max); } diff --git a/contrib/tools/python3/src/Modules/_io/_iomodule.c b/contrib/tools/python3/src/Modules/_io/_iomodule.c index d7cadacea1b..170dea41e8a 100644 --- a/contrib/tools/python3/src/Modules/_io/_iomodule.c +++ b/contrib/tools/python3/src/Modules/_io/_iomodule.c @@ -10,6 +10,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "_iomodule.h" +#include "pycore_pystate.h" // _PyInterpreterState_GET() #ifdef HAVE_SYS_TYPES_H #include @@ -33,6 +34,7 @@ PyObject *_PyIO_str_fileno = NULL; PyObject *_PyIO_str_flush = NULL; PyObject *_PyIO_str_getstate = NULL; PyObject *_PyIO_str_isatty = NULL; +PyObject *_PyIO_str_locale = NULL; PyObject *_PyIO_str_newlines = NULL; PyObject *_PyIO_str_nl = NULL; PyObject *_PyIO_str_peek = NULL; @@ -504,6 +506,45 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, return NULL; } + +/*[clinic input] +_io.text_encoding + encoding: object + stacklevel: int = 2 + / + +A helper function to choose the text encoding. + +When encoding is not None, just return it. +Otherwise, return the default text encoding (i.e. "locale"). + +This function emits an EncodingWarning if encoding is None and +sys.flags.warn_default_encoding is true. + +This can be used in APIs with an encoding=None parameter. +However, please consider using encoding="utf-8" for new APIs. +[clinic start generated code]*/ + +static PyObject * +_io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel) +/*[clinic end generated code: output=91b2cfea6934cc0c input=bf70231213e2a7b4]*/ +{ + if (encoding == NULL || encoding == Py_None) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_PyInterpreterState_GetConfig(interp)->warn_default_encoding) { + if (PyErr_WarnEx(PyExc_EncodingWarning, + "'encoding' argument not specified", stacklevel)) { + return NULL; + } + } + Py_INCREF(_PyIO_str_locale); + return _PyIO_str_locale; + } + Py_INCREF(encoding); + return encoding; +} + + /*[clinic input] _io.open_code @@ -532,7 +573,7 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err) { Py_off_t result; PyObject *runerr; - PyObject *value = PyNumber_Index(item); + PyObject *value = _PyNumber_Index(item); if (value == NULL) return -1; @@ -593,39 +634,12 @@ _PyIO_get_module_state(void) return state; } -PyObject * -_PyIO_get_locale_module(_PyIO_State *state) -{ - PyObject *mod; - if (state->locale_module != NULL) { - assert(PyWeakref_CheckRef(state->locale_module)); - mod = PyWeakref_GET_OBJECT(state->locale_module); - if (mod != Py_None) { - Py_INCREF(mod); - return mod; - } - Py_CLEAR(state->locale_module); - } - mod = PyImport_ImportModule("_bootlocale"); - if (mod == NULL) - return NULL; - state->locale_module = PyWeakref_NewRef(mod, NULL); - if (state->locale_module == NULL) { - Py_DECREF(mod); - return NULL; - } - return mod; -} - - static int iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = get_io_state(mod); if (!state->initialized) return 0; - if (state->locale_module != NULL) { - Py_VISIT(state->locale_module); - } + Py_VISIT(state->locale_module); Py_VISIT(state->unsupported_operation); return 0; } @@ -656,6 +670,7 @@ iomodule_free(PyObject *mod) { static PyMethodDef module_methods[] = { _IO_OPEN_METHODDEF + _IO_TEXT_ENCODING_METHODDEF _IO_OPEN_CODE_METHODDEF {NULL, NULL} }; @@ -774,6 +789,7 @@ PyInit__io(void) ADD_INTERNED(flush) ADD_INTERNED(getstate) ADD_INTERNED(isatty) + ADD_INTERNED(locale) ADD_INTERNED(newlines) ADD_INTERNED(peek) ADD_INTERNED(read) diff --git a/contrib/tools/python3/src/Modules/_io/_iomodule.h b/contrib/tools/python3/src/Modules/_io/_iomodule.h index a8f3951e57f..638797fd357 100644 --- a/contrib/tools/python3/src/Modules/_io/_iomodule.h +++ b/contrib/tools/python3/src/Modules/_io/_iomodule.h @@ -150,7 +150,6 @@ typedef struct { #define IO_STATE() _PyIO_get_module_state() extern _PyIO_State *_PyIO_get_module_state(void); -extern PyObject *_PyIO_get_locale_module(_PyIO_State *); #ifdef MS_WINDOWS extern char _PyIO_get_console_type(PyObject *); diff --git a/contrib/tools/python3/src/Modules/_io/bufferedio.c b/contrib/tools/python3/src/Modules/_io/bufferedio.c index b0fe9e45891..ba966f568b3 100644 --- a/contrib/tools/python3/src/Modules/_io/bufferedio.c +++ b/contrib/tools/python3/src/Modules/_io/bufferedio.c @@ -1485,6 +1485,15 @@ _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len) } n = PyNumber_AsSsize_t(res, PyExc_ValueError); Py_DECREF(res); + + if (n == -1 && PyErr_Occurred()) { + _PyErr_FormatFromCause( + PyExc_OSError, + "raw readinto() failed" + ); + return -1; + } + if (n < 0 || n > len) { PyErr_Format(PyExc_OSError, "raw readinto() returned invalid length %zd " diff --git a/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h b/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h index 1a9651d3408..91c55b1816c 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h @@ -178,11 +178,6 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } buffering = _PyLong_AsInt(args[2]); if (buffering == -1 && PyErr_Occurred()) { goto exit; @@ -261,11 +256,6 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } if (args[6]) { - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } closefd = _PyLong_AsInt(args[6]); if (closefd == -1 && PyErr_Occurred()) { goto exit; @@ -282,6 +272,52 @@ exit: return return_value; } +PyDoc_STRVAR(_io_text_encoding__doc__, +"text_encoding($module, encoding, stacklevel=2, /)\n" +"--\n" +"\n" +"A helper function to choose the text encoding.\n" +"\n" +"When encoding is not None, just return it.\n" +"Otherwise, return the default text encoding (i.e. \"locale\").\n" +"\n" +"This function emits an EncodingWarning if encoding is None and\n" +"sys.flags.warn_default_encoding is true.\n" +"\n" +"This can be used in APIs with an encoding=None parameter.\n" +"However, please consider using encoding=\"utf-8\" for new APIs."); + +#define _IO_TEXT_ENCODING_METHODDEF \ + {"text_encoding", (PyCFunction)(void(*)(void))_io_text_encoding, METH_FASTCALL, _io_text_encoding__doc__}, + +static PyObject * +_io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel); + +static PyObject * +_io_text_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *encoding; + int stacklevel = 2; + + if (!_PyArg_CheckPositional("text_encoding", nargs, 1, 2)) { + goto exit; + } + encoding = args[0]; + if (nargs < 2) { + goto skip_optional; + } + stacklevel = _PyLong_AsInt(args[1]); + if (stacklevel == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _io_text_encoding_impl(module, encoding, stacklevel); + +exit: + return return_value; +} + PyDoc_STRVAR(_io_open_code__doc__, "open_code($module, /, path)\n" "--\n" @@ -323,4 +359,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=3df6bc6d91697545 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=06e055d1d80b835d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h index 56d6332a250..19543fdf79d 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h @@ -120,14 +120,9 @@ _io__Buffered_peek(buffered *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -200,14 +195,9 @@ _io__Buffered_read1(buffered *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -356,11 +346,6 @@ _io__Buffered_seek(buffered *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } whence = _PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; @@ -434,14 +419,9 @@ _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(fastargs[1]); + PyObject *iobj = _PyNumber_Index(fastargs[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -493,14 +473,9 @@ _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(fastargs[1]); + PyObject *iobj = _PyNumber_Index(fastargs[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -590,14 +565,9 @@ _io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs) if (PyTuple_GET_SIZE(args) < 3) { goto skip_optional; } - if (PyFloat_Check(PyTuple_GET_ITEM(args, 2))) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(PyTuple_GET_ITEM(args, 2)); + PyObject *iobj = _PyNumber_Index(PyTuple_GET_ITEM(args, 2)); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -649,14 +619,9 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(fastargs[1]); + PyObject *iobj = _PyNumber_Index(fastargs[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -672,4 +637,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=7d9ad40c95bdd808 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=98ccf7610c0e82ba input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h index 83cd490dc59..5ea80ae01c1 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h @@ -402,14 +402,9 @@ _io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -422,11 +417,6 @@ _io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } whence = _PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; @@ -515,4 +505,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=4ec2506def9c8eb9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=49a32140eb8c5555 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h index 53e7067cf7a..9b237c156d3 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h @@ -87,11 +87,6 @@ _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - if (PyFloat_Check(fastargs[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } closefd = _PyLong_AsInt(fastargs[2]); if (closefd == -1 && PyErr_Occurred()) { goto exit; @@ -351,11 +346,6 @@ _io_FileIO_seek(fileio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } whence = _PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; @@ -447,4 +437,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=e7682d0a3264d284 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3479912ec0f7e029 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h b/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h index ddaff7b5d13..4fd6e18c4ef 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h @@ -274,14 +274,9 @@ _io__RawIOBase_read(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -315,4 +310,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=61b6ea7153ef9940 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=83c1361a7a51ca84 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h index 77a720c2a6f..147ef668a0b 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h @@ -177,14 +177,9 @@ _io_StringIO_seek(stringio *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -197,11 +192,6 @@ _io_StringIO_seek(stringio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } whence = _PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; @@ -348,4 +338,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { return _io_StringIO_seekable_impl(self); } -/*[clinic end generated code: output=7aad5ab2e64a25b8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eea93dcab10d0a97 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h index b8b507543ea..0b047ac0aab 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h @@ -39,11 +39,6 @@ _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject goto exit; } decoder = fastargs[0]; - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } translate = _PyLong_AsInt(fastargs[1]); if (translate == -1 && PyErr_Occurred()) { goto exit; @@ -90,11 +85,6 @@ _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *ar if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[1]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -266,11 +256,6 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[4]) { - if (PyFloat_Check(fastargs[4])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } line_buffering = _PyLong_AsInt(fastargs[4]); if (line_buffering == -1 && PyErr_Occurred()) { goto exit; @@ -279,11 +264,6 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } } - if (PyFloat_Check(fastargs[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } write_through = _PyLong_AsInt(fastargs[5]); if (write_through == -1 && PyErr_Occurred()) { goto exit; @@ -470,14 +450,9 @@ _io_TextIOWrapper_readline(textio *self, PyObject *const *args, Py_ssize_t nargs if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -519,11 +494,6 @@ _io_TextIOWrapper_seek(textio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } whence = _PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; @@ -701,4 +671,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=b1bae4f4cdf6019e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2604c8f3a45b9a03 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h index 3e501a58537..84e73dcaf70 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h @@ -8,10 +8,10 @@ PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, "close($self, /)\n" "--\n" "\n" -"Close the handle.\n" +"Close the console object.\n" "\n" -"A closed handle cannot be used for further I/O operations. close() may be\n" -"called more than once without error."); +"A closed console object cannot be used for further I/O operations.\n" +"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__}, @@ -86,11 +86,6 @@ _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - if (PyFloat_Check(fastargs[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } closefd = _PyLong_AsInt(fastargs[2]); if (closefd == -1 && PyErr_Occurred()) { goto exit; @@ -115,10 +110,7 @@ PyDoc_STRVAR(_io__WindowsConsoleIO_fileno__doc__, "fileno($self, /)\n" "--\n" "\n" -"Return the underlying file descriptor (an integer).\n" -"\n" -"fileno is only set when a file descriptor is used to open\n" -"one of the standard streams."); +"Return the underlying file descriptor (an integer)."); #define _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF \ {"fileno", (PyCFunction)_io__WindowsConsoleIO_fileno, METH_NOARGS, _io__WindowsConsoleIO_fileno__doc__}, @@ -386,4 +378,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=f5b8860a658a001a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48080572ffee22f5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/fileio.c b/contrib/tools/python3/src/Modules/_io/fileio.c index 048484bde54..b9856b3b631 100644 --- a/contrib/tools/python3/src/Modules/_io/fileio.c +++ b/contrib/tools/python3/src/Modules/_io/fileio.c @@ -255,12 +255,6 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, self->fd = -1; } - if (PyFloat_Check(nameobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; - } - fd = _PyLong_AsInt(nameobj); if (fd < 0) { if (!PyErr_Occurred()) { @@ -276,10 +270,14 @@ _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 @@ -500,6 +498,11 @@ _Py_COMP_DIAG_POP internal_close(self); done: +#ifdef MS_WINDOWS +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(widename); +#endif /* USE_UNICODE_WCHAR_CACHE */ +#endif Py_CLEAR(stringobj); return ret; } @@ -898,10 +901,6 @@ portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_er pos = 0; } else { - if(PyFloat_Check(posobj)) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return NULL; - } #if defined(HAVE_LARGEFILE_SUPPORT) pos = PyLong_AsLongLong(posobj); #else diff --git a/contrib/tools/python3/src/Modules/_io/iobase.c b/contrib/tools/python3/src/Modules/_io/iobase.c index 0f150a3583d..4c81befebd7 100644 --- a/contrib/tools/python3/src/Modules/_io/iobase.c +++ b/contrib/tools/python3/src/Modules/_io/iobase.c @@ -10,6 +10,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_long.h" // _PyLong_GetOne() #include "pycore_object.h" #include // offsetof() #include "_iomodule.h" @@ -348,8 +349,9 @@ iobase_dealloc(iobase *self) if (_PyIOBase_finalize((PyObject *) self) < 0) { /* When called from a heap type's dealloc, the type will be decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ - if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) + if (_PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) { Py_INCREF(Py_TYPE(self)); + } return; } _PyObject_GC_UNTRACK(self); @@ -554,7 +556,7 @@ _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) PyObject *b; if (peek != NULL) { - PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_One); + PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_GetOne()); if (readahead == NULL) { /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR occurs so we needn't do it ourselves. */ diff --git a/contrib/tools/python3/src/Modules/_io/textio.c b/contrib/tools/python3/src/Modules/_io/textio.c index f9903e25000..e28dbaa7b7e 100644 --- a/contrib/tools/python3/src/Modules/_io/textio.c +++ b/contrib/tools/python3/src/Modules/_io/textio.c @@ -9,6 +9,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "pycore_interp.h" // PyInterpreterState.fs_codec +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_fileutils.h" // _Py_GetLocaleEncoding() #include "pycore_object.h" #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" // PyMemberDef @@ -26,7 +28,6 @@ _Py_IDENTIFIER(_dealloc_warn); _Py_IDENTIFIER(decode); _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(flush); -_Py_IDENTIFIER(getpreferredencoding); _Py_IDENTIFIER(isatty); _Py_IDENTIFIER(mode); _Py_IDENTIFIER(name); @@ -971,7 +972,7 @@ _textiowrapper_fix_encoder_state(textio *self) return -1; } - int cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); + int cmp = PyObject_RichCompareBool(cookieObj, _PyLong_GetZero(), Py_EQ); Py_DECREF(cookieObj); if (cmp < 0) { return -1; @@ -980,7 +981,7 @@ _textiowrapper_fix_encoder_state(textio *self) if (cmp == 0) { self->encoding_start_of_stream = 0; PyObject *res = PyObject_CallMethodOneArg( - self->encoder, _PyIO_str_setstate, _PyLong_Zero); + self->encoder, _PyIO_str_setstate, _PyLong_GetZero()); if (res == NULL) { return -1; } @@ -1084,6 +1085,19 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, self->ok = 0; self->detached = 0; + if (encoding == NULL) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_PyInterpreterState_GetConfig(interp)->warn_default_encoding) { + if (PyErr_WarnEx(PyExc_EncodingWarning, + "'encoding' argument not specified", 1)) { + return -1; + } + } + } + else if (strcmp(encoding, "locale") == 0) { + encoding = NULL; + } + if (errors == Py_None) { errors = _PyUnicode_FromId(&PyId_strict); /* borrowed */ if (errors == NULL) { @@ -1154,29 +1168,11 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, } } if (encoding == NULL && self->encoding == NULL) { - PyObject *locale_module = _PyIO_get_locale_module(state); - if (locale_module == NULL) - goto catch_ImportError; - self->encoding = _PyObject_CallMethodIdOneArg( - locale_module, &PyId_getpreferredencoding, Py_False); - Py_DECREF(locale_module); + self->encoding = _Py_GetLocaleEncodingObject(); if (self->encoding == NULL) { - catch_ImportError: - /* - Importing locale can raise an ImportError because of - _functools, and locale.getpreferredencoding can raise an - ImportError if _locale is not available. These will happen - during module building. - */ - if (PyErr_ExceptionMatches(PyExc_ImportError)) { - PyErr_Clear(); - self->encoding = PyUnicode_FromString("ascii"); - } - else - goto error; + goto error; } - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); + assert(PyUnicode_Check(self->encoding)); } if (self->encoding != NULL) { encoding = PyUnicode_AsUTF8(self->encoding); @@ -2429,7 +2425,7 @@ _textiowrapper_encoder_reset(textio *self, int start_of_stream) } else { res = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_setstate, - _PyLong_Zero); + _PyLong_GetZero()); self->encoding_start_of_stream = 0; } if (res == NULL) @@ -2473,10 +2469,12 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } + PyObject *zero = _PyLong_GetZero(); // borrowed reference + switch (whence) { case SEEK_CUR: /* seek relative to current position */ - cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); + cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ); if (cmp < 0) goto fail; @@ -2496,7 +2494,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) case SEEK_END: /* seek relative to end of file */ - cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); + cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ); if (cmp < 0) goto fail; @@ -2525,7 +2523,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; if (self->encoder) { /* If seek() == 0, we are at the start of stream, otherwise not */ - cmp = PyObject_RichCompareBool(res, _PyLong_Zero, Py_EQ); + cmp = PyObject_RichCompareBool(res, zero, Py_EQ); if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) { Py_DECREF(res); goto fail; @@ -2543,7 +2541,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_LT); + cmp = PyObject_RichCompareBool(cookieObj, zero, Py_LT); if (cmp < 0) goto fail; diff --git a/contrib/tools/python3/src/Modules/_io/winconsoleio.c b/contrib/tools/python3/src/Modules/_io/winconsoleio.c index a83ef37a1fc..460f2d3fa07 100644 --- a/contrib/tools/python3/src/Modules/_io/winconsoleio.c +++ b/contrib/tools/python3/src/Modules/_io/winconsoleio.c @@ -64,10 +64,7 @@ char _PyIO_get_console_type(PyObject *path_or_fd) { int fd = PyLong_AsLong(path_or_fd); PyErr_Clear(); if (fd >= 0) { - HANDLE handle; - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH + HANDLE handle = _Py_get_osfhandle_noraise(fd); if (handle == INVALID_HANDLE_VALUE) return '\0'; return _get_console_type(handle); @@ -143,12 +140,11 @@ class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type" typedef struct { PyObject_HEAD - HANDLE handle; int fd; unsigned int created : 1; unsigned int readable : 1; unsigned int writable : 1; - unsigned int closehandle : 1; + unsigned int closefd : 1; char finalizing; unsigned int blksize; PyObject *weakreflist; @@ -164,7 +160,7 @@ _Py_IDENTIFIER(name); int _PyWindowsConsoleIO_closed(PyObject *self) { - return ((winconsoleio *)self)->handle == INVALID_HANDLE_VALUE; + return ((winconsoleio *)self)->fd == -1; } @@ -172,16 +168,12 @@ _PyWindowsConsoleIO_closed(PyObject *self) static int internal_close(winconsoleio *self) { - if (self->handle != INVALID_HANDLE_VALUE) { - if (self->closehandle) { - if (self->fd >= 0) { - _Py_BEGIN_SUPPRESS_IPH - close(self->fd); - _Py_END_SUPPRESS_IPH - } - CloseHandle(self->handle); + if (self->fd != -1) { + if (self->closefd) { + _Py_BEGIN_SUPPRESS_IPH + close(self->fd); + _Py_END_SUPPRESS_IPH } - self->handle = INVALID_HANDLE_VALUE; self->fd = -1; } return 0; @@ -190,15 +182,15 @@ internal_close(winconsoleio *self) /*[clinic input] _io._WindowsConsoleIO.close -Close the handle. +Close the console object. -A closed handle cannot be used for further I/O operations. close() may be -called more than once without error. +A closed console object cannot be used for further I/O operations. +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=185617e349ae4c7b]*/ +/*[clinic end generated code: output=27ef95b66c29057b input=68c4e5754f8136c2]*/ { PyObject *res; PyObject *exc, *val, *tb; @@ -206,8 +198,8 @@ _io__WindowsConsoleIO_close_impl(winconsoleio *self) _Py_IDENTIFIER(close); res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type, &PyId_close, (PyObject*)self); - if (!self->closehandle) { - self->handle = INVALID_HANDLE_VALUE; + if (!self->closefd) { + self->fd = -1; return res; } if (res == NULL) @@ -229,12 +221,11 @@ winconsoleio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self = (winconsoleio *) type->tp_alloc(type, 0); if (self != NULL) { - self->handle = INVALID_HANDLE_VALUE; self->fd = -1; self->created = 0; self->readable = 0; self->writable = 0; - self->closehandle = 0; + self->closefd = 0; self->blksize = 0; self->weakreflist = NULL; } @@ -269,22 +260,17 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, int rwa = 0; int fd = -1; int fd_is_own = 0; + HANDLE handle = NULL; assert(PyWindowsConsoleIO_Check(self)); - if (self->handle >= 0) { - if (self->closehandle) { + if (self->fd >= 0) { + if (self->closefd) { /* Have to close the existing file first. */ if (internal_close(self) < 0) return -1; } else - self->handle = INVALID_HANDLE_VALUE; - } - - if (PyFloat_Check(nameobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; + self->fd = -1; } fd = _PyLong_AsInt(nameobj); @@ -347,14 +333,12 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, goto bad_mode; if (fd >= 0) { - _Py_BEGIN_SUPPRESS_IPH - self->handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH - self->closehandle = 0; + handle = _Py_get_osfhandle_noraise(fd); + self->closefd = 0; } else { DWORD access = GENERIC_READ; - self->closehandle = 1; + self->closefd = 1; if (!closefd) { PyErr_SetString(PyExc_ValueError, "Cannot use closefd=False with file name"); @@ -369,21 +353,31 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, on the specific access. This is required for modern names CONIN$ and CONOUT$, which allow reading/writing state as well as reading/writing content. */ - self->handle = CreateFileW(name, GENERIC_READ | GENERIC_WRITE, + handle = CreateFileW(name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (self->handle == INVALID_HANDLE_VALUE) - self->handle = CreateFileW(name, access, + if (handle == INVALID_HANDLE_VALUE) + handle = CreateFileW(name, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); Py_END_ALLOW_THREADS - if (self->handle == INVALID_HANDLE_VALUE) { + if (handle == INVALID_HANDLE_VALUE) { PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, GetLastError(), nameobj); goto error; } + + if (self->writable) + self->fd = _Py_open_osfhandle_noraise(handle, _O_WRONLY | _O_BINARY); + else + self->fd = _Py_open_osfhandle_noraise(handle, _O_RDONLY | _O_BINARY); + if (self->fd < 0) { + CloseHandle(handle); + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + goto error; + } } if (console_type == '\0') - console_type = _get_console_type(self->handle); + console_type = _get_console_type(handle); if (self->writable && console_type != 'w') { PyErr_SetString(PyExc_ValueError, @@ -466,25 +460,14 @@ _io._WindowsConsoleIO.fileno Return the underlying file descriptor (an integer). -fileno is only set when a file descriptor is used to open -one of the standard streams. - [clinic start generated code]*/ static PyObject * _io__WindowsConsoleIO_fileno_impl(winconsoleio *self) -/*[clinic end generated code: output=006fa74ce3b5cfbf input=079adc330ddaabe6]*/ +/*[clinic end generated code: output=006fa74ce3b5cfbf input=845c47ebbc3a2f67]*/ { - if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) { - _Py_BEGIN_SUPPRESS_IPH - if (self->writable) - self->fd = _open_osfhandle((intptr_t)self->handle, _O_WRONLY | _O_BINARY); - else - self->fd = _open_osfhandle((intptr_t)self->handle, _O_RDONLY | _O_BINARY); - _Py_END_SUPPRESS_IPH - } if (self->fd < 0) - return err_mode("fileno"); + return err_closed(); return PyLong_FromLong(self->fd); } @@ -498,7 +481,7 @@ static PyObject * _io__WindowsConsoleIO_readable_impl(winconsoleio *self) /*[clinic end generated code: output=daf9cef2743becf0 input=6be9defb5302daae]*/ { - if (self->handle == INVALID_HANDLE_VALUE) + if (self->fd == -1) return err_closed(); return PyBool_FromLong((long) self->readable); } @@ -513,7 +496,7 @@ static PyObject * _io__WindowsConsoleIO_writable_impl(winconsoleio *self) /*[clinic end generated code: output=e0a2ad7eae5abf67 input=cefbd8abc24df6a0]*/ { - if (self->handle == INVALID_HANDLE_VALUE) + if (self->fd == -1) return err_closed(); return PyBool_FromLong((long) self->writable); } @@ -648,7 +631,7 @@ error: static Py_ssize_t readinto(winconsoleio *self, char *buf, Py_ssize_t len) { - if (self->handle == INVALID_HANDLE_VALUE) { + if (self->fd == -1) { err_closed(); return -1; } @@ -663,6 +646,10 @@ readinto(winconsoleio *self, char *buf, Py_ssize_t len) return -1; } + HANDLE handle = _Py_get_osfhandle(self->fd); + if (handle == INVALID_HANDLE_VALUE) + return -1; + /* Each character may take up to 4 bytes in the final buffer. This is highly conservative, but necessary to avoid failure for any given Unicode input (e.g. \U0010ffff). @@ -684,7 +671,7 @@ readinto(winconsoleio *self, char *buf, Py_ssize_t len) return read_len; DWORD n; - wchar_t *wbuf = read_console_w(self->handle, wlen, &n); + wchar_t *wbuf = read_console_w(handle, wlen, &n); if (wbuf == NULL) return -1; if (n == 0) { @@ -790,10 +777,15 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self) DWORD bufsize, n, len = 0; PyObject *bytes; DWORD bytes_size, rn; + HANDLE handle; - if (self->handle == INVALID_HANDLE_VALUE) + if (self->fd == -1) return err_closed(); + handle = _Py_get_osfhandle(self->fd); + if (handle == INVALID_HANDLE_VALUE) + return NULL; + bufsize = BUFSIZ; buf = (wchar_t*)PyMem_Malloc((bufsize + 1) * sizeof(wchar_t)); @@ -825,7 +817,7 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self) buf = tmp; } - subbuf = read_console_w(self->handle, bufsize - len, &n); + subbuf = read_console_w(handle, bufsize - len, &n); if (subbuf == NULL) { PyMem_Free(buf); @@ -915,7 +907,7 @@ _io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) PyObject *bytes; Py_ssize_t bytes_size; - if (self->handle == INVALID_HANDLE_VALUE) + if (self->fd == -1) return err_closed(); if (!self->readable) return err_mode("reading"); @@ -965,12 +957,17 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) BOOL res = TRUE; wchar_t *wbuf; DWORD len, wlen, n = 0; + HANDLE handle; - if (self->handle == INVALID_HANDLE_VALUE) + if (self->fd == -1) return err_closed(); if (!self->writable) return err_mode("writing"); + handle = _Py_get_osfhandle(self->fd); + if (handle == INVALID_HANDLE_VALUE) + return NULL; + if (!b->len) { return PyLong_FromLong(0); } @@ -1001,7 +998,7 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) Py_BEGIN_ALLOW_THREADS wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, wbuf, wlen); if (wlen) { - res = WriteConsoleW(self->handle, wbuf, wlen, &n, NULL); + res = WriteConsoleW(handle, wbuf, wlen, &n, NULL); if (res && n < wlen) { /* Wrote fewer characters than expected, which means our * len value may be wrong. So recalculate it from the @@ -1033,15 +1030,15 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) static PyObject * winconsoleio_repr(winconsoleio *self) { - if (self->handle == INVALID_HANDLE_VALUE) + if (self->fd == -1) return PyUnicode_FromFormat("<_io._WindowsConsoleIO [closed]>"); if (self->readable) return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='rb' closefd=%s>", - self->closehandle ? "True" : "False"); + self->closefd ? "True" : "False"); if (self->writable) return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='wb' closefd=%s>", - self->closehandle ? "True" : "False"); + self->closefd ? "True" : "False"); PyErr_SetString(PyExc_SystemError, "_WindowsConsoleIO has invalid mode"); return NULL; @@ -1057,7 +1054,7 @@ static PyObject * _io__WindowsConsoleIO_isatty_impl(winconsoleio *self) /*[clinic end generated code: output=9eac09d287c11bd7 input=9b91591dbe356f86]*/ { - if (self->handle == INVALID_HANDLE_VALUE) + if (self->fd == -1) return err_closed(); Py_RETURN_TRUE; @@ -1083,13 +1080,13 @@ static PyMethodDef winconsoleio_methods[] = { static PyObject * get_closed(winconsoleio *self, void *closure) { - return PyBool_FromLong((long)(self->handle == INVALID_HANDLE_VALUE)); + return PyBool_FromLong((long)(self->fd == -1)); } static PyObject * get_closefd(winconsoleio *self, void *closure) { - return PyBool_FromLong((long)(self->closehandle)); + return PyBool_FromLong((long)(self->closefd)); } static PyObject * diff --git a/contrib/tools/python3/src/Modules/_json.c b/contrib/tools/python3/src/Modules/_json.c index faa3944eedd..6f68c1f7f9b 100644 --- a/contrib/tools/python3/src/Modules/_json.c +++ b/contrib/tools/python3/src/Modules/_json.c @@ -79,7 +79,6 @@ static PyObject * ascii_escape_unicode(PyObject *pystr); static PyObject * py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr); -void init_json(void); static PyObject * scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); static PyObject * @@ -317,18 +316,22 @@ static void raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) { /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ - static PyObject *JSONDecodeError = NULL; - PyObject *exc; + _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); if (JSONDecodeError == NULL) { - PyObject *decoder = PyImport_ImportModule("json.decoder"); - if (decoder == NULL) - return; - JSONDecodeError = PyObject_GetAttrString(decoder, "JSONDecodeError"); - Py_DECREF(decoder); - if (JSONDecodeError == NULL) - return; + return; } + + PyObject *exc; exc = PyObject_CallFunction(JSONDecodeError, "zOn", msg, s, end); + Py_DECREF(JSONDecodeError); if (exc) { PyErr_SetObject(JSONDecodeError, exc); Py_DECREF(exc); @@ -1308,28 +1311,28 @@ _encoded_const(PyObject *obj) { /* Return the JSON string representation of None, True, False */ if (obj == Py_None) { - static PyObject *s_null = NULL; + _Py_static_string(PyId_null, "null"); + PyObject *s_null = _PyUnicode_FromId(&PyId_null); if (s_null == NULL) { - s_null = PyUnicode_InternFromString("null"); + return NULL; } - Py_XINCREF(s_null); - return s_null; + return Py_NewRef(s_null); } else if (obj == Py_True) { - static PyObject *s_true = NULL; + _Py_static_string(PyId_true, "true"); + PyObject *s_true = _PyUnicode_FromId(&PyId_true); if (s_true == NULL) { - s_true = PyUnicode_InternFromString("true"); + return NULL; } - Py_XINCREF(s_true); - return s_true; + return Py_NewRef(s_true); } else if (obj == Py_False) { - static PyObject *s_false = NULL; + _Py_static_string(PyId_false, "false"); + PyObject *s_false = _PyUnicode_FromId(&PyId_false); if (s_false == NULL) { - s_false = PyUnicode_InternFromString("false"); + return NULL; } - Py_XINCREF(s_false); - return s_false; + return Py_NewRef(s_false); } else { PyErr_SetString(PyExc_ValueError, "not a const"); @@ -1493,9 +1496,12 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level) { /* Encode Python dict dct a JSON term */ - static PyObject *open_dict = NULL; - static PyObject *close_dict = NULL; - static PyObject *empty_dict = NULL; + _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; @@ -1504,11 +1510,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, Py_ssize_t idx; if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { - open_dict = PyUnicode_InternFromString("{"); - close_dict = PyUnicode_InternFromString("}"); - empty_dict = PyUnicode_InternFromString("{}"); - if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) - return -1; + return -1; } if (PyDict_GET_SIZE(dct) == 0) /* Fast path */ return _PyAccu_Accumulate(acc, empty_dict); @@ -1650,19 +1652,18 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level) { /* Encode Python list seq to a JSON term */ - static PyObject *open_array = NULL; - static PyObject *close_array = NULL; - static PyObject *empty_array = NULL; + _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) { - open_array = PyUnicode_InternFromString("["); - close_array = PyUnicode_InternFromString("]"); - empty_array = PyUnicode_InternFromString("[]"); - if (open_array == NULL || close_array == NULL || empty_array == NULL) - return -1; + return -1; } ident = NULL; s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); diff --git a/contrib/tools/python3/src/Modules/_localemodule.c b/contrib/tools/python3/src/Modules/_localemodule.c index 2e353bba00b..564f5598edc 100644 --- a/contrib/tools/python3/src/Modules/_localemodule.c +++ b/contrib/tools/python3/src/Modules/_localemodule.c @@ -53,10 +53,14 @@ get_locale_state(PyObject *m) return (_locale_state *)state; } -/* support functions for formatting floating point numbers */ +#include "clinic/_localemodule.c.h" + +/*[clinic input] +module _locale +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed98569b726feada]*/ -PyDoc_STRVAR(setlocale__doc__, -"(integer,string=None) -> string. Activates/queries locale processing."); +/* support functions for formatting floating point numbers */ /* the grouping is terminated by either 0 or CHAR_MAX */ static PyObject* @@ -91,20 +95,27 @@ copy_grouping(const char* s) return result; } -static PyObject* -PyLocale_setlocale(PyObject* self, PyObject* args) +/*[clinic input] +_locale.setlocale + + category: int + locale: str(accept={str, NoneType}) = NULL + / + +Activates/queries locale processing. +[clinic start generated code]*/ + +static PyObject * +_locale_setlocale_impl(PyObject *module, int category, const char *locale) +/*[clinic end generated code: output=a0e777ae5d2ff117 input=dbe18f1d66c57a6a]*/ { - int category; - char *locale = NULL, *result; + char *result; PyObject *result_object; - if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) - return NULL; - #if defined(MS_WINDOWS) if (category < LC_MIN || category > LC_MAX) { - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "invalid locale category"); return NULL; } @@ -115,7 +126,7 @@ PyLocale_setlocale(PyObject* self, PyObject* args) result = setlocale(category, locale); if (!result) { /* operation failed, no setting was changed */ - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "unsupported locale setting"); return NULL; } @@ -126,7 +137,7 @@ PyLocale_setlocale(PyObject* self, PyObject* args) /* get locale */ result = setlocale(category, NULL); if (!result) { - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "locale query failed"); return NULL; } @@ -221,11 +232,15 @@ done: return res; } -PyDoc_STRVAR(localeconv__doc__, -"() -> dict. Returns numeric and monetary locale-specific parameters."); +/*[clinic input] +_locale.localeconv -static PyObject* -PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored)) +Returns numeric and monetary locale-specific parameters. +[clinic start generated code]*/ + +static PyObject * +_locale_localeconv_impl(PyObject *module) +/*[clinic end generated code: output=43a54515e0a2aef5 input=f1132d15accf4444]*/ { PyObject* result; struct lconv *lc; @@ -326,17 +341,24 @@ PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored)) } #if defined(HAVE_WCSCOLL) -PyDoc_STRVAR(strcoll__doc__, -"string,string -> int. Compares two strings according to the locale."); -static PyObject* -PyLocale_strcoll(PyObject* self, PyObject* args) +/*[clinic input] +_locale.strcoll + + os1: unicode + os2: unicode + / + +Compares two strings according to the locale. +[clinic start generated code]*/ + +static PyObject * +_locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2) +/*[clinic end generated code: output=82ddc6d62c76d618 input=693cd02bcbf38dd8]*/ { - PyObject *os1, *os2, *result = NULL; + PyObject *result = NULL; wchar_t *ws1 = NULL, *ws2 = NULL; - if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2)) - return NULL; /* Convert the unicode strings to wchar[]. */ ws1 = PyUnicode_AsWideCharString(os1, NULL); if (ws1 == NULL) @@ -348,30 +370,32 @@ PyLocale_strcoll(PyObject* self, PyObject* args) result = PyLong_FromLong(wcscoll(ws1, ws2)); done: /* Deallocate everything. */ - if (ws1) PyMem_FREE(ws1); - if (ws2) PyMem_FREE(ws2); + if (ws1) PyMem_Free(ws1); + if (ws2) PyMem_Free(ws2); return result; } #endif #ifdef HAVE_WCSXFRM -PyDoc_STRVAR(strxfrm__doc__, -"strxfrm(string) -> string.\n\ -\n\ -Return a string that can be used as a key for locale-aware comparisons."); -static PyObject* -PyLocale_strxfrm(PyObject* self, PyObject* args) +/*[clinic input] +_locale.strxfrm + + string as str: unicode + / + +Return a string that can be used as a key for locale-aware comparisons. +[clinic start generated code]*/ + +static PyObject * +_locale_strxfrm_impl(PyObject *module, PyObject *str) +/*[clinic end generated code: output=3081866ebffc01af input=1378bbe6a88b4780]*/ { - PyObject *str; Py_ssize_t n1; wchar_t *s = NULL, *buf = NULL; size_t n2; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "U:strxfrm", &str)) - return NULL; - s = PyUnicode_AsWideCharString(str, &n1); if (s == NULL) goto exit; @@ -418,8 +442,15 @@ exit: #endif #if defined(MS_WINDOWS) -static PyObject* -PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored)) + +/*[clinic input] +_locale._getdefaultlocale + +[clinic start generated code]*/ + +static PyObject * +_locale__getdefaultlocale_impl(PyObject *module) +/*[clinic end generated code: output=e6254088579534c2 input=003ea41acd17f7c7]*/ { char encoding[20]; char locale[100]; @@ -525,7 +556,6 @@ static struct langinfo_constant{ LANGINFO(PM_STR), /* The following constants are available only with XPG4, but... - AIX 3.2. only has CODESET. OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have a few of the others. Solution: ifdef-test them all. */ @@ -563,16 +593,20 @@ static struct langinfo_constant{ {0, 0} }; -PyDoc_STRVAR(nl_langinfo__doc__, -"nl_langinfo(key) -> string\n" -"Return the value for the locale information associated with key."); +/*[clinic input] +_locale.nl_langinfo -static PyObject* -PyLocale_nl_langinfo(PyObject* self, PyObject* args) + key as item: int + / + +Return the value for the locale information associated with key. +[clinic start generated code]*/ + +static PyObject * +_locale_nl_langinfo_impl(PyObject *module, int item) +/*[clinic end generated code: output=6aea457b47e077a3 input=00798143eecfeddc]*/ { - int item, i; - if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item)) - return NULL; + int i; /* Check whether this is a supported constant. GNU libc sometimes returns numeric values in the char* return value, which would crash PyUnicode_FromString. */ @@ -591,56 +625,75 @@ PyLocale_nl_langinfo(PyObject* self, PyObject* args) #ifdef HAVE_LIBINTL_H -PyDoc_STRVAR(gettext__doc__, -"gettext(msg) -> string\n" -"Return translation of msg."); +/*[clinic input] +_locale.gettext -static PyObject* -PyIntl_gettext(PyObject* self, PyObject *args) + msg as in: str + / + +gettext(msg) -> string + +Return translation of msg. +[clinic start generated code]*/ + +static PyObject * +_locale_gettext_impl(PyObject *module, const char *in) +/*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/ { - char *in; - if (!PyArg_ParseTuple(args, "s", &in)) - return 0; return PyUnicode_DecodeLocale(gettext(in), NULL); } -PyDoc_STRVAR(dgettext__doc__, -"dgettext(domain, msg) -> string\n" -"Return translation of msg in domain."); +/*[clinic input] +_locale.dgettext -static PyObject* -PyIntl_dgettext(PyObject* self, PyObject *args) + domain: str(accept={str, NoneType}) + msg as in: str + / + +dgettext(domain, msg) -> string + +Return translation of msg in domain. +[clinic start generated code]*/ + +static PyObject * +_locale_dgettext_impl(PyObject *module, const char *domain, const char *in) +/*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/ { - char *domain, *in; - if (!PyArg_ParseTuple(args, "zs", &domain, &in)) - return 0; return PyUnicode_DecodeLocale(dgettext(domain, in), NULL); } -PyDoc_STRVAR(dcgettext__doc__, -"dcgettext(domain, msg, category) -> string\n" -"Return translation of msg in domain and category."); +/*[clinic input] +_locale.dcgettext -static PyObject* -PyIntl_dcgettext(PyObject *self, PyObject *args) + domain: str(accept={str, NoneType}) + msg as msgid: str + category: int + / + +Return translation of msg in domain and category. +[clinic start generated code]*/ + +static PyObject * +_locale_dcgettext_impl(PyObject *module, const char *domain, + const char *msgid, int category) +/*[clinic end generated code: output=0f4cc4fce0aa283f input=ec5f8fed4336de67]*/ { - char *domain, *msgid; - int category; - if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category)) - return 0; return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL); } -PyDoc_STRVAR(textdomain__doc__, -"textdomain(domain) -> string\n" -"Set the C library's textdmain to domain, returning the new domain."); +/*[clinic input] +_locale.textdomain -static PyObject* -PyIntl_textdomain(PyObject* self, PyObject* args) + domain: str(accept={str, NoneType}) + / + +Set the C library's textdmain to domain, returning the new domain. +[clinic start generated code]*/ + +static PyObject * +_locale_textdomain_impl(PyObject *module, const char *domain) +/*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/ { - char *domain; - if (!PyArg_ParseTuple(args, "z", &domain)) - return 0; domain = textdomain(domain); if (!domain) { PyErr_SetFromErrno(PyExc_OSError); @@ -649,20 +702,26 @@ PyIntl_textdomain(PyObject* self, PyObject* args) return PyUnicode_DecodeLocale(domain, NULL); } -PyDoc_STRVAR(bindtextdomain__doc__, -"bindtextdomain(domain, dir) -> string\n" -"Bind the C library's domain to dir."); +/*[clinic input] +_locale.bindtextdomain -static PyObject* -PyIntl_bindtextdomain(PyObject* self, PyObject*args) + domain: str + dir as dirname_obj: object + / + +Bind the C library's domain to dir. +[clinic start generated code]*/ + +static PyObject * +_locale_bindtextdomain_impl(PyObject *module, const char *domain, + PyObject *dirname_obj) +/*[clinic end generated code: output=6d6f3c7b345d785c input=c0dff085acfe272b]*/ { - const char *domain, *dirname, *current_dirname; - PyObject *dirname_obj, *dirname_bytes = NULL, *result; + const char *dirname, *current_dirname; + PyObject *dirname_bytes = NULL, *result; - if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) - return 0; if (!strlen(domain)) { - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "domain must be a non-empty string"); return 0; } @@ -686,61 +745,73 @@ PyIntl_bindtextdomain(PyObject* self, PyObject*args) } #ifdef HAVE_BIND_TEXTDOMAIN_CODESET -PyDoc_STRVAR(bind_textdomain_codeset__doc__, -"bind_textdomain_codeset(domain, codeset) -> string\n" -"Bind the C library's domain to codeset."); -static PyObject* -PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args) +/*[clinic input] +_locale.bind_textdomain_codeset + + domain: str + codeset: str(accept={str, NoneType}) + / + +Bind the C library's domain to codeset. +[clinic start generated code]*/ + +static PyObject * +_locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain, + const char *codeset) +/*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/ { - char *domain,*codeset; - if (!PyArg_ParseTuple(args, "sz", &domain, &codeset)) - return NULL; codeset = bind_textdomain_codeset(domain, codeset); if (codeset) { return PyUnicode_DecodeLocale(codeset, NULL); } Py_RETURN_NONE; } -#endif +#endif // HAVE_BIND_TEXTDOMAIN_CODESET + +#endif // HAVE_LIBINTL_H + + +/*[clinic input] +_locale._get_locale_encoding + +Get the current locale encoding. +[clinic start generated code]*/ + +static PyObject * +_locale__get_locale_encoding_impl(PyObject *module) +/*[clinic end generated code: output=e8e2f6f6f184591a input=513d9961d2f45c76]*/ +{ + return _Py_GetLocaleEncodingObject(); +} -#endif static struct PyMethodDef PyLocale_Methods[] = { - {"setlocale", (PyCFunction) PyLocale_setlocale, - METH_VARARGS, setlocale__doc__}, - {"localeconv", PyLocale_localeconv, METH_NOARGS, localeconv__doc__}, + _LOCALE_SETLOCALE_METHODDEF + _LOCALE_LOCALECONV_METHODDEF #ifdef HAVE_WCSCOLL - {"strcoll", (PyCFunction) PyLocale_strcoll, - METH_VARARGS, strcoll__doc__}, + _LOCALE_STRCOLL_METHODDEF #endif #ifdef HAVE_WCSXFRM - {"strxfrm", (PyCFunction) PyLocale_strxfrm, - METH_VARARGS, strxfrm__doc__}, + _LOCALE_STRXFRM_METHODDEF #endif #if defined(MS_WINDOWS) - {"_getdefaultlocale", PyLocale_getdefaultlocale, METH_NOARGS}, + _LOCALE__GETDEFAULTLOCALE_METHODDEF #endif #ifdef HAVE_LANGINFO_H - {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo, - METH_VARARGS, nl_langinfo__doc__}, + _LOCALE_NL_LANGINFO_METHODDEF #endif #ifdef HAVE_LIBINTL_H - {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS, - gettext__doc__}, - {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS, - dgettext__doc__}, - {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS, - dcgettext__doc__}, - {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS, - textdomain__doc__}, - {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS, - bindtextdomain__doc__}, + _LOCALE_GETTEXT_METHODDEF + _LOCALE_DGETTEXT_METHODDEF + _LOCALE_DCGETTEXT_METHODDEF + _LOCALE_TEXTDOMAIN_METHODDEF + _LOCALE_BINDTEXTDOMAIN_METHODDEF #ifdef HAVE_BIND_TEXTDOMAIN_CODESET - {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset, - METH_VARARGS, bind_textdomain_codeset__doc__}, + _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #endif #endif + _LOCALE__GET_LOCALE_ENCODING_METHODDEF {NULL, NULL} }; diff --git a/contrib/tools/python3/src/Modules/_lsprof.c b/contrib/tools/python3/src/Modules/_lsprof.c index 5e53d839640..703067cc743 100644 --- a/contrib/tools/python3/src/Modules/_lsprof.c +++ b/contrib/tools/python3/src/Modules/_lsprof.c @@ -50,10 +50,27 @@ typedef struct { #define POF_BUILTINS 0x004 #define POF_NOMEMORY 0x100 -static PyTypeObject PyProfiler_Type; +/*[clinic input] +module _lsprof +class _lsprof.Profiler "ProfilerObject *" "&ProfilerType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e349ac952152f336]*/ -#define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) -#define PyProfiler_CheckExact(op) Py_IS_TYPE(op, &PyProfiler_Type) +#include "clinic/_lsprof.c.h" + +typedef struct { + PyTypeObject *profiler_type; + PyTypeObject *stats_entry_type; + PyTypeObject *stats_subentry_type; +} _lsprof_state; + +static inline _lsprof_state* +_lsprof_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_lsprof_state *)state; +} /*** External Timers ***/ @@ -471,28 +488,24 @@ static PyStructSequence_Field profiler_subentry_fields[] = { }; static PyStructSequence_Desc profiler_entry_desc = { - "_lsprof.profiler_entry", /* name */ - NULL, /* doc */ - profiler_entry_fields, - 6 + .name = "_lsprof.profiler_entry", + .fields = profiler_entry_fields, + .doc = NULL, + .n_in_sequence = 6 }; static PyStructSequence_Desc profiler_subentry_desc = { - "_lsprof.profiler_subentry", /* name */ - NULL, /* doc */ - profiler_subentry_fields, - 5 + .name = "_lsprof.profiler_subentry", + .fields = profiler_subentry_fields, + .doc = NULL, + .n_in_sequence = 5 }; -static int initialized; -static PyTypeObject StatsEntryType; -static PyTypeObject StatsSubEntryType; - - typedef struct { PyObject *list; PyObject *sublist; double factor; + _lsprof_state *state; } statscollector_t; static int statsForSubEntry(rotating_node_t *node, void *arg) @@ -502,7 +515,7 @@ static int statsForSubEntry(rotating_node_t *node, void *arg) ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key; int err; PyObject *sinfo; - sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType, + sinfo = PyObject_CallFunction((PyObject*) collect->state->stats_subentry_type, "((Olldd))", entry->userObj, sentry->callcount, @@ -540,7 +553,7 @@ static int statsForEntry(rotating_node_t *node, void *arg) collect->sublist = Py_None; } - info = PyObject_CallFunction((PyObject*) &StatsEntryType, + info = PyObject_CallFunction((PyObject*) collect->state->stats_entry_type, "((OllddO))", entry->userObj, entry->callcount, @@ -556,49 +569,57 @@ static int statsForEntry(rotating_node_t *node, void *arg) return err; } -PyDoc_STRVAR(getstats_doc, "\ -getstats() -> list of profiler_entry objects\n\ -\n\ -Return all information collected by the profiler.\n\ -Each profiler_entry is a tuple-like object with the\n\ -following attributes:\n\ -\n\ - code code object\n\ - callcount how many times this was called\n\ - reccallcount how many times called recursively\n\ - totaltime total time in this entry\n\ - inlinetime inline time in this entry (not in subcalls)\n\ - calls details of the calls\n\ -\n\ -The calls attribute is either None or a list of\n\ -profiler_subentry objects:\n\ -\n\ - code called code object\n\ - callcount how many times this is called\n\ - reccallcount how many times this is called recursively\n\ - totaltime total time spent in this call\n\ - inlinetime inline time (not in further subcalls)\n\ -"); +/*[clinic input] +_lsprof.Profiler.getstats -static PyObject* -profiler_getstats(ProfilerObject *pObj, PyObject* noarg) + cls: defining_class + +list of profiler_entry objects. + +getstats() -> list of profiler_entry objects + +Return all information collected by the profiler. +Each profiler_entry is a tuple-like object with the +following attributes: + + code code object + callcount how many times this was called + reccallcount how many times called recursively + totaltime total time in this entry + inlinetime inline time in this entry (not in subcalls) + calls details of the calls + +The calls attribute is either None or a list of +profiler_subentry objects: + + code called code object + callcount how many times this is called + reccallcount how many times this is called recursively + totaltime total time spent in this call + inlinetime inline time (not in further subcalls) +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=1806ef720019ee03 input=445e193ef4522902]*/ { statscollector_t collect; - if (pending_exception(pObj)) { + collect.state = PyType_GetModuleState(cls); + if (pending_exception(self)) { return NULL; } - if (!pObj->externalTimer || pObj->externalTimerUnit == 0.0) { + if (!self->externalTimer || self->externalTimerUnit == 0.0) { _PyTime_t onesec = _PyTime_FromSeconds(1); collect.factor = (double)1 / onesec; } else { - collect.factor = pObj->externalTimerUnit; + collect.factor = self->externalTimerUnit; } collect.list = PyList_New(0); if (collect.list == NULL) return NULL; - if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) + if (RotatingTree_Enum(self->profilerEntries, statsForEntry, &collect) != 0) { Py_DECREF(collect.list); return NULL; @@ -710,6 +731,13 @@ profiler_clear(ProfilerObject *pObj, PyObject* noarg) Py_RETURN_NONE; } +static int +profiler_traverse(ProfilerObject *op, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(op)); + return 0; +} + static void profiler_dealloc(ProfilerObject *op) { @@ -723,7 +751,9 @@ profiler_dealloc(ProfilerObject *op) flush_unmatched(op); clearEntries(op); Py_XDECREF(op->externalTimer); - Py_TYPE(op)->tp_free(op); + PyTypeObject *tp = Py_TYPE(op); + tp->tp_free(op); + Py_DECREF(tp); } static int @@ -750,8 +780,7 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) } static PyMethodDef profiler_methods[] = { - {"getstats", (PyCFunction)profiler_getstats, - METH_NOARGS, getstats_doc}, + _LSPROF_PROFILER_GETSTATS_METHODDEF {"enable", (PyCFunction)(void(*)(void))profiler_enable, METH_VARARGS | METH_KEYWORDS, enable_doc}, {"disable", (PyCFunction)profiler_disable, @@ -771,91 +800,106 @@ Profiler(timer=None, timeunit=None, subcalls=True, builtins=True)\n\ is, in seconds).\n\ "); -static PyTypeObject PyProfiler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lsprof.Profiler", /* tp_name */ - sizeof(ProfilerObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)profiler_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 */ - profiler_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - profiler_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 */ - (initproc)profiler_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - PyObject_Del, /* tp_free */ +static PyType_Slot _lsprof_profiler_type_spec_slots[] = { + {Py_tp_doc, (void *)profiler_doc}, + {Py_tp_methods, profiler_methods}, + {Py_tp_dealloc, profiler_dealloc}, + {Py_tp_init, profiler_init}, + {Py_tp_traverse, profiler_traverse}, + {0, 0} +}; + +static PyType_Spec _lsprof_profiler_type_spec = { + .name = "_lsprof.Profiler", + .basicsize = sizeof(ProfilerObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = _lsprof_profiler_type_spec_slots, }; static PyMethodDef moduleMethods[] = { {NULL, NULL} }; +static int +_lsprof_traverse(PyObject *module, visitproc visit, void *arg) +{ + _lsprof_state *state = _lsprof_get_state(module); + Py_VISIT(state->profiler_type); + Py_VISIT(state->stats_entry_type); + Py_VISIT(state->stats_subentry_type); + return 0; +} + +static int +_lsprof_clear(PyObject *module) +{ + _lsprof_state *state = _lsprof_get_state(module); + Py_CLEAR(state->profiler_type); + Py_CLEAR(state->stats_entry_type); + Py_CLEAR(state->stats_subentry_type); + return 0; +} + +static void +_lsprof_free(void *module) +{ + _lsprof_clear((PyObject *)module); +} + +static int +_lsprof_exec(PyObject *module) +{ + _lsprof_state *state = PyModule_GetState(module); + + state->profiler_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &_lsprof_profiler_type_spec, NULL); + if (state->profiler_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, state->profiler_type) < 0) { + return -1; + } + + state->stats_entry_type = PyStructSequence_NewType(&profiler_entry_desc); + if (state->stats_entry_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->stats_entry_type) < 0) { + return -1; + } + + state->stats_subentry_type = PyStructSequence_NewType(&profiler_subentry_desc); + if (state->stats_subentry_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->stats_subentry_type) < 0) { + return -1; + } + + return 0; +} + +static PyModuleDef_Slot _lsprofslots[] = { + {Py_mod_exec, _lsprof_exec}, + {0, NULL} +}; static struct PyModuleDef _lsprofmodule = { PyModuleDef_HEAD_INIT, - "_lsprof", - "Fast profiler", - -1, - moduleMethods, - NULL, - NULL, - NULL, - NULL + .m_name = "_lsprof", + .m_doc = "Fast profiler", + .m_size = sizeof(_lsprof_state), + .m_methods = moduleMethods, + .m_slots = _lsprofslots, + .m_traverse = _lsprof_traverse, + .m_clear = _lsprof_clear, + .m_free = _lsprof_free }; PyMODINIT_FUNC PyInit__lsprof(void) { - PyObject *module, *d; - module = PyModule_Create(&_lsprofmodule); - if (module == NULL) - return NULL; - d = PyModule_GetDict(module); - if (PyType_Ready(&PyProfiler_Type) < 0) - return NULL; - PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); - - if (!initialized) { - if (PyStructSequence_InitType2(&StatsEntryType, - &profiler_entry_desc) < 0) - return NULL; - if (PyStructSequence_InitType2(&StatsSubEntryType, - &profiler_subentry_desc) < 0) - return NULL; - } - Py_INCREF((PyObject*) &StatsEntryType); - Py_INCREF((PyObject*) &StatsSubEntryType); - PyModule_AddObject(module, "profiler_entry", - (PyObject*) &StatsEntryType); - PyModule_AddObject(module, "profiler_subentry", - (PyObject*) &StatsSubEntryType); - initialized = 1; - return module; + return PyModuleDef_Init(&_lsprofmodule); } diff --git a/contrib/tools/python3/src/Modules/_lzmamodule.c b/contrib/tools/python3/src/Modules/_lzmamodule.c index 2a62a683568..915c0c918f6 100644 --- a/contrib/tools/python3/src/Modules/_lzmamodule.c +++ b/contrib/tools/python3/src/Modules/_lzmamodule.c @@ -15,6 +15,60 @@ #include +// Blocks output buffer wrappers +#include "pycore_blocks_output_buffer.h" + +#if OUTPUT_BUFFER_MAX_BLOCK_SIZE > SIZE_MAX + #error "The maximum block size accepted by liblzma is SIZE_MAX." +#endif + +/* On success, return value >= 0 + On failure, return -1 */ +static inline Py_ssize_t +OutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer, Py_ssize_t max_length, + uint8_t **next_out, size_t *avail_out) +{ + Py_ssize_t allocated; + + allocated = _BlocksOutputBuffer_InitAndGrow( + buffer, max_length, (void**) next_out); + *avail_out = (size_t) allocated; + return allocated; +} + +/* On success, return value >= 0 + On failure, return -1 */ +static inline Py_ssize_t +OutputBuffer_Grow(_BlocksOutputBuffer *buffer, + uint8_t **next_out, size_t *avail_out) +{ + Py_ssize_t allocated; + + allocated = _BlocksOutputBuffer_Grow( + buffer, (void**) next_out, (Py_ssize_t) *avail_out); + *avail_out = (size_t) allocated; + return allocated; +} + +static inline Py_ssize_t +OutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer, size_t avail_out) +{ + return _BlocksOutputBuffer_GetDataSize(buffer, (Py_ssize_t) avail_out); +} + +static inline PyObject * +OutputBuffer_Finish(_BlocksOutputBuffer *buffer, size_t avail_out) +{ + return _BlocksOutputBuffer_Finish(buffer, (Py_ssize_t) avail_out); +} + +static inline void +OutputBuffer_OnError(_BlocksOutputBuffer *buffer) +{ + _BlocksOutputBuffer_OnError(buffer); +} + + #define ACQUIRE_LOCK(obj) do { \ if (!PyThread_acquire_lock((obj)->lock, 0)) { \ Py_BEGIN_ALLOW_THREADS \ @@ -23,6 +77,20 @@ } } while (0) #define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock) +typedef struct { + PyTypeObject *lzma_compressor_type; + PyTypeObject *lzma_decompressor_type; + PyObject *error; + PyObject *empty_tuple; +} _lzma_state; + +static inline _lzma_state* +get_lzma_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_lzma_state *)state; +} /* Container formats: */ enum { @@ -56,17 +124,10 @@ typedef struct { PyThread_type_lock lock; } Decompressor; -/* LZMAError class object. */ -static PyObject *Error; - -/* An empty tuple, used by the filter specifier parsing code. */ -static PyObject *empty_tuple; - - /* Helper functions. */ static int -catch_lzma_error(lzma_ret lzret) +catch_lzma_error(_lzma_state *state, lzma_ret lzret) { switch (lzret) { case LZMA_OK: @@ -75,31 +136,31 @@ catch_lzma_error(lzma_ret lzret) case LZMA_STREAM_END: return 0; case LZMA_UNSUPPORTED_CHECK: - PyErr_SetString(Error, "Unsupported integrity check"); + PyErr_SetString(state->error, "Unsupported integrity check"); return 1; case LZMA_MEM_ERROR: PyErr_NoMemory(); return 1; case LZMA_MEMLIMIT_ERROR: - PyErr_SetString(Error, "Memory usage limit exceeded"); + PyErr_SetString(state->error, "Memory usage limit exceeded"); return 1; case LZMA_FORMAT_ERROR: - PyErr_SetString(Error, "Input format not supported by decoder"); + PyErr_SetString(state->error, "Input format not supported by decoder"); return 1; case LZMA_OPTIONS_ERROR: - PyErr_SetString(Error, "Invalid or unsupported options"); + PyErr_SetString(state->error, "Invalid or unsupported options"); return 1; case LZMA_DATA_ERROR: - PyErr_SetString(Error, "Corrupt input data"); + PyErr_SetString(state->error, "Corrupt input data"); return 1; case LZMA_BUF_ERROR: - PyErr_SetString(Error, "Insufficient buffer space"); + PyErr_SetString(state->error, "Insufficient buffer space"); return 1; case LZMA_PROG_ERROR: - PyErr_SetString(Error, "Internal error"); + PyErr_SetString(state->error, "Internal error"); return 1; default: - PyErr_Format(Error, "Unrecognized error from liblzma: %d", lzret); + PyErr_Format(state->error, "Unrecognized error from liblzma: %d", lzret); return 1; } } @@ -107,8 +168,9 @@ catch_lzma_error(lzma_ret lzret) static void* PyLzma_Malloc(void *opaque, size_t items, size_t size) { - if (size != 0 && items > (size_t)PY_SSIZE_T_MAX / size) + if (size != 0 && items > (size_t)PY_SSIZE_T_MAX / size) { return NULL; + } /* PyMem_Malloc() cannot be used: the GIL is not held when lzma_code() is called */ return PyMem_RawMalloc(items * size); @@ -120,24 +182,6 @@ PyLzma_Free(void *opaque, void *ptr) PyMem_RawFree(ptr); } -#if BUFSIZ < 8192 -#define INITIAL_BUFFER_SIZE 8192 -#else -#define INITIAL_BUFFER_SIZE BUFSIZ -#endif - -static int -grow_buffer(PyObject **buf, Py_ssize_t max_length) -{ - Py_ssize_t size = PyBytes_GET_SIZE(*buf); - Py_ssize_t newsize = size + (size >> 3) + 6; - - if (max_length > 0 && newsize > max_length) - newsize = max_length; - - return _PyBytes_Resize(buf, newsize); -} - /* Some custom type conversions for PyArg_ParseTupleAndKeywords(), since the predefined conversion specifiers do not suit our needs: @@ -186,7 +230,7 @@ INT_TYPE_CONVERTER_FUNC(lzma_match_finder, lzma_mf_converter) the C lzma_filter structs expected by liblzma. */ static void * -parse_filter_spec_lzma(PyObject *spec) +parse_filter_spec_lzma(_lzma_state *state, PyObject *spec) { static char *optnames[] = {"id", "preset", "dict_size", "lc", "lp", "pb", "mode", "nice_len", "mf", "depth", NULL}; @@ -200,28 +244,32 @@ parse_filter_spec_lzma(PyObject *spec) preset_obj = PyMapping_GetItemString(spec, "preset"); if (preset_obj == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) + if (PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Clear(); - else + } + else { return NULL; + } } else { int ok = uint32_converter(preset_obj, &preset); Py_DECREF(preset_obj); - if (!ok) + if (!ok) { return NULL; + } } options = (lzma_options_lzma *)PyMem_Calloc(1, sizeof *options); - if (options == NULL) + if (options == NULL) { return PyErr_NoMemory(); + } if (lzma_lzma_preset(options, preset)) { PyMem_Free(options); - PyErr_Format(Error, "Invalid compression preset: %u", preset); + PyErr_Format(state->error, "Invalid compression preset: %u", preset); return NULL; } - if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, + if (!PyArg_ParseTupleAndKeywords(state->empty_tuple, spec, "|OOO&O&O&O&O&O&O&O&", optnames, &id, &preset_obj, uint32_converter, &options->dict_size, @@ -235,20 +283,21 @@ parse_filter_spec_lzma(PyObject *spec) PyErr_SetString(PyExc_ValueError, "Invalid filter specifier for LZMA filter"); PyMem_Free(options); - options = NULL; + return NULL; } + return options; } static void * -parse_filter_spec_delta(PyObject *spec) +parse_filter_spec_delta(_lzma_state *state, PyObject *spec) { static char *optnames[] = {"id", "dist", NULL}; PyObject *id; uint32_t dist = 1; lzma_options_delta *options; - if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames, + if (!PyArg_ParseTupleAndKeywords(state->empty_tuple, spec, "|OO&", optnames, &id, uint32_converter, &dist)) { PyErr_SetString(PyExc_ValueError, "Invalid filter specifier for delta filter"); @@ -256,22 +305,23 @@ parse_filter_spec_delta(PyObject *spec) } options = (lzma_options_delta *)PyMem_Calloc(1, sizeof *options); - if (options == NULL) + if (options == NULL) { return PyErr_NoMemory(); + } options->type = LZMA_DELTA_TYPE_BYTE; options->dist = dist; return options; } static void * -parse_filter_spec_bcj(PyObject *spec) +parse_filter_spec_bcj(_lzma_state *state, PyObject *spec) { static char *optnames[] = {"id", "start_offset", NULL}; PyObject *id; uint32_t start_offset = 0; lzma_options_bcj *options; - if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames, + if (!PyArg_ParseTupleAndKeywords(state->empty_tuple, spec, "|OO&", optnames, &id, uint32_converter, &start_offset)) { PyErr_SetString(PyExc_ValueError, "Invalid filter specifier for BCJ filter"); @@ -279,14 +329,15 @@ parse_filter_spec_bcj(PyObject *spec) } options = (lzma_options_bcj *)PyMem_Calloc(1, sizeof *options); - if (options == NULL) + if (options == NULL) { return PyErr_NoMemory(); + } options->start_offset = start_offset; return options; } static int -lzma_filter_converter(PyObject *spec, void *ptr) +lzma_filter_converter(_lzma_state *state, PyObject *spec, void *ptr) { lzma_filter *f = (lzma_filter *)ptr; PyObject *id_obj; @@ -305,16 +356,17 @@ lzma_filter_converter(PyObject *spec, void *ptr) } f->id = PyLong_AsUnsignedLongLong(id_obj); Py_DECREF(id_obj); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { return 0; + } switch (f->id) { case LZMA_FILTER_LZMA1: case LZMA_FILTER_LZMA2: - f->options = parse_filter_spec_lzma(spec); + f->options = parse_filter_spec_lzma(state, spec); return f->options != NULL; case LZMA_FILTER_DELTA: - f->options = parse_filter_spec_delta(spec); + f->options = parse_filter_spec_delta(state, spec); return f->options != NULL; case LZMA_FILTER_X86: case LZMA_FILTER_POWERPC: @@ -322,7 +374,7 @@ lzma_filter_converter(PyObject *spec, void *ptr) case LZMA_FILTER_ARM: case LZMA_FILTER_ARMTHUMB: case LZMA_FILTER_SPARC: - f->options = parse_filter_spec_bcj(spec); + f->options = parse_filter_spec_bcj(state, spec); return f->options != NULL; default: PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id); @@ -333,20 +385,20 @@ lzma_filter_converter(PyObject *spec, void *ptr) static void free_filter_chain(lzma_filter filters[]) { - int i; - - for (i = 0; filters[i].id != LZMA_VLI_UNKNOWN; i++) + for (int i = 0; filters[i].id != LZMA_VLI_UNKNOWN; i++) { PyMem_Free(filters[i].options); + } } static int -parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs) +parse_filter_chain_spec(_lzma_state *state, lzma_filter filters[], PyObject *filterspecs) { Py_ssize_t i, num_filters; num_filters = PySequence_Length(filterspecs); - if (num_filters == -1) + if (num_filters == -1) { return -1; + } if (num_filters > LZMA_FILTERS_MAX) { PyErr_Format(PyExc_ValueError, "Too many filters - liblzma supports a maximum of %d", @@ -357,8 +409,9 @@ parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs) for (i = 0; i < num_filters; i++) { int ok = 1; PyObject *spec = PySequence_GetItem(filterspecs, i); - if (spec == NULL || !lzma_filter_converter(spec, &filters[i])) + if (spec == NULL || !lzma_filter_converter(state, spec, &filters[i])) { ok = 0; + } Py_XDECREF(spec); if (!ok) { filters[i].id = LZMA_VLI_UNKNOWN; @@ -383,8 +436,9 @@ spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned long long value) PyObject *value_object; value_object = PyLong_FromUnsignedLongLong(value); - if (value_object == NULL) + if (value_object == NULL) { return -1; + } status = _PyDict_SetItemId(spec, key, value_object); Py_DECREF(value_object); @@ -397,8 +451,9 @@ build_filter_spec(const lzma_filter *f) PyObject *spec; spec = PyDict_New(); - if (spec == NULL) + if (spec == NULL) { return NULL; + } #define ADD_FIELD(SOURCE, FIELD) \ do { \ @@ -490,44 +545,47 @@ class lzma_filter_converter(CConverter): static PyObject * compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) { - Py_ssize_t data_size = 0; PyObject *result; + _BlocksOutputBuffer buffer = {.list = NULL}; + _lzma_state *state = PyType_GetModuleState(Py_TYPE(c)); + assert(state != NULL); - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - if (result == NULL) - return NULL; + if (OutputBuffer_InitAndGrow(&buffer, -1, &c->lzs.next_out, &c->lzs.avail_out) < 0) { + goto error; + } c->lzs.next_in = data; c->lzs.avail_in = len; - c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result); - c->lzs.avail_out = PyBytes_GET_SIZE(result); + for (;;) { lzma_ret lzret; Py_BEGIN_ALLOW_THREADS lzret = lzma_code(&c->lzs, action); - data_size = (char *)c->lzs.next_out - PyBytes_AS_STRING(result); - if (lzret == LZMA_BUF_ERROR && len == 0 && c->lzs.avail_out > 0) - lzret = LZMA_OK; /* That wasn't a real error */ Py_END_ALLOW_THREADS - if (catch_lzma_error(lzret)) + + if (lzret == LZMA_BUF_ERROR && len == 0 && c->lzs.avail_out > 0) { + lzret = LZMA_OK; /* That wasn't a real error */ + } + if (catch_lzma_error(state, lzret)) { goto error; + } if ((action == LZMA_RUN && c->lzs.avail_in == 0) || (action == LZMA_FINISH && lzret == LZMA_STREAM_END)) { break; } else if (c->lzs.avail_out == 0) { - if (grow_buffer(&result, -1) == -1) + if (OutputBuffer_Grow(&buffer, &c->lzs.next_out, &c->lzs.avail_out) < 0) { goto error; - c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; - c->lzs.avail_out = PyBytes_GET_SIZE(result) - data_size; + } } } - if (data_size != PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) == -1) - goto error; - return result; + + result = OutputBuffer_Finish(&buffer, c->lzs.avail_out); + if (result != NULL) { + return result; + } error: - Py_XDECREF(result); + OutputBuffer_OnError(&buffer); return NULL; } @@ -552,10 +610,12 @@ _lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data) PyObject *result = NULL; ACQUIRE_LOCK(self); - if (self->flushed) + if (self->flushed) { PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); - else + } + else { result = compress(self, data->buf, data->len, LZMA_RUN); + } RELEASE_LOCK(self); return result; } @@ -588,8 +648,8 @@ _lzma_LZMACompressor_flush_impl(Compressor *self) } static int -Compressor_init_xz(lzma_stream *lzs, int check, uint32_t preset, - PyObject *filterspecs) +Compressor_init_xz(_lzma_state *state, lzma_stream *lzs, + int check, uint32_t preset, PyObject *filterspecs) { lzma_ret lzret; @@ -598,19 +658,21 @@ Compressor_init_xz(lzma_stream *lzs, int check, uint32_t preset, } else { lzma_filter filters[LZMA_FILTERS_MAX + 1]; - if (parse_filter_chain_spec(filters, filterspecs) == -1) + if (parse_filter_chain_spec(state, filters, filterspecs) == -1) return -1; lzret = lzma_stream_encoder(lzs, filters, check); free_filter_chain(filters); } - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { return -1; - else + } + else { return 0; + } } static int -Compressor_init_alone(lzma_stream *lzs, uint32_t preset, PyObject *filterspecs) +Compressor_init_alone(_lzma_state *state, lzma_stream *lzs, uint32_t preset, PyObject *filterspecs) { lzma_ret lzret; @@ -618,14 +680,14 @@ Compressor_init_alone(lzma_stream *lzs, uint32_t preset, PyObject *filterspecs) lzma_options_lzma options; if (lzma_lzma_preset(&options, preset)) { - PyErr_Format(Error, "Invalid compression preset: %u", preset); + PyErr_Format(state->error, "Invalid compression preset: %u", preset); return -1; } lzret = lzma_alone_encoder(lzs, &options); } else { lzma_filter filters[LZMA_FILTERS_MAX + 1]; - if (parse_filter_chain_spec(filters, filterspecs) == -1) + if (parse_filter_chain_spec(state, filters, filterspecs) == -1) return -1; if (filters[0].id == LZMA_FILTER_LZMA1 && filters[1].id == LZMA_VLI_UNKNOWN) { @@ -638,14 +700,16 @@ Compressor_init_alone(lzma_stream *lzs, uint32_t preset, PyObject *filterspecs) } free_filter_chain(filters); } - if (PyErr_Occurred() || catch_lzma_error(lzret)) + if (PyErr_Occurred() || catch_lzma_error(state, lzret)) { return -1; - else + } + else { return 0; + } } static int -Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) +Compressor_init_raw(_lzma_state *state, lzma_stream *lzs, PyObject *filterspecs) { lzma_filter filters[LZMA_FILTERS_MAX + 1]; lzma_ret lzret; @@ -655,14 +719,17 @@ Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) "Must specify filters for FORMAT_RAW"); return -1; } - if (parse_filter_chain_spec(filters, filterspecs) == -1) + if (parse_filter_chain_spec(state, filters, filterspecs) == -1) { return -1; + } lzret = lzma_raw_encoder(lzs, filters); free_filter_chain(filters); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { return -1; - else + } + else { return 0; + } } /*[-clinic input] @@ -706,12 +773,14 @@ 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)); + assert(state != NULL); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiOO:LZMACompressor", arg_names, &format, &check, &preset_obj, - &filterspecs)) + &filterspecs)) { return -1; + } if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) { PyErr_SetString(PyExc_ValueError, @@ -725,9 +794,11 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) return -1; } - if (preset_obj != Py_None) - if (!uint32_converter(preset_obj, &preset)) + if (preset_obj != Py_None) { + if (!uint32_converter(preset_obj, &preset)) { return -1; + } + } self->alloc.opaque = NULL; self->alloc.alloc = PyLzma_Malloc; @@ -743,20 +814,24 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) self->flushed = 0; switch (format) { case FORMAT_XZ: - if (check == -1) + if (check == -1) { check = LZMA_CHECK_CRC64; - if (Compressor_init_xz(&self->lzs, check, preset, filterspecs) != 0) + } + if (Compressor_init_xz(state, &self->lzs, check, preset, filterspecs) != 0) { break; + } return 0; case FORMAT_ALONE: - if (Compressor_init_alone(&self->lzs, preset, filterspecs) != 0) + if (Compressor_init_alone(state, &self->lzs, preset, filterspecs) != 0) { break; + } return 0; case FORMAT_RAW: - if (Compressor_init_raw(&self->lzs, filterspecs) != 0) + if (Compressor_init_raw(state, &self->lzs, filterspecs) != 0) { break; + } return 0; default: @@ -774,9 +849,12 @@ static void Compressor_dealloc(Compressor *self) { lzma_end(&self->lzs); - if (self->lock != NULL) + if (self->lock != NULL) { PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + } + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static PyMethodDef Compressor_methods[] = { @@ -785,6 +863,13 @@ static PyMethodDef Compressor_methods[] = { {NULL} }; +static int +Compressor_traverse(Compressor *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + PyDoc_STRVAR(Compressor_doc, "LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)\n" "\n" @@ -813,47 +898,26 @@ PyDoc_STRVAR(Compressor_doc, "\n" "For one-shot compression, use the compress() function instead.\n"); -static PyTypeObject Compressor_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lzma.LZMACompressor", /* tp_name */ - sizeof(Compressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)Compressor_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, /* tp_flags */ - Compressor_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Compressor_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 */ - (initproc)Compressor_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ +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_doc, (char *)Compressor_doc}, + {Py_tp_traverse, Compressor_traverse}, + {0, 0} }; +static PyType_Spec lzma_compressor_type_spec = { + .name = "_lzma.LZMACompressor", + .basicsize = sizeof(Compressor), + // Calling PyType_GetModuleState() on a subclass is not safe. + // lzma_compressor_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 = lzma_compressor_type_slots, +}; /* LZMADecompressor class. */ @@ -864,34 +928,32 @@ static PyTypeObject Compressor_type = { static PyObject* decompress_buf(Decompressor *d, Py_ssize_t max_length) { - Py_ssize_t data_size = 0; PyObject *result; lzma_stream *lzs = &d->lzs; + _BlocksOutputBuffer buffer = {.list = NULL}; + _lzma_state *state = PyType_GetModuleState(Py_TYPE(d)); + assert(state != NULL); - if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - else - result = PyBytes_FromStringAndSize(NULL, max_length); - if (result == NULL) - return NULL; - - lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result); - lzs->avail_out = PyBytes_GET_SIZE(result); + if (OutputBuffer_InitAndGrow(&buffer, max_length, &lzs->next_out, &lzs->avail_out) < 0) { + goto error; + } for (;;) { lzma_ret lzret; Py_BEGIN_ALLOW_THREADS lzret = lzma_code(lzs, LZMA_RUN); - data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result); - if (lzret == LZMA_BUF_ERROR && lzs->avail_in == 0 && lzs->avail_out > 0) - lzret = LZMA_OK; /* That wasn't a real error */ Py_END_ALLOW_THREADS - if (catch_lzma_error(lzret)) + if (lzret == LZMA_BUF_ERROR && lzs->avail_in == 0 && lzs->avail_out > 0) { + lzret = LZMA_OK; /* That wasn't a real error */ + } + if (catch_lzma_error(state, lzret)) { goto error; - if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK) + } + if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK) { d->check = lzma_get_check(&d->lzs); + } if (lzret == LZMA_STREAM_END) { d->eof = 1; break; @@ -900,24 +962,24 @@ decompress_buf(Decompressor *d, Py_ssize_t max_length) Maybe lzs's internal state still have a few bytes can be output, grow the output buffer and continue if max_lengh < 0. */ - if (data_size == max_length) + if (OutputBuffer_GetDataSize(&buffer, lzs->avail_out) == max_length) { break; - if (grow_buffer(&result, max_length) == -1) + } + if (OutputBuffer_Grow(&buffer, &lzs->next_out, &lzs->avail_out) < 0) { goto error; - lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; - lzs->avail_out = PyBytes_GET_SIZE(result) - data_size; + } } else if (lzs->avail_in == 0) { break; } } - if (data_size != PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) == -1) - goto error; - return result; + result = OutputBuffer_Finish(&buffer, lzs->avail_out); + if (result != NULL) { + return result; + } error: - Py_XDECREF(result); + OutputBuffer_OnError(&buffer); return NULL; } @@ -984,8 +1046,9 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) if (lzs->avail_in > 0) { Py_XSETREF(d->unused_data, PyBytes_FromStringAndSize((char *)lzs->next_in, lzs->avail_in)); - if (d->unused_data == NULL) + if (d->unused_data == NULL) { goto error; + } } } else if (lzs->avail_in == 0) { @@ -997,7 +1060,7 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) be output, try to output them next time. */ d->needs_input = 0; - /* if max_length < 0, lzs->avail_out always > 0 */ + /* If max_length < 0, lzs->avail_out always > 0 */ assert(max_length >= 0); } else { /* Input buffer exhausted, output buffer has space. */ @@ -1082,19 +1145,22 @@ _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, } static int -Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) +Decompressor_init_raw(_lzma_state *state, lzma_stream *lzs, PyObject *filterspecs) { lzma_filter filters[LZMA_FILTERS_MAX + 1]; lzma_ret lzret; - if (parse_filter_chain_spec(filters, filterspecs) == -1) + if (parse_filter_chain_spec(state, filters, filterspecs) == -1) { return -1; + } lzret = lzma_raw_decoder(lzs, filters); free_filter_chain(filters); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { return -1; - else + } + else { return 0; + } } /*[clinic input] @@ -1130,6 +1196,8 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format, 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)); + assert(state != NULL); if (memlimit != Py_None) { if (format == FORMAT_RAW) { @@ -1138,8 +1206,9 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format, return -1; } memlimit_ = PyLong_AsUnsignedLongLong(memlimit); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { return -1; + } } if (format == FORMAT_RAW && filters == Py_None) { @@ -1173,33 +1242,38 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format, self->input_buffer = NULL; self->input_buffer_size = 0; Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0)); - if (self->unused_data == NULL) + if (self->unused_data == NULL) { goto error; + } switch (format) { case FORMAT_AUTO: lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { break; + } return 0; case FORMAT_XZ: lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { break; + } return 0; case FORMAT_ALONE: self->check = LZMA_CHECK_NONE; lzret = lzma_alone_decoder(&self->lzs, memlimit_); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { break; + } return 0; case FORMAT_RAW: self->check = LZMA_CHECK_NONE; - if (Decompressor_init_raw(&self->lzs, filters) == -1) + if (Decompressor_init_raw(state, &self->lzs, filters) == -1) { break; + } return 0; default: @@ -1223,9 +1297,19 @@ Decompressor_dealloc(Decompressor *self) lzma_end(&self->lzs); Py_CLEAR(self->unused_data); - if (self->lock != NULL) + if (self->lock != NULL) { PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + } + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); +} + +static int +Decompressor_traverse(Decompressor *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; } static PyMethodDef Decompressor_methods[] = { @@ -1257,45 +1341,26 @@ static PyMemberDef Decompressor_members[] = { {NULL} }; -static PyTypeObject Decompressor_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lzma.LZMADecompressor", /* tp_name */ - sizeof(Decompressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)Decompressor_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, /* tp_flags */ - _lzma_LZMADecompressor___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Decompressor_methods, /* tp_methods */ - Decompressor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _lzma_LZMADecompressor___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ +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_traverse, Decompressor_traverse}, + {Py_tp_members, Decompressor_members}, + {0, 0} +}; + +static PyType_Spec lzma_decompressor_type_spec = { + .name = "_lzma.LZMADecompressor", + .basicsize = sizeof(Decompressor), + // Calling PyType_GetModuleState() on a subclass is not safe. + // lzma_decompressor_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 = lzma_decompressor_type_slots, }; @@ -1318,27 +1383,52 @@ _lzma_is_check_supported_impl(PyObject *module, int check_id) return PyBool_FromLong(lzma_check_is_supported(check_id)); } +PyDoc_STRVAR(_lzma__encode_filter_properties__doc__, +"_encode_filter_properties($module, filter, /)\n" +"--\n" +"\n" +"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" +"\n" +"The result does not include the filter ID itself, only the options."); -/*[clinic input] -_lzma._encode_filter_properties - filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}") - / +#define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF \ + {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_O, _lzma__encode_filter_properties__doc__}, -Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict). +static PyObject * +_lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter); -The result does not include the filter ID itself, only the options. -[clinic start generated code]*/ +static PyObject * +_lzma__encode_filter_properties(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL}; + _lzma_state *state = get_lzma_state(module); + assert(state != NULL); + if (!lzma_filter_converter(state, arg, &filter)) { + goto exit; + } + return_value = _lzma__encode_filter_properties_impl(module, filter); + +exit: + /* Cleanup for filter */ + if (filter.id != LZMA_VLI_UNKNOWN) { + PyMem_Free(filter.options); + } + + return return_value; +} static PyObject * _lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter) -/*[clinic end generated code: output=5c93c8e14e7be5a8 input=d4c64f1b557c77d4]*/ { lzma_ret lzret; uint32_t encoded_size; PyObject *result = NULL; + _lzma_state *state = get_lzma_state(module); + assert(state != NULL); lzret = lzma_properties_size(&encoded_size, &filter); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) goto error; result = PyBytes_FromStringAndSize(NULL, encoded_size); @@ -1347,8 +1437,9 @@ _lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter) lzret = lzma_properties_encode( &filter, (uint8_t *)PyBytes_AS_STRING(result)); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { goto error; + } return result; @@ -1378,11 +1469,14 @@ _lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, lzma_ret lzret; PyObject *result = NULL; filter.id = filter_id; + _lzma_state *state = get_lzma_state(module); + assert(state != NULL); lzret = lzma_properties_decode( &filter, NULL, encoded_props->buf, encoded_props->len); - if (catch_lzma_error(lzret)) + if (catch_lzma_error(state, lzret)) { return NULL; + } result = build_filter_spec(&filter); @@ -1392,103 +1486,162 @@ _lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, return result; } - -/* Module initialization. */ - -static PyMethodDef module_methods[] = { - _LZMA_IS_CHECK_SUPPORTED_METHODDEF - _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF - _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF - {NULL} -}; - -static PyModuleDef _lzmamodule = { - PyModuleDef_HEAD_INIT, - "_lzma", - NULL, - -1, - module_methods, - NULL, - NULL, - NULL, - NULL, -}; - /* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant would not work correctly on platforms with 32-bit longs. */ static int module_add_int_constant(PyObject *m, const char *name, long long value) { PyObject *o = PyLong_FromLongLong(value); - if (o == NULL) + if (o == NULL) { return -1; - if (PyModule_AddObject(m, name, o) == 0) + } + if (PyModule_AddObject(m, name, o) == 0) { return 0; + } Py_DECREF(o); return -1; } -#define ADD_INT_PREFIX_MACRO(m, macro) \ - module_add_int_constant(m, #macro, LZMA_ ## macro) - -PyMODINIT_FUNC -PyInit__lzma(void) +static int +lzma_exec(PyObject *module) { - PyObject *m; +#define ADD_INT_PREFIX_MACRO(module, macro) \ + do { \ + if (module_add_int_constant(module, #macro, LZMA_ ## macro) < 0) { \ + return -1; \ + } \ + } while(0) + +#define ADD_INT_MACRO(module, macro) \ + do { \ + if (PyModule_AddIntMacro(module, macro) < 0) { \ + return -1; \ + } \ + } while (0) - empty_tuple = PyTuple_New(0); - if (empty_tuple == NULL) - return NULL; - m = PyModule_Create(&_lzmamodule); - if (m == NULL) - return NULL; + _lzma_state *state = get_lzma_state(module); - if (PyModule_AddIntMacro(m, FORMAT_AUTO) == -1 || - PyModule_AddIntMacro(m, FORMAT_XZ) == -1 || - PyModule_AddIntMacro(m, FORMAT_ALONE) == -1 || - PyModule_AddIntMacro(m, FORMAT_RAW) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_NONE) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_CRC32) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_CRC64) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_SHA256) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_ID_MAX) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_UNKNOWN) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_LZMA1) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_LZMA2) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_DELTA) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_X86) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_IA64) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_ARM) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_ARMTHUMB) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_SPARC) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_POWERPC) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_HC3) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_HC4) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_BT2) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_BT3) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_BT4) == -1 || - ADD_INT_PREFIX_MACRO(m, MODE_FAST) == -1 || - ADD_INT_PREFIX_MACRO(m, MODE_NORMAL) == -1 || - ADD_INT_PREFIX_MACRO(m, PRESET_DEFAULT) == -1 || - ADD_INT_PREFIX_MACRO(m, PRESET_EXTREME) == -1) - return NULL; + state->empty_tuple = PyTuple_New(0); + if (state->empty_tuple == NULL) { + return -1; + } - Error = PyErr_NewExceptionWithDoc( - "_lzma.LZMAError", "Call to liblzma failed.", NULL, NULL); - if (Error == NULL) - return NULL; - Py_INCREF(Error); - if (PyModule_AddObject(m, "LZMAError", Error) == -1) - return NULL; + ADD_INT_MACRO(module, FORMAT_AUTO); + ADD_INT_MACRO(module, FORMAT_XZ); + ADD_INT_MACRO(module, FORMAT_ALONE); + ADD_INT_MACRO(module, FORMAT_RAW); + ADD_INT_PREFIX_MACRO(module, CHECK_NONE); + ADD_INT_PREFIX_MACRO(module, CHECK_CRC32); + ADD_INT_PREFIX_MACRO(module, CHECK_CRC64); + ADD_INT_PREFIX_MACRO(module, CHECK_SHA256); + ADD_INT_PREFIX_MACRO(module, CHECK_ID_MAX); + ADD_INT_PREFIX_MACRO(module, CHECK_UNKNOWN); + ADD_INT_PREFIX_MACRO(module, FILTER_LZMA1); + ADD_INT_PREFIX_MACRO(module, FILTER_LZMA2); + ADD_INT_PREFIX_MACRO(module, FILTER_DELTA); + ADD_INT_PREFIX_MACRO(module, FILTER_X86); + ADD_INT_PREFIX_MACRO(module, FILTER_IA64); + ADD_INT_PREFIX_MACRO(module, FILTER_ARM); + ADD_INT_PREFIX_MACRO(module, FILTER_ARMTHUMB); + ADD_INT_PREFIX_MACRO(module, FILTER_SPARC); + ADD_INT_PREFIX_MACRO(module, FILTER_POWERPC); + ADD_INT_PREFIX_MACRO(module, MF_HC3); + ADD_INT_PREFIX_MACRO(module, MF_HC4); + ADD_INT_PREFIX_MACRO(module, MF_BT2); + ADD_INT_PREFIX_MACRO(module, MF_BT3); + ADD_INT_PREFIX_MACRO(module, MF_BT4); + ADD_INT_PREFIX_MACRO(module, MODE_FAST); + ADD_INT_PREFIX_MACRO(module, MODE_NORMAL); + ADD_INT_PREFIX_MACRO(module, PRESET_DEFAULT); + ADD_INT_PREFIX_MACRO(module, PRESET_EXTREME); + + state->error = PyErr_NewExceptionWithDoc("_lzma.LZMAError", "Call to liblzma failed.", NULL, NULL); + if (state->error == NULL) { + return -1; + } - if (PyModule_AddType(m, &Compressor_type) < 0) { - return NULL; + if (PyModule_AddType(module, (PyTypeObject *)state->error) < 0) { + return -1; } - if (PyModule_AddType(m, &Decompressor_type) < 0) { - return NULL; + + state->lzma_compressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, + &lzma_compressor_type_spec, NULL); + if (state->lzma_compressor_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, state->lzma_compressor_type) < 0) { + return -1; + } + + state->lzma_decompressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, + &lzma_decompressor_type_spec, NULL); + if (state->lzma_decompressor_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, state->lzma_decompressor_type) < 0) { + return -1; } - return m; + return 0; +} + +static PyMethodDef lzma_methods[] = { + _LZMA_IS_CHECK_SUPPORTED_METHODDEF + _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF + _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF + {NULL} +}; + +static PyModuleDef_Slot lzma_slots[] = { + {Py_mod_exec, lzma_exec}, + {0, NULL} +}; + +static int +lzma_traverse(PyObject *module, visitproc visit, void *arg) +{ + _lzma_state *state = get_lzma_state(module); + Py_VISIT(state->lzma_compressor_type); + Py_VISIT(state->lzma_decompressor_type); + Py_VISIT(state->error); + Py_VISIT(state->empty_tuple); + return 0; +} + +static int +lzma_clear(PyObject *module) +{ + _lzma_state *state = get_lzma_state(module); + Py_CLEAR(state->lzma_compressor_type); + Py_CLEAR(state->lzma_decompressor_type); + Py_CLEAR(state->error); + Py_CLEAR(state->empty_tuple); + return 0; +} + +static void +lzma_free(void *module) +{ + lzma_clear((PyObject *)module); +} + +static PyModuleDef _lzmamodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_lzma", + .m_size = sizeof(_lzma_state), + .m_methods = lzma_methods, + .m_slots = lzma_slots, + .m_traverse = lzma_traverse, + .m_clear = lzma_clear, + .m_free = lzma_free, +}; + +PyMODINIT_FUNC +PyInit__lzma(void) +{ + return PyModuleDef_Init(&_lzmamodule); } diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/clinic/multiprocessing.c.h b/contrib/tools/python3/src/Modules/_multiprocessing/clinic/multiprocessing.c.h new file mode 100644 index 00000000000..7096442bd0b --- /dev/null +++ b/contrib/tools/python3/src/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -0,0 +1,151 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_closesocket__doc__, +"closesocket($module, handle, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_CLOSESOCKET_METHODDEF \ + {"closesocket", (PyCFunction)_multiprocessing_closesocket, METH_O, _multiprocessing_closesocket__doc__}, + +static PyObject * +_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle); + +static PyObject * +_multiprocessing_closesocket(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE handle; + + if (!PyArg_Parse(arg, ""F_HANDLE":closesocket", &handle)) { + goto exit; + } + return_value = _multiprocessing_closesocket_impl(module, handle); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_recv__doc__, +"recv($module, handle, size, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_RECV_METHODDEF \ + {"recv", (PyCFunction)(void(*)(void))_multiprocessing_recv, METH_FASTCALL, _multiprocessing_recv__doc__}, + +static PyObject * +_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size); + +static PyObject * +_multiprocessing_recv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + int size; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:recv", + &handle, &size)) { + goto exit; + } + return_value = _multiprocessing_recv_impl(module, handle, size); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_send__doc__, +"send($module, handle, buf, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEND_METHODDEF \ + {"send", (PyCFunction)(void(*)(void))_multiprocessing_send, METH_FASTCALL, _multiprocessing_send__doc__}, + +static PyObject * +_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf); + +static PyObject * +_multiprocessing_send(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + Py_buffer buf = {NULL, NULL}; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:send", + &handle, &buf)) { + goto exit; + } + return_value = _multiprocessing_send_impl(module, handle, &buf); + +exit: + /* Cleanup for buf */ + if (buf.obj) { + PyBuffer_Release(&buf); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +PyDoc_STRVAR(_multiprocessing_sem_unlink__doc__, +"sem_unlink($module, name, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEM_UNLINK_METHODDEF \ + {"sem_unlink", (PyCFunction)_multiprocessing_sem_unlink, METH_O, _multiprocessing_sem_unlink__doc__}, + +static PyObject * +_multiprocessing_sem_unlink_impl(PyObject *module, const char *name); + +static PyObject * +_multiprocessing_sem_unlink(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("sem_unlink", "argument", "str", arg); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(arg, &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _multiprocessing_sem_unlink_impl(module, name); + +exit: + return return_value; +} + +#ifndef _MULTIPROCESSING_CLOSESOCKET_METHODDEF + #define _MULTIPROCESSING_CLOSESOCKET_METHODDEF +#endif /* !defined(_MULTIPROCESSING_CLOSESOCKET_METHODDEF) */ + +#ifndef _MULTIPROCESSING_RECV_METHODDEF + #define _MULTIPROCESSING_RECV_METHODDEF +#endif /* !defined(_MULTIPROCESSING_RECV_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEND_METHODDEF + #define _MULTIPROCESSING_SEND_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEND_METHODDEF) */ +/*[clinic end generated code: output=418191c446cd5751 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/clinic/posixshmem.c.h b/contrib/tools/python3/src/Modules/_multiprocessing/clinic/posixshmem.c.h index a99f0d2aae1..3424b10a569 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/contrib/tools/python3/src/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -42,11 +42,6 @@ _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto exit; } path = args[0]; - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -54,11 +49,6 @@ _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -130,4 +120,4 @@ exit: #ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF #define _POSIXSHMEM_SHM_UNLINK_METHODDEF #endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ -/*[clinic end generated code: output=9132861c61d8c2d8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bca8e78d0f43ef1a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/clinic/semaphore.c.h b/contrib/tools/python3/src/Modules/_multiprocessing/clinic/semaphore.c.h new file mode 100644 index 00000000000..e1b9309e9f2 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_multiprocessing/clinic/semaphore.c.h @@ -0,0 +1,402 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, +"acquire($self, /, block=True, timeout=None)\n" +"--\n" +"\n" +"Acquire the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ + {"acquire", (PyCFunction)(void(*)(void))_multiprocessing_SemLock_acquire, METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj); + +static PyObject * +_multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"block", "timeout", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int blocking = 1; + PyObject *timeout_obj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + blocking = _PyLong_AsInt(args[0]); + if (blocking == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout_obj = args[1]; +skip_optional_pos: + return_value = _multiprocessing_SemLock_acquire_impl(self, blocking, timeout_obj); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, +"release($self, /)\n" +"--\n" +"\n" +"Release the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF \ + {"release", (PyCFunction)_multiprocessing_SemLock_release, METH_NOARGS, _multiprocessing_SemLock_release__doc__}, + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock_release_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if !defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, +"acquire($self, /, block=True, timeout=None)\n" +"--\n" +"\n" +"Acquire the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ + {"acquire", (PyCFunction)(void(*)(void))_multiprocessing_SemLock_acquire, METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj); + +static PyObject * +_multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"block", "timeout", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int blocking = 1; + PyObject *timeout_obj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + blocking = _PyLong_AsInt(args[0]); + if (blocking == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout_obj = args[1]; +skip_optional_pos: + return_value = _multiprocessing_SemLock_acquire_impl(self, blocking, timeout_obj); + +exit: + return return_value; +} + +#endif /* !defined(MS_WINDOWS) */ + +#if !defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, +"release($self, /)\n" +"--\n" +"\n" +"Release the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF \ + {"release", (PyCFunction)_multiprocessing_SemLock_release, METH_NOARGS, _multiprocessing_SemLock_release__doc__}, + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock_release_impl(self); +} + +#endif /* !defined(MS_WINDOWS) */ + +static PyObject * +_multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, + int maxvalue, const char *name, int unlink); + +static PyObject * +_multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"kind", "value", "maxvalue", "name", "unlink", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "SemLock", 0}; + PyObject *argsbuf[5]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + int kind; + int value; + int maxvalue; + const char *name; + int unlink; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 5, 5, 0, argsbuf); + if (!fastargs) { + goto exit; + } + kind = _PyLong_AsInt(fastargs[0]); + if (kind == -1 && PyErr_Occurred()) { + goto exit; + } + value = _PyLong_AsInt(fastargs[1]); + if (value == -1 && PyErr_Occurred()) { + goto exit; + } + maxvalue = _PyLong_AsInt(fastargs[2]); + if (maxvalue == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(fastargs[3])) { + _PyArg_BadArgument("SemLock", "argument 'name'", "str", fastargs[3]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(fastargs[3], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + unlink = _PyLong_AsInt(fastargs[4]); + if (unlink == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _multiprocessing_SemLock_impl(type, kind, value, maxvalue, name, unlink); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multiprocessing_SemLock__rebuild__doc__, +"_rebuild($type, handle, kind, maxvalue, name, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF \ + {"_rebuild", (PyCFunction)(void(*)(void))_multiprocessing_SemLock__rebuild, METH_FASTCALL|METH_CLASS, _multiprocessing_SemLock__rebuild__doc__}, + +static PyObject * +_multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, + int kind, int maxvalue, + const char *name); + +static PyObject * +_multiprocessing_SemLock__rebuild(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + SEM_HANDLE handle; + int kind; + int maxvalue; + const char *name; + + if (!_PyArg_ParseStack(args, nargs, ""F_SEM_HANDLE"iiz:_rebuild", + &handle, &kind, &maxvalue, &name)) { + goto exit; + } + return_value = _multiprocessing_SemLock__rebuild_impl(type, handle, kind, maxvalue, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multiprocessing_SemLock__count__doc__, +"_count($self, /)\n" +"--\n" +"\n" +"Num of `acquire()`s minus num of `release()`s for this process."); + +#define _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF \ + {"_count", (PyCFunction)_multiprocessing_SemLock__count, METH_NOARGS, _multiprocessing_SemLock__count__doc__}, + +static PyObject * +_multiprocessing_SemLock__count_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__count(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__count_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__is_mine__doc__, +"_is_mine($self, /)\n" +"--\n" +"\n" +"Whether the lock is owned by this thread."); + +#define _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF \ + {"_is_mine", (PyCFunction)_multiprocessing_SemLock__is_mine, METH_NOARGS, _multiprocessing_SemLock__is_mine__doc__}, + +static PyObject * +_multiprocessing_SemLock__is_mine_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__is_mine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__is_mine_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__get_value__doc__, +"_get_value($self, /)\n" +"--\n" +"\n" +"Get the value of the semaphore."); + +#define _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF \ + {"_get_value", (PyCFunction)_multiprocessing_SemLock__get_value, METH_NOARGS, _multiprocessing_SemLock__get_value__doc__}, + +static PyObject * +_multiprocessing_SemLock__get_value_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__get_value(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__get_value_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__is_zero__doc__, +"_is_zero($self, /)\n" +"--\n" +"\n" +"Return whether semaphore has value zero."); + +#define _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF \ + {"_is_zero", (PyCFunction)_multiprocessing_SemLock__is_zero, METH_NOARGS, _multiprocessing_SemLock__is_zero__doc__}, + +static PyObject * +_multiprocessing_SemLock__is_zero_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__is_zero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__is_zero_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__after_fork__doc__, +"_after_fork($self, /)\n" +"--\n" +"\n" +"Rezero the net acquisition count after fork()."); + +#define _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF \ + {"_after_fork", (PyCFunction)_multiprocessing_SemLock__after_fork, METH_NOARGS, _multiprocessing_SemLock__after_fork__doc__}, + +static PyObject * +_multiprocessing_SemLock__after_fork_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__after_fork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__after_fork_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock___enter____doc__, +"__enter__($self, /)\n" +"--\n" +"\n" +"Enter the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)_multiprocessing_SemLock___enter__, METH_NOARGS, _multiprocessing_SemLock___enter____doc__}, + +static PyObject * +_multiprocessing_SemLock___enter___impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock___enter__(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock___enter___impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock___exit____doc__, +"__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" +"--\n" +"\n" +"Exit the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)(void(*)(void))_multiprocessing_SemLock___exit__, METH_FASTCALL, _multiprocessing_SemLock___exit____doc__}, + +static PyObject * +_multiprocessing_SemLock___exit___impl(SemLockObject *self, + PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +_multiprocessing_SemLock___exit__(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc_type = Py_None; + PyObject *exc_value = Py_None; + PyObject *exc_tb = Py_None; + + if (!_PyArg_CheckPositional("__exit__", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + exc_type = args[0]; + if (nargs < 2) { + goto skip_optional; + } + exc_value = args[1]; + if (nargs < 3) { + goto skip_optional; + } + exc_tb = args[2]; +skip_optional: + return_value = _multiprocessing_SemLock___exit___impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#ifndef _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF) */ +/*[clinic end generated code: output=e7fd938150601fe5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c index 806e638340f..bec23517fca 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c +++ b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c @@ -9,6 +9,20 @@ #include "multiprocessing.h" +/*[python input] +class HANDLE_converter(CConverter): + type = "HANDLE" + format_unit = '"F_HANDLE"' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/ + +/*[clinic input] +module _multiprocessing +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/ + +#include "clinic/multiprocessing.c.h" /* * Function which raises exceptions based on error codes @@ -50,15 +64,20 @@ _PyMp_SetError(PyObject *Type, int num) } #ifdef MS_WINDOWS +/*[clinic input] +_multiprocessing.closesocket + + handle: HANDLE + / + +[clinic start generated code]*/ + static PyObject * -multiprocessing_closesocket(PyObject *self, PyObject *args) +_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle) +/*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/ { - HANDLE handle; int ret; - if (!PyArg_ParseTuple(args, F_HANDLE ":closesocket" , &handle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = closesocket((SOCKET) handle); Py_END_ALLOW_THREADS @@ -68,16 +87,22 @@ multiprocessing_closesocket(PyObject *self, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_multiprocessing.recv + + handle: HANDLE + size: int + / + +[clinic start generated code]*/ + static PyObject * -multiprocessing_recv(PyObject *self, PyObject *args) +_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size) +/*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/ { - HANDLE handle; - int size, nread; + int nread; PyObject *buf; - if (!PyArg_ParseTuple(args, F_HANDLE "i:recv" , &handle, &size)) - return NULL; - buf = PyBytes_FromStringAndSize(NULL, size); if (!buf) return NULL; @@ -94,23 +119,27 @@ multiprocessing_recv(PyObject *self, PyObject *args) return buf; } +/*[clinic input] +_multiprocessing.send + + handle: HANDLE + buf: Py_buffer + / + +[clinic start generated code]*/ + static PyObject * -multiprocessing_send(PyObject *self, PyObject *args) +_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf) +/*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/ { - HANDLE handle; - Py_buffer buf; int ret, length; - if (!PyArg_ParseTuple(args, F_HANDLE "y*:send" , &handle, &buf)) - return NULL; - - length = (int)Py_MIN(buf.len, INT_MAX); + length = (int)Py_MIN(buf->len, INT_MAX); Py_BEGIN_ALLOW_THREADS - ret = send((SOCKET) handle, buf.buf, length, 0); + ret = send((SOCKET) handle, buf->buf, length, 0); Py_END_ALLOW_THREADS - PyBuffer_Release(&buf); if (ret < 0) return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); return PyLong_FromLong(ret); @@ -118,18 +147,33 @@ multiprocessing_send(PyObject *self, PyObject *args) #endif +/*[clinic input] +_multiprocessing.sem_unlink + + name: str + / + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_sem_unlink_impl(PyObject *module, const char *name) +/*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/ +{ + return _PyMp_sem_unlink(name); +} + /* * Function table */ static PyMethodDef module_methods[] = { #ifdef MS_WINDOWS - {"closesocket", multiprocessing_closesocket, METH_VARARGS, ""}, - {"recv", multiprocessing_recv, METH_VARARGS, ""}, - {"send", multiprocessing_send, METH_VARARGS, ""}, + _MULTIPROCESSING_CLOSESOCKET_METHODDEF + _MULTIPROCESSING_RECV_METHODDEF + _MULTIPROCESSING_SEND_METHODDEF #endif #if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) - {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""}, + _MULTIPROCESSING_SEM_UNLINK_METHODDEF #endif {NULL} }; @@ -139,35 +183,17 @@ static PyMethodDef module_methods[] = { * Initialize */ -static struct PyModuleDef multiprocessing_module = { - PyModuleDef_HEAD_INIT, - "_multiprocessing", - NULL, - -1, - module_methods, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit__multiprocessing(void) +static int +multiprocessing_exec(PyObject *module) { - PyObject *module, *temp, *value = NULL; - - /* Initialize module */ - module = PyModule_Create(&multiprocessing_module); - if (!module) - return NULL; - #if defined(MS_WINDOWS) || \ (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) + /* Add _PyMp_SemLock type to module */ - if (PyType_Ready(&_PyMp_SemLockType) < 0) - return NULL; - Py_INCREF(&_PyMp_SemLockType); + if (PyModule_AddType(module, &_PyMp_SemLockType) < 0) { + return -1; + } + { PyObject *py_sem_value_max; /* Some systems define SEM_VALUE_MAX as an unsigned value that @@ -179,25 +205,40 @@ PyInit__multiprocessing(void) 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 NULL; - PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", - py_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; + } + Py_DECREF(py_sem_value_max); } - PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType); + #endif /* Add configuration macros */ - temp = PyDict_New(); - if (!temp) - return NULL; + PyObject *flags = PyDict_New(); + if (!flags) { + return -1; + } -#define ADD_FLAG(name) \ - value = Py_BuildValue("i", name); \ - if (value == NULL) { Py_DECREF(temp); return NULL; } \ - if (PyDict_SetItemString(temp, #name, value) < 0) { \ - Py_DECREF(temp); Py_DECREF(value); return NULL; } \ - Py_DECREF(value) +#define ADD_FLAG(name) \ + do { \ + PyObject *value = PyLong_FromLong(name); \ + if (value == NULL) { \ + Py_DECREF(flags); \ + return -1; \ + } \ + if (PyDict_SetItemString(flags, #name, value) < 0) { \ + Py_DECREF(flags); \ + Py_DECREF(value); \ + return -1; \ + } \ + Py_DECREF(value); \ + } while (0) #if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) ADD_FLAG(HAVE_SEM_OPEN); @@ -212,8 +253,28 @@ PyInit__multiprocessing(void) ADD_FLAG(HAVE_BROKEN_SEM_UNLINK); #endif - if (PyModule_AddObject(module, "flags", temp) < 0) - return NULL; + if (PyModule_AddObject(module, "flags", flags) < 0) { + Py_DECREF(flags); + return -1; + } + + return 0; +} + +static PyModuleDef_Slot multiprocessing_slots[] = { + {Py_mod_exec, multiprocessing_exec}, + {0, NULL} +}; - return module; +static struct PyModuleDef multiprocessing_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_multiprocessing", + .m_methods = module_methods, + .m_slots = multiprocessing_slots, +}; + +PyMODINIT_FUNC +PyInit__multiprocessing(void) +{ + return PyModuleDef_Init(&multiprocessing_module); } diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h index fe78135d466..277963bc157 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h +++ b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h @@ -88,6 +88,6 @@ PyObject *_PyMp_SetError(PyObject *Type, int num); */ extern PyTypeObject _PyMp_SemLockType; -extern PyObject *_PyMp_sem_unlink(PyObject *ignore, PyObject *args); +extern PyObject *_PyMp_sem_unlink(const char *name); #endif /* MULTIPROCESSING_H */ diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/posixshmem.c b/contrib/tools/python3/src/Modules/_multiprocessing/posixshmem.c index 436ac6d6b39..d64ded41682 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/posixshmem.c +++ b/contrib/tools/python3/src/Modules/_multiprocessing/posixshmem.c @@ -110,21 +110,17 @@ static PyMethodDef module_methods[ ] = { }; -static struct PyModuleDef this_module = { - PyModuleDef_HEAD_INIT, // m_base - "_posixshmem", // m_name - "POSIX shared memory module", // m_doc - -1, // m_size (space allocated for module globals) - module_methods, // m_methods +static struct PyModuleDef _posixshmemmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_posixshmem", + .m_doc = "POSIX shared memory module", + .m_size = 0, + .m_methods = module_methods, }; /* Module init function */ PyMODINIT_FUNC -PyInit__posixshmem(void) { - PyObject *module; - module = PyModule_Create(&this_module); - if (!module) { - return NULL; - } - return module; +PyInit__posixshmem(void) +{ + return PyModuleDef_Init(&_posixshmemmodule); } diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c b/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c index ee490256d2a..9a2d1f85c92 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c +++ b/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c @@ -21,6 +21,22 @@ typedef struct { char *name; } SemLockObject; +/*[python input] +class SEM_HANDLE_converter(CConverter): + type = "SEM_HANDLE" + format_unit = '"F_SEM_HANDLE"' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3e0ad43e482d8716]*/ + +/*[clinic input] +module _multiprocessing +class _multiprocessing.SemLock "SemLockObject *" "&_PyMp_SemLockType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=935fb41b7d032599]*/ + +#include "clinic/semaphore.c.h" + #define ISMINE(o) (o->count > 0 && PyThread_get_thread_ident() == o->last_tid) @@ -58,21 +74,24 @@ _GetSemaphoreValue(HANDLE handle, long *value) } } +/*[clinic input] +_multiprocessing.SemLock.acquire + + block as blocking: bool(accept={int}) = True + timeout as timeout_obj: object = None + +Acquire the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj) +/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ { - int blocking = 1; double timeout; - PyObject *timeout_obj = Py_None; DWORD res, full_msecs, nhandles; HANDLE handles[2], sigint_event; - static char *kwlist[] = {"block", "timeout", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, - &blocking, &timeout_obj)) - return NULL; - /* calculate timeout */ if (!blocking) { full_msecs = 0; @@ -146,8 +165,15 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) } } +/*[clinic input] +_multiprocessing.SemLock.release + +Release the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_release(SemLockObject *self, PyObject *args) +_multiprocessing_SemLock_release_impl(SemLockObject *self) +/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ { if (self->kind == RECURSIVE_MUTEX) { if (!ISMINE(self)) { @@ -264,19 +290,23 @@ sem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) #endif /* !HAVE_SEM_TIMEDWAIT */ +/*[clinic input] +_multiprocessing.SemLock.acquire + + block as blocking: bool(accept={int}) = True + timeout as timeout_obj: object = None + +Acquire the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj) +/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ { - int blocking = 1, res, err = 0; - PyObject *timeout_obj = Py_None; + int res, err = 0; struct timespec deadline = {0}; - static char *kwlist[] = {"block", "timeout", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, - &blocking, &timeout_obj)) - return NULL; - if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { ++self->count; Py_RETURN_TRUE; @@ -345,8 +375,15 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) Py_RETURN_TRUE; } +/*[clinic input] +_multiprocessing.SemLock.release + +Release the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_release(SemLockObject *self, PyObject *args) +_multiprocessing_SemLock_release_impl(SemLockObject *self) +/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ { if (self->kind == RECURSIVE_MUTEX) { if (!ISMINE(self)) { @@ -429,19 +466,26 @@ newsemlockobject(PyTypeObject *type, SEM_HANDLE handle, int kind, int maxvalue, return (PyObject*)self; } +/*[clinic input] +@classmethod +_multiprocessing.SemLock.__new__ + + kind: int + value: int + maxvalue: int + name: str + unlink: bool(accept={int}) + +[clinic start generated code]*/ + static PyObject * -semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +_multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, + int maxvalue, const char *name, int unlink) +/*[clinic end generated code: output=30727e38f5f7577a input=b378c3ee27d3a0fa]*/ { SEM_HANDLE handle = SEM_FAILED; - int kind, maxvalue, value, unlink; PyObject *result; - char *name, *name_copy = NULL; - static char *kwlist[] = {"kind", "value", "maxvalue", "name", "unlink", - NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiisi", kwlist, - &kind, &value, &maxvalue, &name, &unlink)) - return NULL; + char *name_copy = NULL; if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { PyErr_SetString(PyExc_ValueError, "unrecognized kind"); @@ -481,16 +525,25 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } +/*[clinic input] +@classmethod +_multiprocessing.SemLock._rebuild + + handle: SEM_HANDLE + kind: int + maxvalue: int + name: str(accept={str, NoneType}) + / + +[clinic start generated code]*/ + static PyObject * -semlock_rebuild(PyTypeObject *type, PyObject *args) +_multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, + int kind, int maxvalue, + const char *name) +/*[clinic end generated code: output=2aaee14f063f3bd9 input=f7040492ac6d9962]*/ { - SEM_HANDLE handle; - int kind, maxvalue; - char *name, *name_copy = NULL; - - if (!PyArg_ParseTuple(args, F_SEM_HANDLE "iiz", - &handle, &kind, &maxvalue, &name)) - return NULL; + char *name_copy = NULL; if (name != NULL) { name_copy = PyMem_Malloc(strlen(name) + 1); @@ -518,24 +571,45 @@ semlock_dealloc(SemLockObject* self) if (self->handle != SEM_FAILED) SEM_CLOSE(self->handle); PyMem_Free(self->name); - PyObject_Del(self); + PyObject_Free(self); } +/*[clinic input] +_multiprocessing.SemLock._count + +Num of `acquire()`s minus num of `release()`s for this process. +[clinic start generated code]*/ + static PyObject * -semlock_count(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__count_impl(SemLockObject *self) +/*[clinic end generated code: output=5ba8213900e517bb input=36fc59b1cd1025ab]*/ { return PyLong_FromLong((long)self->count); } +/*[clinic input] +_multiprocessing.SemLock._is_mine + +Whether the lock is owned by this thread. +[clinic start generated code]*/ + static PyObject * -semlock_ismine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__is_mine_impl(SemLockObject *self) +/*[clinic end generated code: output=92dc98863f4303be input=a96664cb2f0093ba]*/ { /* only makes sense for a lock */ return PyBool_FromLong(ISMINE(self)); } +/*[clinic input] +_multiprocessing.SemLock._get_value + +Get the value of the semaphore. +[clinic start generated code]*/ + static PyObject * -semlock_getvalue(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__get_value_impl(SemLockObject *self) +/*[clinic end generated code: output=64bc1b89bda05e36 input=cb10f9a769836203]*/ { #ifdef HAVE_BROKEN_SEM_GETVALUE PyErr_SetNone(PyExc_NotImplementedError); @@ -552,8 +626,15 @@ semlock_getvalue(SemLockObject *self, PyObject *Py_UNUSED(ignored)) #endif } +/*[clinic input] +_multiprocessing.SemLock._is_zero + +Return whether semaphore has value zero. +[clinic start generated code]*/ + static PyObject * -semlock_iszero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__is_zero_impl(SemLockObject *self) +/*[clinic end generated code: output=815d4c878c806ed7 input=294a446418d31347]*/ { #ifdef HAVE_BROKEN_SEM_GETVALUE if (sem_trywait(self->handle) < 0) { @@ -573,38 +654,68 @@ semlock_iszero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) #endif } +/*[clinic input] +_multiprocessing.SemLock._after_fork + +Rezero the net acquisition count after fork(). +[clinic start generated code]*/ + static PyObject * -semlock_afterfork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__after_fork_impl(SemLockObject *self) +/*[clinic end generated code: output=718bb27914c6a6c1 input=190991008a76621e]*/ { self->count = 0; Py_RETURN_NONE; } +/*[clinic input] +_multiprocessing.SemLock.__enter__ + +Enter the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock___enter___impl(SemLockObject *self) +/*[clinic end generated code: output=beeb2f07c858511f input=c5e27d594284690b]*/ +{ + return _multiprocessing_SemLock_acquire_impl(self, 1, Py_None); +} + +/*[clinic input] +_multiprocessing.SemLock.__exit__ + + exc_type: object = None + exc_value: object = None + exc_tb: object = None + / + +Exit the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock___exit___impl(SemLockObject *self, + PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=3b37c1a9f8b91a03 input=7d644b64a89903f8]*/ +{ + return _multiprocessing_SemLock_release_impl(self); +} + /* * Semaphore methods */ static PyMethodDef semlock_methods[] = { - {"acquire", (PyCFunction)(void(*)(void))semlock_acquire, METH_VARARGS | METH_KEYWORDS, - "acquire the semaphore/lock"}, - {"release", (PyCFunction)semlock_release, METH_NOARGS, - "release the semaphore/lock"}, - {"__enter__", (PyCFunction)(void(*)(void))semlock_acquire, METH_VARARGS | METH_KEYWORDS, - "enter the semaphore/lock"}, - {"__exit__", (PyCFunction)semlock_release, METH_VARARGS, - "exit the semaphore/lock"}, - {"_count", (PyCFunction)semlock_count, METH_NOARGS, - "num of `acquire()`s minus num of `release()`s for this process"}, - {"_is_mine", (PyCFunction)semlock_ismine, METH_NOARGS, - "whether the lock is owned by this thread"}, - {"_get_value", (PyCFunction)semlock_getvalue, METH_NOARGS, - "get the value of the semaphore"}, - {"_is_zero", (PyCFunction)semlock_iszero, METH_NOARGS, - "returns whether semaphore has value zero"}, - {"_rebuild", (PyCFunction)semlock_rebuild, METH_VARARGS | METH_CLASS, - ""}, - {"_after_fork", (PyCFunction)semlock_afterfork, METH_NOARGS, - "rezero the net acquisition count after fork()"}, + _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF + _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF + _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF + _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF + _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF + _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF + _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF + _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF + _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF + _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF {NULL} }; @@ -666,7 +777,7 @@ PyTypeObject _PyMp_SemLockType = { /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, - /* tp_new */ semlock_new, + /* tp_new */ _multiprocessing_SemLock, }; /* @@ -674,13 +785,8 @@ PyTypeObject _PyMp_SemLockType = { */ PyObject * -_PyMp_sem_unlink(PyObject *ignore, PyObject *args) +_PyMp_sem_unlink(const char *name) { - char *name; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - if (SEM_UNLINK(name) < 0) { _PyMp_SetError(NULL, MP_STANDARD_ERROR); return NULL; diff --git a/contrib/tools/python3/src/Modules/_opcode.c b/contrib/tools/python3/src/Modules/_opcode.c index 42a8732694a..d8de0762e76 100644 --- a/contrib/tools/python3/src/Modules/_opcode.c +++ b/contrib/tools/python3/src/Modules/_opcode.c @@ -36,8 +36,9 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, return -1; } oparg_int = (int)PyLong_AsLong(oparg); - if ((oparg_int == -1) && PyErr_Occurred()) + if ((oparg_int == -1) && PyErr_Occurred()) { return -1; + } } else if (oparg != Py_None) { PyErr_SetString(PyExc_ValueError, @@ -67,30 +68,22 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, return effect; } - - - static PyMethodDef opcode_functions[] = { _OPCODE_STACK_EFFECT_METHODDEF {NULL, NULL, 0, NULL} }; - static struct PyModuleDef opcodemodule = { PyModuleDef_HEAD_INIT, - "_opcode", - "Opcode support module.", - -1, - opcode_functions, - NULL, - NULL, - NULL, - NULL + .m_name = "_opcode", + .m_doc = "Opcode support module.", + .m_size = 0, + .m_methods = opcode_functions }; PyMODINIT_FUNC PyInit__opcode(void) { - return PyModule_Create(&opcodemodule); + return PyModuleDef_Init(&opcodemodule); } diff --git a/contrib/tools/python3/src/Modules/_operator.c b/contrib/tools/python3/src/Modules/_operator.c index 0136e380d2a..f051513fc79 100644 --- a/contrib/tools/python3/src/Modules/_operator.c +++ b/contrib/tools/python3/src/Modules/_operator.c @@ -1,8 +1,21 @@ - #include "Python.h" - +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "clinic/_operator.c.h" +typedef struct { + PyObject *itemgetter_type; + PyObject *attrgetter_type; + PyObject *methodcaller_type; +} _operator_state; + +static inline _operator_state* +get_operator_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (_operator_state *)state; +} + /*[clinic input] module _operator [clinic start generated code]*/ @@ -942,8 +955,6 @@ typedef struct { Py_ssize_t index; // -1 unless *item* is a single non-negative integer index } itemgetterobject; -static PyTypeObject itemgetter_type; - /* AC 3.5: treats first argument as an iterable, otherwise uses *args */ static PyObject * itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -960,13 +971,15 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (nitems <= 1) { if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item)) return NULL; - } else + } else { item = args; - + } + _operator_state *state = PyType_GetModuleState(type); /* create itemgetterobject structure */ - ig = PyObject_GC_New(itemgetterobject, &itemgetter_type); - if (ig == NULL) + ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type); + if (ig == NULL) { return NULL; + } Py_INCREF(item); ig->item = item; @@ -991,17 +1004,27 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)ig; } +static int +itemgetter_clear(itemgetterobject *ig) +{ + Py_CLEAR(ig->item); + return 0; +} + static void itemgetter_dealloc(itemgetterobject *ig) { + PyTypeObject *tp = Py_TYPE(ig); PyObject_GC_UnTrack(ig); - Py_XDECREF(ig->item); - PyObject_GC_Del(ig); + (void)itemgetter_clear(ig); + tp->tp_free(ig); + Py_DECREF(tp); } static int itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(ig)); Py_VISIT(ig->item); return 0; } @@ -1093,49 +1116,27 @@ 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])"); -static PyTypeObject itemgetter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.itemgetter", /* tp_name */ - sizeof(itemgetterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)itemgetter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)itemgetter_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)itemgetter_call, /* 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 */ - itemgetter_doc, /* tp_doc */ - (traverseproc)itemgetter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - itemgetter_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 */ - itemgetter_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot itemgetter_type_slots[] = { + {Py_tp_doc, (void *)itemgetter_doc}, + {Py_tp_dealloc, itemgetter_dealloc}, + {Py_tp_call, itemgetter_call}, + {Py_tp_traverse, itemgetter_traverse}, + {Py_tp_clear, itemgetter_clear}, + {Py_tp_methods, itemgetter_methods}, + {Py_tp_new, itemgetter_new}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_repr, itemgetter_repr}, + {0, 0} }; +static PyType_Spec itemgetter_type_spec = { + .name = "operator.itemgetter", + .basicsize = sizeof(itemgetterobject), + .itemsize = 0, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = itemgetter_type_slots, +}; /* attrgetter object **********************************************************/ @@ -1145,8 +1146,6 @@ typedef struct { PyObject *attr; } attrgetterobject; -static PyTypeObject attrgetter_type; - /* AC 3.5: treats first argument as an iterable, otherwise uses *args */ static PyObject * attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1246,8 +1245,9 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } + _operator_state *state = PyType_GetModuleState(type); /* create attrgetterobject structure */ - ag = PyObject_GC_New(attrgetterobject, &attrgetter_type); + ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type); if (ag == NULL) { Py_DECREF(attr); return NULL; @@ -1260,18 +1260,28 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)ag; } +static int +attrgetter_clear(attrgetterobject *ag) +{ + Py_CLEAR(ag->attr); + return 0; +} + static void attrgetter_dealloc(attrgetterobject *ag) { + PyTypeObject *tp = Py_TYPE(ag); PyObject_GC_UnTrack(ag); - Py_XDECREF(ag->attr); - PyObject_GC_Del(ag); + (void)attrgetter_clear(ag); + tp->tp_free(ag); + Py_DECREF(tp); } static int attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg) { Py_VISIT(ag->attr); + Py_VISIT(Py_TYPE(ag)); return 0; } @@ -1438,47 +1448,26 @@ After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\ After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\ (r.name.first, r.name.last)."); -static PyTypeObject attrgetter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.attrgetter", /* tp_name */ - sizeof(attrgetterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)attrgetter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)attrgetter_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)attrgetter_call, /* 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 */ - attrgetter_doc, /* tp_doc */ - (traverseproc)attrgetter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - attrgetter_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 */ - attrgetter_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot attrgetter_type_slots[] = { + {Py_tp_doc, (void *)attrgetter_doc}, + {Py_tp_dealloc, attrgetter_dealloc}, + {Py_tp_call, attrgetter_call}, + {Py_tp_traverse, attrgetter_traverse}, + {Py_tp_clear, attrgetter_clear}, + {Py_tp_methods, attrgetter_methods}, + {Py_tp_new, attrgetter_new}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_repr, attrgetter_repr}, + {0, 0} +}; + +static PyType_Spec attrgetter_type_spec = { + .name = "operator.attrgetter", + .basicsize = sizeof(attrgetterobject), + .itemsize = 0, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = attrgetter_type_slots, }; @@ -1491,8 +1480,6 @@ typedef struct { PyObject *kwds; } methodcallerobject; -static PyTypeObject methodcaller_type; - /* AC 3.5: variable number of arguments, not currently support by AC */ static PyObject * methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1513,10 +1500,12 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } + _operator_state *state = PyType_GetModuleState(type); /* create methodcallerobject structure */ - mc = PyObject_GC_New(methodcallerobject, &methodcaller_type); - if (mc == NULL) + mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type); + if (mc == NULL) { return NULL; + } name = PyTuple_GET_ITEM(args, 0); Py_INCREF(name); @@ -1536,21 +1525,32 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)mc; } +static int +methodcaller_clear(methodcallerobject *mc) +{ + Py_CLEAR(mc->name); + Py_CLEAR(mc->args); + Py_CLEAR(mc->kwds); + return 0; +} + static void methodcaller_dealloc(methodcallerobject *mc) { + PyTypeObject *tp = Py_TYPE(mc); PyObject_GC_UnTrack(mc); - Py_XDECREF(mc->name); - Py_XDECREF(mc->args); - Py_XDECREF(mc->kwds); - PyObject_GC_Del(mc); + (void)methodcaller_clear(mc); + tp->tp_free(mc); + Py_DECREF(tp); } static int methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg) { + Py_VISIT(mc->name); Py_VISIT(mc->args); Py_VISIT(mc->kwds); + Py_VISIT(Py_TYPE(mc)); return 0; } @@ -1704,63 +1704,54 @@ 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\ r.name('date', foo=1)."); -static PyTypeObject methodcaller_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.methodcaller", /* tp_name */ - sizeof(methodcallerobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)methodcaller_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)methodcaller_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)methodcaller_call, /* 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 */ - methodcaller_doc, /* tp_doc */ - (traverseproc)methodcaller_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - methodcaller_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 */ - methodcaller_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot methodcaller_type_slots[] = { + {Py_tp_doc, (void *)methodcaller_doc}, + {Py_tp_dealloc, methodcaller_dealloc}, + {Py_tp_call, methodcaller_call}, + {Py_tp_traverse, methodcaller_traverse}, + {Py_tp_clear, methodcaller_clear}, + {Py_tp_methods, methodcaller_methods}, + {Py_tp_new, methodcaller_new}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_repr, methodcaller_repr}, + {0, 0} }; +static PyType_Spec methodcaller_type_spec = { + .name = "operator.methodcaller", + .basicsize = sizeof(methodcallerobject), + .itemsize = 0, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = methodcaller_type_slots, +}; static int operator_exec(PyObject *module) { - PyTypeObject *types[] = { - &itemgetter_type, - &attrgetter_type, - &methodcaller_type - }; + _operator_state *state = get_operator_state(module); + state->attrgetter_type = PyType_FromModuleAndSpec(module, &attrgetter_type_spec, NULL); + if (state->attrgetter_type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)state->attrgetter_type) < 0) { + return -1; + } - for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { - if (PyModule_AddType(module, types[i]) < 0) { - return -1; - } + state->itemgetter_type = PyType_FromModuleAndSpec(module, &itemgetter_type_spec, NULL); + if (state->itemgetter_type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)state->itemgetter_type) < 0) { + return -1; + } + + state->methodcaller_type = PyType_FromModuleAndSpec(module, &methodcaller_type_spec, NULL); + if (state->methodcaller_type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)state->methodcaller_type) < 0) { + return -1; } return 0; @@ -1772,17 +1763,42 @@ static struct PyModuleDef_Slot operator_slots[] = { {0, NULL} }; +static int +operator_traverse(PyObject *module, visitproc visit, void *arg) +{ + _operator_state *state = get_operator_state(module); + Py_VISIT(state->attrgetter_type); + Py_VISIT(state->itemgetter_type); + Py_VISIT(state->methodcaller_type); + return 0; +} + +static int +operator_clear(PyObject *module) +{ + _operator_state *state = get_operator_state(module); + Py_CLEAR(state->attrgetter_type); + Py_CLEAR(state->itemgetter_type); + Py_CLEAR(state->methodcaller_type); + return 0; +} + +static void +operator_free(void *module) +{ + operator_clear((PyObject *)module); +} static struct PyModuleDef operatormodule = { PyModuleDef_HEAD_INIT, - "_operator", - operator_doc, - 0, - operator_methods, - operator_slots, - NULL, - NULL, - NULL + .m_name = "_operator", + .m_doc = operator_doc, + .m_size = sizeof(_operator_state), + .m_methods = operator_methods, + .m_slots = operator_slots, + .m_traverse = operator_traverse, + .m_clear = operator_clear, + .m_free = operator_free, }; PyMODINIT_FUNC diff --git a/contrib/tools/python3/src/Modules/_peg_parser.c b/contrib/tools/python3/src/Modules/_peg_parser.c deleted file mode 100644 index ca2a3cf7b5f..00000000000 --- a/contrib/tools/python3/src/Modules/_peg_parser.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include "pegen_interface.h" - -static int -_mode_str_to_int(char *mode_str) -{ - int mode; - if (strcmp(mode_str, "exec") == 0) { - mode = Py_file_input; - } - else if (strcmp(mode_str, "eval") == 0) { - mode = Py_eval_input; - } - else if (strcmp(mode_str, "single") == 0) { - mode = Py_single_input; - } - else { - mode = -1; - } - return mode; -} - -static mod_ty -_run_parser(char *str, char *filename, int mode, PyCompilerFlags *flags, PyArena *arena, int oldparser) -{ - mod_ty mod; - if (!oldparser) { - mod = PyPegen_ASTFromString(str, filename, mode, flags, arena); - } - else { - mod = PyParser_ASTFromString(str, filename, mode, flags, arena); - } - return mod; -} - -PyObject * -_Py_compile_string(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *keywords[] = {"string", "filename", "mode", "oldparser", NULL}; - char *the_string; - char *filename = ""; - char *mode_str = "exec"; - int oldparser = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ssp", keywords, - &the_string, &filename, &mode_str, &oldparser)) { - return NULL; - } - - int mode = _mode_str_to_int(mode_str); - if (mode == -1) { - return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); - } - - PyCompilerFlags flags = _PyCompilerFlags_INIT; - flags.cf_flags = PyCF_IGNORE_COOKIE; - - PyArena *arena = PyArena_New(); - if (arena == NULL) { - return NULL; - } - - mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); - if (mod == NULL) { - PyArena_Free(arena); - return NULL; - } - - PyObject *filename_ob = PyUnicode_DecodeFSDefault(filename); - if (filename_ob == NULL) { - PyArena_Free(arena); - return NULL; - } - PyCodeObject *result = PyAST_CompileObject(mod, filename_ob, &flags, -1, arena); - Py_XDECREF(filename_ob); - PyArena_Free(arena); - return (PyObject *)result; -} - -PyObject * -_Py_parse_string(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *keywords[] = {"string", "filename", "mode", "oldparser", "ast", NULL}; - char *the_string; - char *filename = ""; - char *mode_str = "exec"; - int oldparser = 0; - int ast = 1; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|sspp", keywords, - &the_string, &filename, &mode_str, &oldparser, &ast)) { - return NULL; - } - - int mode = _mode_str_to_int(mode_str); - if (mode == -1) { - return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); - } - - PyCompilerFlags flags = _PyCompilerFlags_INIT; - flags.cf_flags = PyCF_IGNORE_COOKIE; - - PyArena *arena = PyArena_New(); - if (arena == NULL) { - return NULL; - } - - mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); - if (mod == NULL) { - PyArena_Free(arena); - return NULL; - } - - PyObject *result; - if (ast) { - result = PyAST_mod2obj(mod); - } - else { - Py_INCREF(Py_None); - result = Py_None; - } - PyArena_Free(arena); - return result; -} - -static PyMethodDef ParseMethods[] = { - { - "parse_string", - (PyCFunction)(void (*)(void))_Py_parse_string, - METH_VARARGS|METH_KEYWORDS, - "Parse a string, return an AST." - }, - { - "compile_string", - (PyCFunction)(void (*)(void))_Py_compile_string, - METH_VARARGS|METH_KEYWORDS, - "Compile a string, return a code object." - }, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -static struct PyModuleDef parsemodule = { - PyModuleDef_HEAD_INIT, - .m_name = "peg_parser", - .m_doc = "A parser.", - .m_methods = ParseMethods, -}; - -PyMODINIT_FUNC -PyInit__peg_parser(void) -{ - return PyModule_Create(&parsemodule); -} diff --git a/contrib/tools/python3/src/Modules/_pickle.c b/contrib/tools/python3/src/Modules/_pickle.c index 30bb5c0d75c..8a4f0e64fb9 100644 --- a/contrib/tools/python3/src/Modules/_pickle.c +++ b/contrib/tools/python3/src/Modules/_pickle.c @@ -9,6 +9,7 @@ #endif #include "Python.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "structmember.h" // PyMemberDef PyDoc_STRVAR(pickle_module_doc, @@ -182,7 +183,7 @@ static struct PyModuleDef _picklemodule; static PickleState * _Pickle_GetState(PyObject *module) { - return (PickleState *)PyModule_GetState(module); + return (PickleState *)_PyModule_GetState(module); } /* Find the module instance imported in the currently running sub-interpreter @@ -442,8 +443,8 @@ Pdata_dealloc(Pdata *self) while (--i >= 0) { Py_DECREF(self->data[i]); } - PyMem_FREE(self->data); - PyObject_Del(self); + PyMem_Free(self->data); + PyObject_Free(self); } static PyTypeObject Pdata_Type = { @@ -465,7 +466,7 @@ Pdata_New(void) self->mark_set = 0; self->fence = 0; self->allocated = 8; - self->data = PyMem_MALLOC(self->allocated * sizeof(PyObject *)); + self->data = PyMem_Malloc(self->allocated * sizeof(PyObject *)); if (self->data) return (PyObject *)self; Py_DECREF(self); @@ -726,7 +727,7 @@ static PyTypeObject Unpickler_Type; static PyMemoTable * PyMemoTable_New(void) { - PyMemoTable *memo = PyMem_MALLOC(sizeof(PyMemoTable)); + PyMemoTable *memo = PyMem_Malloc(sizeof(PyMemoTable)); if (memo == NULL) { PyErr_NoMemory(); return NULL; @@ -735,9 +736,9 @@ PyMemoTable_New(void) memo->mt_used = 0; memo->mt_allocated = MT_MINSIZE; memo->mt_mask = MT_MINSIZE - 1; - memo->mt_table = PyMem_MALLOC(MT_MINSIZE * sizeof(PyMemoEntry)); + memo->mt_table = PyMem_Malloc(MT_MINSIZE * sizeof(PyMemoEntry)); if (memo->mt_table == NULL) { - PyMem_FREE(memo); + PyMem_Free(memo); PyErr_NoMemory(); return NULL; } @@ -758,10 +759,10 @@ PyMemoTable_Copy(PyMemoTable *self) new->mt_mask = self->mt_mask; /* The table we get from _New() is probably smaller than we wanted. Free it and allocate one that's the right size. */ - PyMem_FREE(new->mt_table); + PyMem_Free(new->mt_table); new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated); if (new->mt_table == NULL) { - PyMem_FREE(new); + PyMem_Free(new); PyErr_NoMemory(); return NULL; } @@ -800,8 +801,8 @@ PyMemoTable_Del(PyMemoTable *self) return; PyMemoTable_Clear(self); - PyMem_FREE(self->mt_table); - PyMem_FREE(self); + PyMem_Free(self->mt_table); + PyMem_Free(self); } /* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup() @@ -880,7 +881,7 @@ _PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size) } /* Deallocate the old table. */ - PyMem_FREE(oldtable); + PyMem_Free(oldtable); return 0; } @@ -1582,7 +1583,7 @@ _Unpickler_MemoCleanup(UnpicklerObject *self) while (--i >= 0) { Py_XDECREF(memo[i]); } - PyMem_FREE(memo); + PyMem_Free(memo); } static UnpicklerObject * @@ -1715,7 +1716,7 @@ memo_get(PicklerObject *self, PyObject *key) if (!self->bin) { pdata[0] = GET; PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, - "%" PY_FORMAT_SIZE_T "d\n", *value); + "%zd\n", *value); len = strlen(pdata); } else { @@ -1772,7 +1773,7 @@ memo_put(PicklerObject *self, PyObject *obj) else if (!self->bin) { pdata[0] = PUT; PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, - "%" PY_FORMAT_SIZE_T "d\n", idx); + "%zd\n", idx); len = strlen(pdata); } else { @@ -2004,26 +2005,21 @@ fast_save_enter(PicklerObject *self, PyObject *obj) self->fast_nesting = -1; return 0; } - if (PyDict_GetItemWithError(self->fast_memo, key)) { - Py_DECREF(key); + int r = PyDict_Contains(self->fast_memo, key); + if (r > 0) { PyErr_Format(PyExc_ValueError, "fast mode: can't pickle cyclic objects " "including object type %.200s at %p", Py_TYPE(obj)->tp_name, obj); - self->fast_nesting = -1; - return 0; } - if (PyErr_Occurred()) { - Py_DECREF(key); - self->fast_nesting = -1; - return 0; + else if (r == 0) { + r = PyDict_SetItem(self->fast_memo, key, Py_None); } - if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) { - Py_DECREF(key); + Py_DECREF(key); + if (r != 0) { self->fast_nesting = -1; return 0; } - Py_DECREF(key); } return 1; } @@ -5912,118 +5908,75 @@ load_inst(UnpicklerObject *self) return 0; } -static int -load_newobj(UnpicklerObject *self) +static void +newobj_unpickling_error(const char * msg, int use_kwargs, PyObject *arg) { - PyObject *args = NULL; - PyObject *clsraw = NULL; - PyTypeObject *cls; /* clsraw cast to its true type */ - PyObject *obj; PickleState *st = _Pickle_GetGlobalState(); - - /* Stack is ... cls argtuple, and we want to call - * cls.__new__(cls, *argtuple). - */ - PDATA_POP(self->stack, args); - if (args == NULL) - goto error; - if (!PyTuple_Check(args)) { - PyErr_SetString(st->UnpicklingError, - "NEWOBJ expected an arg " "tuple."); - goto error; - } - - PDATA_POP(self->stack, clsraw); - cls = (PyTypeObject *)clsraw; - if (cls == NULL) - goto error; - if (!PyType_Check(cls)) { - PyErr_SetString(st->UnpicklingError, "NEWOBJ class argument " - "isn't a type object"); - goto error; - } - if (cls->tp_new == NULL) { - PyErr_SetString(st->UnpicklingError, "NEWOBJ class argument " - "has NULL tp_new"); - goto error; - } - - /* Call __new__. */ - obj = cls->tp_new(cls, args, NULL); - if (obj == NULL) - goto error; - - Py_DECREF(args); - Py_DECREF(clsraw); - PDATA_PUSH(self->stack, obj, -1); - return 0; - - error: - Py_XDECREF(args); - Py_XDECREF(clsraw); - return -1; + PyErr_Format(st->UnpicklingError, msg, + use_kwargs ? "NEWOBJ_EX" : "NEWOBJ", + Py_TYPE(arg)->tp_name); } static int -load_newobj_ex(UnpicklerObject *self) +load_newobj(UnpicklerObject *self, int use_kwargs) { - PyObject *cls, *args, *kwargs; + PyObject *cls, *args, *kwargs = NULL; PyObject *obj; - PickleState *st = _Pickle_GetGlobalState(); - PDATA_POP(self->stack, kwargs); - if (kwargs == NULL) { - return -1; + /* Stack is ... cls args [kwargs], and we want to call + * cls.__new__(cls, *args, **kwargs). + */ + if (use_kwargs) { + PDATA_POP(self->stack, kwargs); + if (kwargs == NULL) { + return -1; + } } PDATA_POP(self->stack, args); if (args == NULL) { - Py_DECREF(kwargs); + Py_XDECREF(kwargs); return -1; } PDATA_POP(self->stack, cls); if (cls == NULL) { - Py_DECREF(kwargs); + Py_XDECREF(kwargs); Py_DECREF(args); return -1; } if (!PyType_Check(cls)) { - PyErr_Format(st->UnpicklingError, - "NEWOBJ_EX class argument must be a type, not %.200s", - Py_TYPE(cls)->tp_name); + newobj_unpickling_error("%s class argument must be a type, not %.200s", + use_kwargs, cls); goto error; } - if (((PyTypeObject *)cls)->tp_new == NULL) { - PyErr_SetString(st->UnpicklingError, - "NEWOBJ_EX class argument doesn't have __new__"); + newobj_unpickling_error("%s class argument '%.200s' doesn't have __new__", + use_kwargs, cls); goto error; } if (!PyTuple_Check(args)) { - PyErr_Format(st->UnpicklingError, - "NEWOBJ_EX args argument must be a tuple, not %.200s", - Py_TYPE(args)->tp_name); + newobj_unpickling_error("%s args argument must be a tuple, not %.200s", + use_kwargs, args); goto error; } - if (!PyDict_Check(kwargs)) { - PyErr_Format(st->UnpicklingError, - "NEWOBJ_EX kwargs argument must be a dict, not %.200s", - Py_TYPE(kwargs)->tp_name); + if (use_kwargs && !PyDict_Check(kwargs)) { + newobj_unpickling_error("%s kwargs argument must be a dict, not %.200s", + use_kwargs, kwargs); goto error; } obj = ((PyTypeObject *)cls)->tp_new((PyTypeObject *)cls, args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(args); - Py_DECREF(cls); if (obj == NULL) { - return -1; + goto error; } + Py_XDECREF(kwargs); + Py_DECREF(args); + Py_DECREF(cls); PDATA_PUSH(self->stack, obj, -1); return 0; error: - Py_DECREF(kwargs); + Py_XDECREF(kwargs); Py_DECREF(args); Py_DECREF(cls); return -1; @@ -6956,8 +6909,8 @@ load(UnpicklerObject *self) OP(FROZENSET, load_frozenset) OP(OBJ, load_obj) OP(INST, load_inst) - OP(NEWOBJ, load_newobj) - OP(NEWOBJ_EX, load_newobj_ex) + OP_ARG(NEWOBJ, load_newobj, 0) + OP_ARG(NEWOBJ_EX, load_newobj, 1) OP(GLOBAL, load_global) OP(STACK_GLOBAL, load_stack_global) OP(APPEND, load_append) @@ -7592,7 +7545,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored for (size_t i = new_memo_size - 1; i != SIZE_MAX; i--) { Py_XDECREF(new_memo[i]); } - PyMem_FREE(new_memo); + PyMem_Free(new_memo); } return -1; } diff --git a/contrib/tools/python3/src/Modules/_posixsubprocess.c b/contrib/tools/python3/src/Modules/_posixsubprocess.c index d64e0a1cfa0..a58159a277b 100644 --- a/contrib/tools/python3/src/Modules/_posixsubprocess.c +++ b/contrib/tools/python3/src/Modules/_posixsubprocess.c @@ -1,5 +1,6 @@ /* Authors: Gregory P. Smith & Jeffrey Yasskin */ #include "Python.h" +#include "pycore_fileutils.h" #if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE) # define _GNU_SOURCE #endif @@ -35,6 +36,14 @@ # define SYS_getdents64 __NR_getdents64 #endif +#if defined(__linux__) && defined(HAVE_VFORK) && defined(HAVE_SIGNAL_H) && \ + defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +/* If this is ever expanded to non-Linux platforms, verify what calls are + * allowed after vfork(). Ex: setsid() may be disallowed on macOS? */ +# include +# define VFORK_USABLE 1 +#endif + #if defined(__sun) && defined(__SVR4) /* readdir64 is used to work around Solaris 9 bug 6395699. */ # define readdir readdir64 @@ -60,47 +69,8 @@ #define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0) -typedef struct { - PyObject* disable; - PyObject* enable; - PyObject* isenabled; -} _posixsubprocessstate; - static struct PyModuleDef _posixsubprocessmodule; -static inline _posixsubprocessstate* -get_posixsubprocess_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_posixsubprocessstate *)state; -} - -#define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule)) - -/* If gc was disabled, call gc.enable(). Return 0 on success. */ -static int -_enable_gc(int need_to_reenable_gc, PyObject *gc_module) -{ - PyObject *result; - PyObject *exctype, *val, *tb; - - if (need_to_reenable_gc) { - PyErr_Fetch(&exctype, &val, &tb); - result = PyObject_CallMethodNoArgs( - gc_module, _posixsubprocessstate_global->enable); - if (exctype != NULL) { - PyErr_Restore(exctype, val, tb); - } - if (result == NULL) { - return 1; - } - Py_DECREF(result); - } - return 0; -} - - /* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */ static int _pos_int_from_ascii(const char *name) @@ -250,7 +220,6 @@ _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) long end_fd = safe_get_max_fd(); Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep); Py_ssize_t keep_seq_idx; - int fd_num; /* As py_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) { @@ -258,21 +227,11 @@ _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) int keep_fd = PyLong_AsLong(py_keep_fd); if (keep_fd < start_fd) continue; - for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) { - close(fd_num); - } + _Py_closerange(start_fd, keep_fd - 1); start_fd = keep_fd + 1; } if (start_fd <= end_fd) { -#if defined(__FreeBSD__) - /* Any errors encountered while closing file descriptors are ignored */ - closefrom(start_fd); -#else - for (fd_num = start_fd; fd_num < end_fd; ++fd_num) { - /* Ignore errors */ - (void)close(fd_num); - } -#endif + _Py_closerange(start_fd, end_fd); } } @@ -417,9 +376,53 @@ _close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) #endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ +#ifdef VFORK_USABLE +/* Reset dispositions for all signals to SIG_DFL except for ignored + * signals. This way we ensure that no signal handlers can run + * after we unblock signals in a child created by vfork(). + */ +static void +reset_signal_handlers(const sigset_t *child_sigmask) +{ + struct sigaction sa_dfl = {.sa_handler = SIG_DFL}; + for (int sig = 1; sig < _NSIG; sig++) { + /* Dispositions for SIGKILL and SIGSTOP can't be changed. */ + if (sig == SIGKILL || sig == SIGSTOP) { + continue; + } + + /* There is no need to reset the disposition of signals that will + * remain blocked across execve() since the kernel will do it. */ + if (sigismember(child_sigmask, sig) == 1) { + continue; + } + + struct sigaction sa; + /* C libraries usually return EINVAL for signals used + * internally (e.g. for thread cancellation), so simply + * skip errors here. */ + if (sigaction(sig, NULL, &sa) == -1) { + continue; + } + + /* void *h works as these fields are both pointer types already. */ + void *h = (sa.sa_flags & SA_SIGINFO ? (void *)sa.sa_sigaction : + (void *)sa.sa_handler); + if (h == SIG_IGN || h == SIG_DFL) { + continue; + } + + /* This call can't reasonably fail, but if it does, terminating + * the child seems to be too harsh, so ignore errors. */ + (void) sigaction(sig, &sa_dfl, NULL); + } +} +#endif /* VFORK_USABLE */ + + /* - * This function is code executed in the child process immediately after fork - * to set things up and call exec(). + * This function is code executed in the child process immediately after + * (v)fork to set things up and call exec(). * * All of the code in this function must only use async-signal-safe functions, * listed at `man 7 signal` or @@ -427,8 +430,28 @@ _close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) * * This restriction is documented at * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html. + * + * If this function is called after vfork(), even more care must be taken. + * The lack of preparations that C libraries normally take on fork(), + * as well as sharing the address space with the parent, might make even + * async-signal-safe functions vfork-unsafe. In particular, on Linux, + * set*id() and setgroups() library functions must not be called, since + * they have to interact with the library-level thread list and send + * library-internal signals to implement per-process credentials semantics + * 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. + * + * In some C libraries, setrlimit() has the same thread list/signalling + * behavior since resource limits were per-thread attributes before + * Linux 2.6.10. Musl, as of 1.2.1, is known to have this issue + * (https://www.openwall.com/lists/musl/2020/10/15/6). + * + * If vfork-unsafe functionality is desired after vfork(), consider using + * syscall() to obtain it. */ -static void +_Py_NO_INLINE static void child_exec(char *const exec_array[], char *const argv[], char *const envp[], @@ -442,6 +465,7 @@ child_exec(char *const exec_array[], 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, + const void *child_sigmask, PyObject *py_fds_to_keep, PyObject *preexec_fn, PyObject *preexec_fn_args_tuple) @@ -517,6 +541,15 @@ child_exec(char *const exec_array[], if (restore_signals) _Py_RestoreSignals(); +#ifdef VFORK_USABLE + if (child_sigmask) { + reset_signal_handlers(child_sigmask); + if ((errno = pthread_sigmask(SIG_SETMASK, child_sigmask, NULL))) { + goto error; + } + } +#endif + #ifdef HAVE_SETSID if (call_setsid) POSIX_CALL(setsid()); @@ -609,8 +642,82 @@ error: } +/* The main purpose of this wrapper function is to isolate vfork() from both + * subprocess_fork_exec() and child_exec(). A child process created via + * vfork() executes on the same stack as the parent process while the latter is + * suspended, so this function should not be inlined to avoid compiler bugs + * that might clobber data needed by the parent later. Additionally, + * child_exec() should not be inlined to avoid spurious -Wclobber warnings from + * GCC (see bpo-35823). + */ +_Py_NO_INLINE static pid_t +do_fork_exec(char *const exec_array[], + char *const argv[], + char *const envp[], + const char *cwd, + int p2cread, int p2cwrite, + int c2pread, int c2pwrite, + int errread, int errwrite, + int errpipe_read, int errpipe_write, + int close_fds, int restore_signals, + int call_setsid, + 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, + const void *child_sigmask, + PyObject *py_fds_to_keep, + PyObject *preexec_fn, + PyObject *preexec_fn_args_tuple) +{ + + pid_t pid; + +#ifdef VFORK_USABLE + if (child_sigmask) { + /* These are checked by our caller; verify them in debug builds. */ + assert(!call_setuid); + assert(!call_setgid); + assert(!call_setgroups); + assert(preexec_fn == Py_None); + + pid = vfork(); + } else +#endif + { + pid = fork(); + } + + if (pid != 0) { + return pid; + } + + /* Child process. + * See the comment above child_exec() for restrictions imposed on + * the code below. + */ + + if (preexec_fn != Py_None) { + /* We'll be calling back into Python later so we need to do this. + * This call may not be async-signal-safe but neither is calling + * back into Python. The user asked us to use hope as a strategy + * to avoid deadlock... */ + PyOS_AfterFork_Child(); + } + + child_exec(exec_array, argv, envp, cwd, + p2cread, p2cwrite, c2pread, c2pwrite, + errread, errwrite, errpipe_read, errpipe_write, + close_fds, restore_signals, call_setsid, + 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); + _exit(255); + return 0; /* Dead code to avoid a potential compiler warning. */ +} + + static PyObject * -subprocess_fork_exec(PyObject* self, PyObject *args) +subprocess_fork_exec(PyObject *module, PyObject *args) { PyObject *gc_module = NULL; PyObject *executable_list, *py_fds_to_keep; @@ -628,7 +735,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) int child_umask; PyObject *cwd_obj, *cwd_obj2 = NULL; const char *cwd; - pid_t pid; + 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; @@ -673,30 +780,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) /* We need to call gc.disable() when we'll be calling preexec_fn */ if (preexec_fn != Py_None) { - PyObject *result; - - gc_module = PyImport_ImportModule("gc"); - if (gc_module == NULL) - return NULL; - result = PyObject_CallMethodNoArgs( - gc_module, _posixsubprocessstate_global->isenabled); - if (result == NULL) { - Py_DECREF(gc_module); - return NULL; - } - need_to_reenable_gc = PyObject_IsTrue(result); - Py_DECREF(result); - if (need_to_reenable_gc == -1) { - Py_DECREF(gc_module); - return NULL; - } - result = PyObject_CallMethodNoArgs( - gc_module, _posixsubprocessstate_global->disable); - if (result == NULL) { - Py_DECREF(gc_module); - return NULL; - } - Py_DECREF(result); + need_to_reenable_gc = PyGC_Disable(); } exec_array = _PySequence_BytesToCharpArray(executable_list); @@ -841,83 +925,92 @@ subprocess_fork_exec(PyObject* self, PyObject *args) need_after_fork = 1; } - pid = fork(); - if (pid == 0) { - /* Child process */ - /* - * Code from here to _exit() must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + /* NOTE: When old_sigmask is non-NULL, do_fork_exec() may use vfork(). */ + const void *old_sigmask = NULL; +#ifdef VFORK_USABLE + /* Use vfork() only if it's safe. See the comment above child_exec(). */ + sigset_t old_sigs; + if (preexec_fn == Py_None && + !call_setuid && !call_setgid && !call_setgroups) { + /* 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 + * pthread_sigmask(), but signal handlers installed by C libraries + * normally service only signals originating from *within the process*, + * so it should be sufficient to consider any library function that + * might send such a signal to be vfork-unsafe and do not call it in + * the child. */ - - if (preexec_fn != Py_None) { - /* We'll be calling back into Python later so we need to do this. - * This call may not be async-signal-safe but neither is calling - * back into Python. The user asked us to use hope as a strategy - * to avoid deadlock... */ - PyOS_AfterFork_Child(); + sigset_t all_sigs; + sigfillset(&all_sigs); + if ((saved_errno = pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs))) { + goto cleanup; } - - child_exec(exec_array, argv, envp, cwd, - p2cread, p2cwrite, c2pread, c2pwrite, - errread, errwrite, errpipe_read, errpipe_write, - close_fds, restore_signals, call_setsid, - call_setgid, gid, call_setgroups, num_groups, groups, - call_setuid, uid, child_umask, - py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); - _exit(255); - return NULL; /* Dead code to avoid a potential compiler warning. */ + old_sigmask = &old_sigs; } +#endif + + pid = do_fork_exec(exec_array, argv, envp, cwd, + p2cread, p2cwrite, c2pread, c2pwrite, + errread, errwrite, errpipe_read, errpipe_write, + close_fds, restore_signals, call_setsid, + 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); + /* Parent (original) process */ if (pid == -1) { /* Capture errno for the exception. */ saved_errno = errno; } - Py_XDECREF(cwd_obj2); +#ifdef VFORK_USABLE + if (old_sigmask) { + /* vfork() semantics guarantees that the parent is blocked + * until the child performs _exit() or execve(), so it is safe + * to unblock signals once we're here. + * Note that in environments where vfork() is implemented as fork(), + * such as QEMU user-mode emulation, the parent won't be blocked, + * but it won't share the address space with the child, + * so it's still safe to unblock the signals. + * + * We don't handle errors here because this call can't fail + * if valid arguments are given, and because there is no good + * way for the caller to deal with a failure to restore + * the thread signal mask. */ + (void) pthread_sigmask(SIG_SETMASK, old_sigmask, NULL); + } +#endif if (need_after_fork) PyOS_AfterFork_Parent(); - if (envp) - _Py_FreeCharPArray(envp); - if (argv) - _Py_FreeCharPArray(argv); - _Py_FreeCharPArray(exec_array); - - /* Reenable gc in the parent process (or if fork failed). */ - if (_enable_gc(need_to_reenable_gc, gc_module)) { - pid = -1; - } - PyMem_RawFree(groups); - Py_XDECREF(preexec_fn_args_tuple); - Py_XDECREF(gc_module); - if (pid == -1) { +cleanup: + if (saved_errno != 0) { errno = saved_errno; /* We can't call this above as PyOS_AfterFork_Parent() calls back * into Python code which would see the unreturned error. */ PyErr_SetFromErrno(PyExc_OSError); - return NULL; /* fork() failed. */ } - return PyLong_FromPid(pid); - -cleanup: + Py_XDECREF(preexec_fn_args_tuple); + PyMem_RawFree(groups); Py_XDECREF(cwd_obj2); if (envp) _Py_FreeCharPArray(envp); + Py_XDECREF(converted_args); + Py_XDECREF(fast_args); if (argv) _Py_FreeCharPArray(argv); if (exec_array) _Py_FreeCharPArray(exec_array); - PyMem_RawFree(groups); - Py_XDECREF(converted_args); - Py_XDECREF(fast_args); - Py_XDECREF(preexec_fn_args_tuple); - _enable_gc(need_to_reenable_gc, gc_module); + if (need_to_reenable_gc) { + PyGC_Enable(); + } Py_XDECREF(gc_module); - return NULL; + + return pid == -1 ? NULL : PyLong_FromPid(pid); } @@ -954,63 +1047,26 @@ Raises: Only on an error in the parent process.\n\ 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}, {NULL, NULL} /* sentinel */ }; - -static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(get_posixsubprocess_state(m)->disable); - Py_VISIT(get_posixsubprocess_state(m)->enable); - Py_VISIT(get_posixsubprocess_state(m)->isenabled); - return 0; -} - -static int _posixsubprocess_clear(PyObject *m) { - Py_CLEAR(get_posixsubprocess_state(m)->disable); - Py_CLEAR(get_posixsubprocess_state(m)->enable); - Py_CLEAR(get_posixsubprocess_state(m)->isenabled); - return 0; -} - -static void _posixsubprocess_free(void *m) { - _posixsubprocess_clear((PyObject *)m); -} +static PyModuleDef_Slot _posixsubprocess_slots[] = { + {0, NULL} +}; static struct PyModuleDef _posixsubprocessmodule = { PyModuleDef_HEAD_INIT, - "_posixsubprocess", - module_doc, - sizeof(_posixsubprocessstate), - module_methods, - NULL, - _posixsubprocess_traverse, - _posixsubprocess_clear, - _posixsubprocess_free, + .m_name = "_posixsubprocess", + .m_doc = module_doc, + .m_size = 0, + .m_methods = module_methods, + .m_slots = _posixsubprocess_slots, }; PyMODINIT_FUNC PyInit__posixsubprocess(void) { - PyObject* m; - - m = PyState_FindModule(&_posixsubprocessmodule); - if (m != NULL) { - Py_INCREF(m); - return m; - } - - m = PyModule_Create(&_posixsubprocessmodule); - if (m == NULL) { - return NULL; - } - - get_posixsubprocess_state(m)->disable = PyUnicode_InternFromString("disable"); - get_posixsubprocess_state(m)->enable = PyUnicode_InternFromString("enable"); - get_posixsubprocess_state(m)->isenabled = PyUnicode_InternFromString("isenabled"); - - PyState_AddModule(m, &_posixsubprocessmodule); - return m; + return PyModuleDef_Init(&_posixsubprocessmodule); } diff --git a/contrib/tools/python3/src/Modules/_queuemodule.c b/contrib/tools/python3/src/Modules/_queuemodule.c index b155ea94239..a124255a72c 100644 --- a/contrib/tools/python3/src/Modules/_queuemodule.c +++ b/contrib/tools/python3/src/Modules/_queuemodule.c @@ -1,16 +1,23 @@ #include "Python.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "structmember.h" // PyMemberDef #include // offsetof() -/*[clinic input] -module _queue -class _queue.SimpleQueue "simplequeueobject *" "&PySimpleQueueType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cf49af81bcbbbea6]*/ - -static PyTypeObject PySimpleQueueType; /* forward decl */ - -static PyObject *EmptyError; +typedef struct { + PyTypeObject *SimpleQueueType; + PyObject *EmptyError; +} simplequeue_state; +static simplequeue_state * +simplequeue_get_state(PyObject *module) +{ + simplequeue_state *state = _PyModule_GetState(module); + assert(state); + return state; +} +static struct PyModuleDef queuemodule; +#define simplequeue_get_state_by_type(type) \ + (simplequeue_get_state(_PyType_GetModuleByDef(type, &queuemodule))) typedef struct { PyObject_HEAD @@ -21,10 +28,24 @@ typedef struct { PyObject *weakreflist; } simplequeueobject; +/*[clinic input] +module _queue +class _queue.SimpleQueue "simplequeueobject *" "simplequeue_get_state_by_type(type)->SimpleQueueType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0a4023fe4d198c8d]*/ + +static int +simplequeue_clear(simplequeueobject *self) +{ + Py_CLEAR(self->lst); + return 0; +} static void simplequeue_dealloc(simplequeueobject *self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); if (self->lock != NULL) { /* Unlock the lock so it's safe to free it */ @@ -32,16 +53,18 @@ simplequeue_dealloc(simplequeueobject *self) PyThread_release_lock(self->lock); PyThread_free_lock(self->lock); } - Py_XDECREF(self->lst); + (void)simplequeue_clear(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); } static int simplequeue_traverse(simplequeueobject *self, visitproc visit, void *arg) { Py_VISIT(self->lst); + Py_VISIT(Py_TYPE(self)); return 0; } @@ -155,6 +178,9 @@ simplequeue_pop_item(simplequeueobject *self) /*[clinic input] _queue.SimpleQueue.get + + cls: defining_class + / block: bool = True timeout: object = None @@ -171,9 +197,9 @@ in that case). [clinic start generated code]*/ static PyObject * -_queue_SimpleQueue_get_impl(simplequeueobject *self, int block, - PyObject *timeout) -/*[clinic end generated code: output=ec82a7157dcccd1a input=4bf691f9f01fa297]*/ +_queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls, + int block, PyObject *timeout) +/*[clinic end generated code: output=1969aefa7db63666 input=5fc4d56b9a54757e]*/ { _PyTime_t endtime = 0; _PyTime_t timeout_val; @@ -225,8 +251,10 @@ _queue_SimpleQueue_get_impl(simplequeueobject *self, int block, return NULL; } if (r == PY_LOCK_FAILURE) { + PyObject *module = PyType_GetModule(cls); + simplequeue_state *state = simplequeue_get_state(module); /* Timed out */ - PyErr_SetNone(EmptyError); + PyErr_SetNone(state->EmptyError); return NULL; } self->locked = 1; @@ -251,6 +279,9 @@ _queue_SimpleQueue_get_impl(simplequeueobject *self, int block, /*[clinic input] _queue.SimpleQueue.get_nowait + cls: defining_class + / + Remove and return an item from the queue without blocking. Only get an item if one is immediately available. Otherwise @@ -258,10 +289,11 @@ raise the Empty exception. [clinic start generated code]*/ static PyObject * -_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self) -/*[clinic end generated code: output=a89731a75dbe4937 input=6fe5102db540a1b9]*/ +_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self, + PyTypeObject *cls) +/*[clinic end generated code: output=620c58e2750f8b8a input=842f732bf04216d3]*/ { - return _queue_SimpleQueue_get_impl(self, 0, Py_None); + return _queue_SimpleQueue_get_impl(self, cls, 0, Py_None); } /*[clinic input] @@ -290,6 +322,29 @@ _queue_SimpleQueue_qsize_impl(simplequeueobject *self) return PyList_GET_SIZE(self->lst) - self->lst_pos; } +static int +queue_traverse(PyObject *m, visitproc visit, void *arg) +{ + simplequeue_state *state = simplequeue_get_state(m); + Py_VISIT(state->SimpleQueueType); + Py_VISIT(state->EmptyError); + return 0; +} + +static int +queue_clear(PyObject *m) +{ + simplequeue_state *state = simplequeue_get_state(m); + Py_CLEAR(state->SimpleQueueType); + Py_CLEAR(state->EmptyError); + return 0; +} + +static void +queue_free(void *m) +{ + queue_clear((PyObject *)m); +} #include "clinic/_queuemodule.c.h" @@ -306,48 +361,28 @@ static PyMethodDef simplequeue_methods[] = { {NULL, NULL} /* sentinel */ }; +static struct PyMemberDef simplequeue_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(simplequeueobject, weakreflist), READONLY}, + {NULL}, +}; + +static PyType_Slot simplequeue_slots[] = { + {Py_tp_dealloc, simplequeue_dealloc}, + {Py_tp_doc, (void *)simplequeue_new__doc__}, + {Py_tp_traverse, simplequeue_traverse}, + {Py_tp_clear, simplequeue_clear}, + {Py_tp_members, simplequeue_members}, + {Py_tp_methods, simplequeue_methods}, + {Py_tp_new, simplequeue_new}, + {0, NULL}, +}; -static PyTypeObject PySimpleQueueType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_queue.SimpleQueue", /*tp_name*/ - sizeof(simplequeueobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)simplequeue_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 */ - simplequeue_new__doc__, /*tp_doc*/ - (traverseproc)simplequeue_traverse, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(simplequeueobject, weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - simplequeue_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 */ - simplequeue_new /* tp_new */ +static PyType_Spec simplequeue_spec = { + .name = "_queue.SimpleQueue", + .basicsize = sizeof(simplequeueobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = simplequeue_slots, }; @@ -357,43 +392,54 @@ PyDoc_STRVAR(queue_module_doc, "C implementation of the Python queue module.\n\ This module is an implementation detail, please do not use it directly."); -static struct PyModuleDef queuemodule = { - PyModuleDef_HEAD_INIT, - "_queue", - queue_module_doc, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit__queue(void) +static int +queuemodule_exec(PyObject *module) { - PyObject *m; - - /* Create the module */ - m = PyModule_Create(&queuemodule); - if (m == NULL) - return NULL; + simplequeue_state *state = simplequeue_get_state(module); - EmptyError = PyErr_NewExceptionWithDoc( + state->EmptyError = PyErr_NewExceptionWithDoc( "_queue.Empty", "Exception raised by Queue.get(block=0)/get_nowait().", NULL, NULL); - if (EmptyError == NULL) - return NULL; - - Py_INCREF(EmptyError); - if (PyModule_AddObject(m, "Empty", EmptyError) < 0) - return NULL; + if (state->EmptyError == NULL) { + return -1; + } + if (PyModule_AddObjectRef(module, "Empty", state->EmptyError) < 0) { + return -1; + } - if (PyModule_AddType(m, &PySimpleQueueType) < 0) { - return NULL; + state->SimpleQueueType = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &simplequeue_spec, NULL); + if (state->SimpleQueueType == NULL) { + return -1; } + if (PyModule_AddType(module, state->SimpleQueueType) < 0) { + return -1; + } + + return 0; +} + +static PyModuleDef_Slot queuemodule_slots[] = { + {Py_mod_exec, queuemodule_exec}, + {0, NULL} +}; - return m; + +static struct PyModuleDef queuemodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_queue", + .m_doc = queue_module_doc, + .m_size = sizeof(simplequeue_state), + .m_slots = queuemodule_slots, + .m_traverse = queue_traverse, + .m_clear = queue_clear, + .m_free = queue_free, +}; + + +PyMODINIT_FUNC +PyInit__queue(void) +{ + return PyModuleDef_Init(&queuemodule); } diff --git a/contrib/tools/python3/src/Modules/_randommodule.c b/contrib/tools/python3/src/Modules/_randommodule.c index a402b937f70..0137e34da65 100644 --- a/contrib/tools/python3/src/Modules/_randommodule.c +++ b/contrib/tools/python3/src/Modules/_randommodule.c @@ -67,7 +67,7 @@ /* ---------------------------------------------------------------*/ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_moduleobject.h" // _PyModule_GetState() #ifdef HAVE_PROCESS_H # include // getpid() #endif @@ -87,14 +87,15 @@ typedef struct { static inline _randomstate* get_random_state(PyObject *module) { - void *state = PyModule_GetState(module); + void *state = _PyModule_GetState(module); assert(state != NULL); return (_randomstate *)state; } static struct PyModuleDef _randommodule; -#define _randomstate_global get_random_state(PyState_FindModule(&_randommodule)) +#define _randomstate_type(type) \ + (get_random_state(_PyType_GetModuleByDef(type, &_randommodule))) typedef struct { PyObject_HEAD @@ -107,9 +108,9 @@ typedef struct { /*[clinic input] module _random -class _random.Random "RandomObject *" "&Random_Type" +class _random.Random "RandomObject *" "_randomstate_type(type)->Random_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f79898ae7847c321]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70a2c99619474983]*/ /* Random methods */ @@ -291,7 +292,8 @@ random_seed(RandomObject *self, PyObject *arg) } else if (PyLong_Check(arg)) { /* Calling int.__abs__() prevents calling arg.__abs__(), which might return an invalid value. See issue #31478. */ - n = PyObject_CallOneArg(_randomstate_global->Long___abs__, arg); + _randomstate *state = _randomstate_type(Py_TYPE(self)); + n = PyObject_CallOneArg(state->Long___abs__, arg); } else { Py_hash_t hash = PyObject_Hash(arg); @@ -518,8 +520,10 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { RandomObject *self; PyObject *tmp; + PyObject *arg = NULL; + _randomstate *state = _randomstate_type(type); - if (type == (PyTypeObject*)_randomstate_global->Random_Type && + if (type == (PyTypeObject*)state->Random_Type && !_PyArg_NoKeywords("Random()", kwds)) { return NULL; } @@ -527,12 +531,22 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self = (RandomObject *)PyType_GenericAlloc(type, 0); if (self == NULL) return NULL; - tmp = random_seed(self, args); + + if (PyTuple_GET_SIZE(args) > 1) { + PyErr_SetString(PyExc_TypeError, "Random() requires 0 or 1 argument"); + return NULL; + } + + if (PyTuple_GET_SIZE(args) == 1) + arg = PyTuple_GET_ITEM(args, 0); + + tmp = random_seed(self, arg); if (tmp == NULL) { Py_DECREF(self); return NULL; } Py_DECREF(tmp); + return (PyObject *)self; } @@ -568,6 +582,45 @@ static PyType_Spec Random_Type_spec = { PyDoc_STRVAR(module_doc, "Module implements the Mersenne Twister random number generator."); +static int +_random_exec(PyObject *module) +{ + _randomstate *state = get_random_state(module); + + state->Random_Type = PyType_FromModuleAndSpec( + module, &Random_Type_spec, NULL); + if (state->Random_Type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)state->Random_Type) < 0) { + return -1; + } + + /* Look up and save int.__abs__, which is needed in random_seed(). */ + PyObject *longval = PyLong_FromLong(0); + if (longval == NULL) { + return -1; + } + + PyObject *longtype = PyObject_Type(longval); + Py_DECREF(longval); + if (longtype == NULL) { + return -1; + } + + state->Long___abs__ = PyObject_GetAttrString(longtype, "__abs__"); + Py_DECREF(longtype); + if (state->Long___abs__ == NULL) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot _random_slots[] = { + {Py_mod_exec, _random_exec}, + {0, NULL} +}; + static int _random_traverse(PyObject *module, visitproc visit, void *arg) { @@ -595,7 +648,7 @@ static struct PyModuleDef _randommodule = { module_doc, sizeof(_randomstate), NULL, - NULL, + _random_slots, _random_traverse, _random_clear, _random_free, @@ -604,43 +657,5 @@ static struct PyModuleDef _randommodule = { PyMODINIT_FUNC PyInit__random(void) { - PyObject *m; - - PyObject *Random_Type = PyType_FromSpec(&Random_Type_spec); - if (Random_Type == NULL) { - return NULL; - } - - m = PyModule_Create(&_randommodule); - if (m == NULL) { - Py_DECREF(Random_Type); - return NULL; - } - get_random_state(m)->Random_Type = Random_Type; - - Py_INCREF(Random_Type); - PyModule_AddObject(m, "Random", Random_Type); - - /* Look up and save int.__abs__, which is needed in random_seed(). */ - PyObject *longval = NULL, *longtype = NULL; - longval = PyLong_FromLong(0); - if (longval == NULL) goto fail; - - longtype = PyObject_Type(longval); - if (longtype == NULL) goto fail; - - PyObject *abs = PyObject_GetAttrString(longtype, "__abs__"); - if (abs == NULL) goto fail; - - Py_DECREF(longtype); - Py_DECREF(longval); - get_random_state(m)->Long___abs__ = abs; - - return m; - -fail: - Py_XDECREF(longtype); - Py_XDECREF(longval); - Py_DECREF(m); - return NULL; + return PyModuleDef_Init(&_randommodule); } diff --git a/contrib/tools/python3/src/Modules/_scproxy.c b/contrib/tools/python3/src/Modules/_scproxy.c index dbee3f7367e..4c1f1aa300c 100644 --- a/contrib/tools/python3/src/Modules/_scproxy.c +++ b/contrib/tools/python3/src/Modules/_scproxy.c @@ -231,21 +231,18 @@ static PyMethodDef mod_methods[] = { { 0, 0, 0, 0 } }; +static PyModuleDef_Slot _scproxy_slots[] = { + {0, NULL} +}; - -static struct PyModuleDef mod_module = { +static struct PyModuleDef _scproxy_module = { PyModuleDef_HEAD_INIT, - "_scproxy", - NULL, - -1, - mod_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_scproxy", + .m_size = 0, + .m_methods = mod_methods, + .m_slots = _scproxy_slots, }; - #ifdef __cplusplus extern "C" { #endif @@ -253,10 +250,9 @@ extern "C" { PyMODINIT_FUNC PyInit__scproxy(void) { - return PyModule_Create(&mod_module); + return PyModuleDef_Init(&_scproxy_module); } #ifdef __cplusplus } #endif - diff --git a/contrib/tools/python3/src/Modules/_sha3/sha3module.c b/contrib/tools/python3/src/Modules/_sha3/sha3module.c index b6a7130dd86..3974e0b6b47 100644 --- a/contrib/tools/python3/src/Modules/_sha3/sha3module.c +++ b/contrib/tools/python3/src/Modules/_sha3/sha3module.c @@ -127,6 +127,28 @@ #define SHA3_squeeze Keccak_HashSqueeze #define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) +typedef struct { + PyTypeObject *sha3_224_type; + PyTypeObject *sha3_256_type; + PyTypeObject *sha3_384_type; + PyTypeObject *sha3_512_type; +#ifdef PY_WITH_KECCAK + PyTypeObject *keccak_224_type; + PyTypeObject *keccak_256_type; + PyTypeObject *keccak_384_type; + PyTypeObject *keccak_512_type; +#endif + PyTypeObject *shake_128_type; + PyTypeObject *shake_256_type; +} SHA3State; + +static inline SHA3State* +sha3_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (SHA3State *)state; +} /*[clinic input] module _sha3 @@ -147,19 +169,6 @@ typedef struct { PyThread_type_lock lock; } SHA3object; -static PyTypeObject SHA3_224type; -static PyTypeObject SHA3_256type; -static PyTypeObject SHA3_384type; -static PyTypeObject SHA3_512type; -#ifdef PY_WITH_KECCAK -static PyTypeObject Keccak_224type; -static PyTypeObject Keccak_256type; -static PyTypeObject Keccak_384type; -static PyTypeObject Keccak_512type; -#endif -static PyTypeObject SHAKE128type; -static PyTypeObject SHAKE256type; - #include "clinic/sha3module.c.h" static SHA3object * @@ -189,42 +198,49 @@ static PyObject * py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) /*[clinic end generated code: output=90409addc5d5e8b0 input=bcfcdf2e4368347a]*/ { - SHA3object *self = NULL; - Py_buffer buf = {NULL, NULL}; HashReturn res; - - self = newSHA3object(type); + Py_buffer buf = {NULL, NULL}; + SHA3State *state = PyType_GetModuleState(type); + SHA3object *self = newSHA3object(type); if (self == NULL) { goto error; } - if (type == &SHA3_224type) { + assert(state != NULL); + + if (type == state->sha3_224_type) { res = Keccak_HashInitialize_SHA3_224(&self->hash_state); - } else if (type == &SHA3_256type) { + } else if (type == state->sha3_256_type) { res = Keccak_HashInitialize_SHA3_256(&self->hash_state); - } else if (type == &SHA3_384type) { + } else if (type == state->sha3_384_type) { res = Keccak_HashInitialize_SHA3_384(&self->hash_state); - } else if (type == &SHA3_512type) { + } else if (type == state->sha3_512_type) { res = Keccak_HashInitialize_SHA3_512(&self->hash_state); #ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { + } else if (type == state->keccak_224_type) { res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); - } else if (type == &Keccak_256type) { + } else if (type == state->keccak_256_type) { res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); - } else if (type == &Keccak_384type) { + } else if (type == state->keccak_384_type) { res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); - } else if (type == &Keccak_512type) { + } else if (type == state->keccak_512_type) { res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); #endif - } else if (type == &SHAKE128type) { + } else if (type == state->shake_128_type) { res = Keccak_HashInitialize_SHAKE128(&self->hash_state); - } else if (type == &SHAKE256type) { + } else if (type == state->shake_256_type) { res = Keccak_HashInitialize_SHAKE256(&self->hash_state); } 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) { @@ -267,7 +283,10 @@ SHA3_dealloc(SHA3object *self) if (self->lock) { PyThread_free_lock(self->lock); } - PyObject_Del(self); + + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); } @@ -421,27 +440,31 @@ static PyObject * SHA3_get_name(SHA3object *self, void *closure) { PyTypeObject *type = Py_TYPE(self); - if (type == &SHA3_224type) { + + SHA3State *state = PyType_GetModuleState(type); + assert(state != NULL); + + if (type == state->sha3_224_type) { return PyUnicode_FromString("sha3_224"); - } else if (type == &SHA3_256type) { + } else if (type == state->sha3_256_type) { return PyUnicode_FromString("sha3_256"); - } else if (type == &SHA3_384type) { + } else if (type == state->sha3_384_type) { return PyUnicode_FromString("sha3_384"); - } else if (type == &SHA3_512type) { + } else if (type == state->sha3_512_type) { return PyUnicode_FromString("sha3_512"); #ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { + } else if (type == state->keccak_224_type) { return PyUnicode_FromString("keccak_224"); - } else if (type == &Keccak_256type) { + } else if (type == state->keccak_256_type) { return PyUnicode_FromString("keccak_256"); - } else if (type == &Keccak_384type) { + } else if (type == state->keccak_384_type) { return PyUnicode_FromString("keccak_384"); - } else if (type == &Keccak_512type) { + } else if (type == state->keccak_512_type) { return PyUnicode_FromString("keccak_512"); #endif - } else if (type == &SHAKE128type) { + } else if (type == state->shake_128_type) { return PyUnicode_FromString("shake_128"); - } else if (type == &SHAKE256type) { + } else if (type == state->shake_256_type) { return PyUnicode_FromString("shake_256"); } else { PyErr_BadInternalCall(); @@ -481,7 +504,6 @@ SHA3_get_suffix(SHA3object *self, void *closure) return PyBytes_FromStringAndSize((const char *)suffix, 1); } - static PyGetSetDef SHA3_getseters[] = { {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, @@ -492,48 +514,24 @@ static PyGetSetDef SHA3_getseters[] = { {NULL} /* Sentinel */ }; +#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods) \ + static PyType_Slot type_slots_obj[] = { \ + {Py_tp_dealloc, SHA3_dealloc}, \ + {Py_tp_doc, (char*)type_doc}, \ + {Py_tp_methods, type_methods}, \ + {Py_tp_getset, SHA3_getseters}, \ + {Py_tp_new, py_sha3_new}, \ + {0,0} \ + } -#define SHA3_TYPE(type_obj, type_name, type_doc, type_methods) \ - static PyTypeObject type_obj = { \ - PyVarObject_HEAD_INIT(NULL, 0) \ - type_name, /* tp_name */ \ - sizeof(SHA3object), /* tp_basicsize */ \ - 0, /* tp_itemsize */ \ - /* methods */ \ - (destructor)SHA3_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, /* tp_flags */ \ - type_doc, /* tp_doc */ \ - 0, /* tp_traverse */ \ - 0, /* tp_clear */ \ - 0, /* tp_richcompare */ \ - 0, /* tp_weaklistoffset */ \ - 0, /* tp_iter */ \ - 0, /* tp_iternext */ \ - type_methods, /* tp_methods */ \ - NULL, /* tp_members */ \ - SHA3_getseters, /* 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 */ \ - py_sha3_new, /* tp_new */ \ +// 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 = { \ + .name = "_sha3." type_name, \ + .basicsize = sizeof(SHA3object), \ + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, \ + .slots = type_slots \ } PyDoc_STRVAR(sha3_224__doc__, @@ -556,11 +554,6 @@ PyDoc_STRVAR(sha3_512__doc__, \n\ Return a new SHA3 hash object with a hashbit length of 64 bytes."); -SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", sha3_224__doc__, SHA3_methods); -SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods); -SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods); -SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods); - #ifdef PY_WITH_KECCAK PyDoc_STRVAR(keccak_224__doc__, "keccak_224([data], *, usedforsecurity=True) -> Keccak object\n\ @@ -582,10 +575,32 @@ PyDoc_STRVAR(keccak_512__doc__, \n\ Return a new Keccak hash object with a hashbit length of 64 bytes."); -SHA3_TYPE(Keccak_224type, "_sha3.keccak_224", keccak_224__doc__, SHA3_methods); -SHA3_TYPE(Keccak_256type, "_sha3.keccak_256", keccak_256__doc__, SHA3_methods); -SHA3_TYPE(Keccak_384type, "_sha3.keccak_384", keccak_384__doc__, SHA3_methods); -SHA3_TYPE(Keccak_512type, "_sha3.keccak_512", keccak_512__doc__, SHA3_methods); +#endif + +SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_224_spec, "sha3_224", sha3_224_slots); + +SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_256_spec, "sha3_256", sha3_256_slots); + +SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_384_spec, "sha3_384", sha3_384_slots); + +SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_512_spec, "sha3_512", sha3_512_slots); + +#ifdef PY_WITH_KECCAK +SHA3_TYPE_SLOTS(Keccak_224_slots, keccak_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_224_spec, "keccak_224", Keccak_224_slots); + +SHA3_TYPE_SLOTS(Keccak_256_slots, keccak_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_256_spec, "keccak_256", Keccak_256_slots); + +SHA3_TYPE_SLOTS(Keccak_384_slots, keccak_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_384_spec, "keccak_384", Keccak_384_slots); + +SHA3_TYPE_SLOTS(Keccak_512_slots, keccak_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_512_spec, "keccak_512", Keccak_512_slots); #endif @@ -689,70 +704,118 @@ PyDoc_STRVAR(shake_256__doc__, \n\ Return a new SHAKE hash object."); -SHA3_TYPE(SHAKE128type, "_sha3.shake_128", shake_128__doc__, SHAKE_methods); -SHA3_TYPE(SHAKE256type, "_sha3.shake_256", shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods); +SHA3_TYPE_SPEC(SHAKE128_spec, "shake_128", SHAKE128slots); +SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SPEC(SHAKE256_spec, "shake_256", SHAKE256slots); -/* Initialize this module. */ -static struct PyModuleDef _SHA3module = { - PyModuleDef_HEAD_INIT, - "_sha3", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; +static int +_sha3_traverse(PyObject *module, visitproc visit, void *arg) +{ + SHA3State *state = sha3_get_state(module); + Py_VISIT(state->sha3_224_type); + Py_VISIT(state->sha3_256_type); + Py_VISIT(state->sha3_384_type); + Py_VISIT(state->sha3_512_type); +#ifdef PY_WITH_KECCAK + Py_VISIT(state->keccak_224_type); + Py_VISIT(state->keccak_256_type); + Py_VISIT(state->keccak_384_type); + Py_VISIT(state->keccak_512_type); +#endif + Py_VISIT(state->shake_128_type); + Py_VISIT(state->shake_256_type); + return 0; +} -PyMODINIT_FUNC -PyInit__sha3(void) +static int +_sha3_clear(PyObject *module) { - PyObject *m = NULL; + SHA3State *state = sha3_get_state(module); + Py_CLEAR(state->sha3_224_type); + Py_CLEAR(state->sha3_256_type); + Py_CLEAR(state->sha3_384_type); + Py_CLEAR(state->sha3_512_type); +#ifdef PY_WITH_KECCAK + Py_CLEAR(state->keccak_224_type); + Py_CLEAR(state->keccak_256_type); + Py_CLEAR(state->keccak_384_type); + Py_CLEAR(state->keccak_512_type); +#endif + Py_CLEAR(state->shake_128_type); + Py_CLEAR(state->shake_256_type); + return 0; +} - if ((m = PyModule_Create(&_SHA3module)) == NULL) { - return NULL; - } +static void +_sha3_free(void *module) +{ + _sha3_clear((PyObject *)module); +} -#define init_sha3type(name, type) \ - do { \ - Py_SET_TYPE(type, &PyType_Type); \ - if (PyType_Ready(type) < 0) { \ - goto error; \ - } \ - Py_INCREF((PyObject *)type); \ - if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ - goto error; \ - } \ +static int +_sha3_exec(PyObject *m) +{ + SHA3State *st = sha3_get_state(m); + +#define init_sha3type(type, typespec) \ + do { \ + st->type = (PyTypeObject *)PyType_FromModuleAndSpec( \ + m, &typespec, NULL); \ + if (st->type == NULL) { \ + return -1; \ + } \ + if (PyModule_AddType(m, st->type) < 0) { \ + return -1; \ + } \ } while(0) - init_sha3type("sha3_224", &SHA3_224type); - init_sha3type("sha3_256", &SHA3_256type); - init_sha3type("sha3_384", &SHA3_384type); - init_sha3type("sha3_512", &SHA3_512type); + init_sha3type(sha3_224_type, sha3_224_spec); + init_sha3type(sha3_256_type, sha3_256_spec); + init_sha3type(sha3_384_type, sha3_384_spec); + init_sha3type(sha3_512_type, sha3_512_spec); #ifdef PY_WITH_KECCAK - init_sha3type("keccak_224", &Keccak_224type); - init_sha3type("keccak_256", &Keccak_256type); - init_sha3type("keccak_384", &Keccak_384type); - init_sha3type("keccak_512", &Keccak_512type); + init_sha3type(keccak_224_type, Keccak_224_spec); + init_sha3type(keccak_256_type, Keccak_256_spec); + init_sha3type(keccak_384_type, Keccak_384_spec); + init_sha3type(keccak_512_type, Keccak_512_spec); #endif - init_sha3type("shake_128", &SHAKE128type); - init_sha3type("shake_256", &SHAKE256type); - + init_sha3type(shake_128_type, SHAKE128_spec); + init_sha3type(shake_256_type, SHAKE256_spec); #undef init_sha3type if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { - goto error; + return -1; } if (PyModule_AddStringConstant(m, "implementation", KeccakP1600_implementation) < 0) { - goto error; + return -1; } - return m; - error: - Py_DECREF(m); - return NULL; + return 0; +} + +static PyModuleDef_Slot _sha3_slots[] = { + {Py_mod_exec, _sha3_exec}, + {0, NULL} +}; + +/* Initialize this module. */ +static struct PyModuleDef _sha3module = { + PyModuleDef_HEAD_INIT, + .m_name = "_sha3", + .m_size = sizeof(SHA3State), + .m_slots = _sha3_slots, + .m_traverse = _sha3_traverse, + .m_clear = _sha3_clear, + .m_free = _sha3_free, +}; + + +PyMODINIT_FUNC +PyInit__sha3(void) +{ + return PyModuleDef_Init(&_sha3module); } diff --git a/contrib/tools/python3/src/Modules/_sqlite/cache.c b/contrib/tools/python3/src/Modules/_sqlite/cache.c index 758fc022f78..fd4e619f6a0 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cache.c +++ b/contrib/tools/python3/src/Modules/_sqlite/cache.c @@ -25,20 +25,18 @@ #include /* only used internally */ -pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) +static pysqlite_Node * +pysqlite_new_node(PyObject *key, PyObject *data) { pysqlite_Node* node; - node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0)); + node = (pysqlite_Node*) (pysqlite_NodeType->tp_alloc(pysqlite_NodeType, 0)); if (!node) { return NULL; } - Py_INCREF(key); - node->key = key; - - Py_INCREF(data); - node->data = data; + node->key = Py_NewRef(key); + node->data = Py_NewRef(data); node->prev = NULL; node->next = NULL; @@ -46,15 +44,35 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) return node; } -void pysqlite_node_dealloc(pysqlite_Node* self) +static int +node_traverse(pysqlite_Node *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->key); + Py_VISIT(self->data); + return 0; +} + +static int +node_clear(pysqlite_Node *self) { - Py_DECREF(self->key); - Py_DECREF(self->data); + Py_CLEAR(self->key); + Py_CLEAR(self->data); + return 0; +} - Py_TYPE(self)->tp_free((PyObject*)self); +static void +pysqlite_node_dealloc(pysqlite_Node *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } -int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) +static int +pysqlite_cache_init(pysqlite_Cache *self, PyObject *args, PyObject *kwargs) { PyObject* factory; int size = 10; @@ -78,38 +96,62 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) return -1; } - Py_INCREF(factory); - self->factory = factory; + self->factory = Py_NewRef(factory); self->decref_factory = 1; return 0; } -void pysqlite_cache_dealloc(pysqlite_Cache* self) +static int +cache_traverse(pysqlite_Cache *self, visitproc visit, void *arg) { - pysqlite_Node* node; - pysqlite_Node* delete_node; + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->mapping); + if (self->decref_factory) { + Py_VISIT(self->factory); + } - if (!self->factory) { - /* constructor failed, just get out of here */ - return; + pysqlite_Node *node = self->first; + while (node) { + Py_VISIT(node); + node = node->next; + } + return 0; +} + +static int +cache_clear(pysqlite_Cache *self) +{ + Py_CLEAR(self->mapping); + if (self->decref_factory) { + Py_CLEAR(self->factory); } /* iterate over all nodes and deallocate them */ - node = self->first; + pysqlite_Node *node = self->first; + self->first = NULL; while (node) { - delete_node = node; + pysqlite_Node *delete_node = node; node = node->next; - Py_DECREF(delete_node); + Py_CLEAR(delete_node); } + return 0; +} - if (self->decref_factory) { - Py_DECREF(self->factory); +static void +pysqlite_cache_dealloc(pysqlite_Cache *self) +{ + if (!self->factory) { + /* constructor failed, just get out of here */ + return; } - Py_DECREF(self->mapping); - Py_TYPE(self)->tp_free((PyObject*)self); + PyObject_GC_UnTrack(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_clear((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) @@ -213,11 +255,11 @@ PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) self->last = node; } - Py_INCREF(node->data); - return node->data; + return Py_NewRef(node->data); } -PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) +static PyObject * +pysqlite_cache_display(pysqlite_Cache *self, PyObject *args) { pysqlite_Node* ptr; PyObject* prevkey; @@ -253,6 +295,21 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) Py_RETURN_NONE; } +static PyType_Slot node_slots[] = { + {Py_tp_dealloc, pysqlite_node_dealloc}, + {Py_tp_traverse, node_traverse}, + {Py_tp_clear, node_clear}, + {0, NULL}, +}; + +static PyType_Spec node_spec = { + .name = MODULE_NAME ".Node", + .basicsize = sizeof(pysqlite_Node), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = node_slots, +}; +PyTypeObject *pysqlite_NodeType = NULL; + static PyMethodDef cache_methods[] = { {"get", (PyCFunction)pysqlite_cache_get, METH_O, PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, @@ -261,102 +318,34 @@ static PyMethodDef cache_methods[] = { {NULL, NULL} }; -PyTypeObject pysqlite_NodeType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME "Node", /* tp_name */ - sizeof(pysqlite_Node), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_node_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, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot cache_slots[] = { + {Py_tp_dealloc, pysqlite_cache_dealloc}, + {Py_tp_methods, cache_methods}, + {Py_tp_init, pysqlite_cache_init}, + {Py_tp_traverse, cache_traverse}, + {Py_tp_clear, cache_clear}, + {0, NULL}, }; -PyTypeObject pysqlite_CacheType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cache", /* tp_name */ - sizeof(pysqlite_Cache), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cache_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 */ - cache_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 */ - (initproc)pysqlite_cache_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Spec cache_spec = { + .name = MODULE_NAME ".Cache", + .basicsize = sizeof(pysqlite_Cache), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = cache_slots, }; +PyTypeObject *pysqlite_CacheType = NULL; -extern int pysqlite_cache_setup_types(void) +int +pysqlite_cache_setup_types(PyObject *mod) { - int rc; - - pysqlite_NodeType.tp_new = PyType_GenericNew; - pysqlite_CacheType.tp_new = PyType_GenericNew; - - rc = PyType_Ready(&pysqlite_NodeType); - if (rc < 0) { - return rc; + pysqlite_NodeType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &node_spec, NULL); + if (pysqlite_NodeType == NULL) { + return -1; } - rc = PyType_Ready(&pysqlite_CacheType); - return rc; + pysqlite_CacheType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &cache_spec, NULL); + if (pysqlite_CacheType == NULL) { + return -1; + } + return 0; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/cache.h b/contrib/tools/python3/src/Modules/_sqlite/cache.h index 529010967c4..083356f93f9 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cache.h +++ b/contrib/tools/python3/src/Modules/_sqlite/cache.h @@ -23,8 +23,7 @@ #ifndef PYSQLITE_CACHE_H #define PYSQLITE_CACHE_H -#define PY_SSIZE_T_CLEAN -#include "Python.h" +#include "module.h" /* The LRU cache is implemented as a combination of a doubly-linked with a * dictionary. The list items are of type 'Node' and the dictionary has the @@ -59,16 +58,11 @@ typedef struct int decref_factory; } pysqlite_Cache; -extern PyTypeObject pysqlite_NodeType; -extern PyTypeObject pysqlite_CacheType; +extern PyTypeObject *pysqlite_NodeType; +extern PyTypeObject *pysqlite_CacheType; -int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); -void pysqlite_node_dealloc(pysqlite_Node* self); - -int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); -void pysqlite_cache_dealloc(pysqlite_Cache* self); PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); -int pysqlite_cache_setup_types(void); +int pysqlite_cache_setup_types(PyObject *module); #endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/clinic/connection.c.h b/contrib/tools/python3/src/Modules/_sqlite/clinic/connection.c.h new file mode 100644 index 00000000000..9ddce41e90d --- /dev/null +++ b/contrib/tools/python3/src/Modules/_sqlite/clinic/connection.c.h @@ -0,0 +1,709 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(pysqlite_connection_cursor__doc__, +"cursor($self, /, factory=)\n" +"--\n" +"\n" +"Return a cursor for the connection."); + +#define PYSQLITE_CONNECTION_CURSOR_METHODDEF \ + {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, + +static PyObject * +pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory); + +static PyObject * +pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"factory", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "cursor", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *factory = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + factory = args[0]; +skip_optional_pos: + return_value = pysqlite_connection_cursor_impl(self, factory); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Closes the connection."); + +#define PYSQLITE_CONNECTION_CLOSE_METHODDEF \ + {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, pysqlite_connection_close__doc__}, + +static PyObject * +pysqlite_connection_close_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_close(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_close_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_commit__doc__, +"commit($self, /)\n" +"--\n" +"\n" +"Commit the current transaction."); + +#define PYSQLITE_CONNECTION_COMMIT_METHODDEF \ + {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, pysqlite_connection_commit__doc__}, + +static PyObject * +pysqlite_connection_commit_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_commit(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_commit_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_rollback__doc__, +"rollback($self, /)\n" +"--\n" +"\n" +"Roll back the current transaction."); + +#define PYSQLITE_CONNECTION_ROLLBACK_METHODDEF \ + {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, pysqlite_connection_rollback__doc__}, + +static PyObject * +pysqlite_connection_rollback_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_rollback(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_rollback_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_create_function__doc__, +"create_function($self, /, name, narg, func, *, deterministic=False)\n" +"--\n" +"\n" +"Creates a new function."); + +#define PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF \ + {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_function__doc__}, + +static PyObject * +pysqlite_connection_create_function_impl(pysqlite_Connection *self, + const char *name, int narg, + PyObject *func, int deterministic); + +static PyObject * +pysqlite_connection_create_function(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "narg", "func", "deterministic", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "create_function", 0}; + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + const char *name; + int narg; + PyObject *func; + int deterministic = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_function", "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; + } + narg = _PyLong_AsInt(args[1]); + if (narg == -1 && PyErr_Occurred()) { + goto exit; + } + func = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + deterministic = PyObject_IsTrue(args[3]); + if (deterministic < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = pysqlite_connection_create_function_impl(self, name, narg, func, deterministic); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_create_aggregate__doc__, +"create_aggregate($self, /, name, n_arg, aggregate_class)\n" +"--\n" +"\n" +"Creates a new aggregate."); + +#define PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF \ + {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_aggregate__doc__}, + +static PyObject * +pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, + const char *name, int n_arg, + PyObject *aggregate_class); + +static PyObject * +pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "n_arg", "aggregate_class", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "create_aggregate", 0}; + PyObject *argsbuf[3]; + const char *name; + int n_arg; + PyObject *aggregate_class; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_aggregate", "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; + } + n_arg = _PyLong_AsInt(args[1]); + if (n_arg == -1 && PyErr_Occurred()) { + goto exit; + } + aggregate_class = args[2]; + return_value = pysqlite_connection_create_aggregate_impl(self, name, n_arg, aggregate_class); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_set_authorizer__doc__, +"set_authorizer($self, /, authorizer_callback)\n" +"--\n" +"\n" +"Sets authorizer callback."); + +#define PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF \ + {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_authorizer__doc__}, + +static PyObject * +pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, + PyObject *authorizer_cb); + +static PyObject * +pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"authorizer_callback", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "set_authorizer", 0}; + PyObject *argsbuf[1]; + PyObject *authorizer_cb; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + authorizer_cb = args[0]; + return_value = pysqlite_connection_set_authorizer_impl(self, authorizer_cb); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_set_progress_handler__doc__, +"set_progress_handler($self, /, progress_handler, n)\n" +"--\n" +"\n" +"Sets progress handler callback."); + +#define PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF \ + {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__}, + +static PyObject * +pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, + PyObject *progress_handler, + int n); + +static PyObject * +pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"progress_handler", "n", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "set_progress_handler", 0}; + PyObject *argsbuf[2]; + PyObject *progress_handler; + int n; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + progress_handler = args[0]; + n = _PyLong_AsInt(args[1]); + if (n == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = pysqlite_connection_set_progress_handler_impl(self, progress_handler, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_set_trace_callback__doc__, +"set_trace_callback($self, /, trace_callback)\n" +"--\n" +"\n" +"Sets a trace callback called for each SQL statement (passed as unicode)."); + +#define PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF \ + {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_trace_callback__doc__}, + +static PyObject * +pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, + PyObject *trace_callback); + +static PyObject * +pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"trace_callback", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "set_trace_callback", 0}; + PyObject *argsbuf[1]; + PyObject *trace_callback; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + trace_callback = args[0]; + return_value = pysqlite_connection_set_trace_callback_impl(self, trace_callback); + +exit: + return return_value; +} + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) + +PyDoc_STRVAR(pysqlite_connection_enable_load_extension__doc__, +"enable_load_extension($self, enable, /)\n" +"--\n" +"\n" +"Enable dynamic loading of SQLite extension modules."); + +#define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF \ + {"enable_load_extension", (PyCFunction)pysqlite_connection_enable_load_extension, METH_O, pysqlite_connection_enable_load_extension__doc__}, + +static PyObject * +pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, + int onoff); + +static PyObject * +pysqlite_connection_enable_load_extension(pysqlite_Connection *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int onoff; + + onoff = _PyLong_AsInt(arg); + if (onoff == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = pysqlite_connection_enable_load_extension_impl(self, onoff); + +exit: + return return_value; +} + +#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) + +PyDoc_STRVAR(pysqlite_connection_load_extension__doc__, +"load_extension($self, name, /)\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__}, + +static PyObject * +pysqlite_connection_load_extension_impl(pysqlite_Connection *self, + const char *extension_name); + +static PyObject * +pysqlite_connection_load_extension(pysqlite_Connection *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *extension_name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("load_extension", "argument", "str", arg); + goto exit; + } + Py_ssize_t extension_name_length; + extension_name = PyUnicode_AsUTF8AndSize(arg, &extension_name_length); + if (extension_name == NULL) { + goto exit; + } + if (strlen(extension_name) != (size_t)extension_name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = pysqlite_connection_load_extension_impl(self, extension_name); + +exit: + return return_value; +} + +#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + +PyDoc_STRVAR(pysqlite_connection_execute__doc__, +"execute($self, sql, parameters=, /)\n" +"--\n" +"\n" +"Executes an SQL statement."); + +#define PYSQLITE_CONNECTION_EXECUTE_METHODDEF \ + {"execute", (PyCFunction)(void(*)(void))pysqlite_connection_execute, METH_FASTCALL, pysqlite_connection_execute__doc__}, + +static PyObject * +pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, + PyObject *parameters); + +static PyObject * +pysqlite_connection_execute(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sql; + PyObject *parameters = NULL; + + if (!_PyArg_CheckPositional("execute", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("execute", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + if (nargs < 2) { + goto skip_optional; + } + parameters = args[1]; +skip_optional: + return_value = pysqlite_connection_execute_impl(self, sql, parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_executemany__doc__, +"executemany($self, sql, parameters, /)\n" +"--\n" +"\n" +"Repeatedly executes an SQL statement."); + +#define PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF \ + {"executemany", (PyCFunction)(void(*)(void))pysqlite_connection_executemany, METH_FASTCALL, pysqlite_connection_executemany__doc__}, + +static PyObject * +pysqlite_connection_executemany_impl(pysqlite_Connection *self, + PyObject *sql, PyObject *parameters); + +static PyObject * +pysqlite_connection_executemany(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sql; + PyObject *parameters; + + if (!_PyArg_CheckPositional("executemany", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("executemany", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + parameters = args[1]; + return_value = pysqlite_connection_executemany_impl(self, sql, parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_executescript__doc__, +"executescript($self, sql_script, /)\n" +"--\n" +"\n" +"Executes multiple SQL statements at once."); + +#define PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF \ + {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_O, pysqlite_connection_executescript__doc__}, + +PyDoc_STRVAR(pysqlite_connection_interrupt__doc__, +"interrupt($self, /)\n" +"--\n" +"\n" +"Abort any pending database operation."); + +#define PYSQLITE_CONNECTION_INTERRUPT_METHODDEF \ + {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, pysqlite_connection_interrupt__doc__}, + +static PyObject * +pysqlite_connection_interrupt_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_interrupt(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_interrupt_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_iterdump__doc__, +"iterdump($self, /)\n" +"--\n" +"\n" +"Returns iterator to the dump of the database in an SQL text format."); + +#define PYSQLITE_CONNECTION_ITERDUMP_METHODDEF \ + {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, pysqlite_connection_iterdump__doc__}, + +static PyObject * +pysqlite_connection_iterdump_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_iterdump(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_iterdump_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_backup__doc__, +"backup($self, /, target, *, pages=-1, progress=None, name=\'main\',\n" +" sleep=0.25)\n" +"--\n" +"\n" +"Makes a backup of the database."); + +#define PYSQLITE_CONNECTION_BACKUP_METHODDEF \ + {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_backup__doc__}, + +static PyObject * +pysqlite_connection_backup_impl(pysqlite_Connection *self, + pysqlite_Connection *target, int pages, + PyObject *progress, const char *name, + double sleep); + +static PyObject * +pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0}; + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + pysqlite_Connection *target; + int pages = -1; + PyObject *progress = Py_None; + const char *name = "main"; + double sleep = 0.25; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) { + _PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]); + goto exit; + } + target = (pysqlite_Connection *)args[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + pages = _PyLong_AsInt(args[1]); + if (pages == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + progress = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("backup", "argument 'name'", "str", args[3]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[3], &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_kwonly; + } + } + if (PyFloat_CheckExact(args[4])) { + sleep = PyFloat_AS_DOUBLE(args[4]); + } + else + { + sleep = PyFloat_AsDouble(args[4]); + if (sleep == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +skip_optional_kwonly: + return_value = pysqlite_connection_backup_impl(self, target, pages, progress, name, sleep); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_create_collation__doc__, +"create_collation($self, name, callback, /)\n" +"--\n" +"\n" +"Creates a collation function."); + +#define PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF \ + {"create_collation", (PyCFunction)(void(*)(void))pysqlite_connection_create_collation, METH_FASTCALL, pysqlite_connection_create_collation__doc__}, + +static PyObject * +pysqlite_connection_create_collation_impl(pysqlite_Connection *self, + PyObject *name, PyObject *callable); + +static PyObject * +pysqlite_connection_create_collation(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *callable; + + if (!_PyArg_CheckPositional("create_collation", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_collation", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + name = args[0]; + callable = args[1]; + return_value = pysqlite_connection_create_collation_impl(self, name, callable); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_enter__doc__, +"__enter__($self, /)\n" +"--\n" +"\n" +"Called when the connection is used as a context manager.\n" +"\n" +"Returns itself as a convenience to the caller."); + +#define PYSQLITE_CONNECTION_ENTER_METHODDEF \ + {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, pysqlite_connection_enter__doc__}, + +static PyObject * +pysqlite_connection_enter_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_enter(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_enter_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_exit__doc__, +"__exit__($self, type, value, traceback, /)\n" +"--\n" +"\n" +"Called when the connection is used as a context manager.\n" +"\n" +"If there was any exception, a rollback takes place; otherwise we commit."); + +#define PYSQLITE_CONNECTION_EXIT_METHODDEF \ + {"__exit__", (PyCFunction)(void(*)(void))pysqlite_connection_exit, METH_FASTCALL, pysqlite_connection_exit__doc__}, + +static PyObject * +pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_tb; + + if (!_PyArg_CheckPositional("__exit__", nargs, 3, 3)) { + goto exit; + } + exc_type = args[0]; + exc_value = args[1]; + exc_tb = args[2]; + return_value = pysqlite_connection_exit_impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#ifndef PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF + #define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF +#endif /* !defined(PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF) */ + +#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF + #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF +#endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ +/*[clinic end generated code: output=2f3f3406ba6b4d2e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_sqlite/clinic/cursor.c.h b/contrib/tools/python3/src/Modules/_sqlite/clinic/cursor.c.h new file mode 100644 index 00000000000..c6e35a23d65 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_sqlite/clinic/cursor.c.h @@ -0,0 +1,262 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static int +pysqlite_cursor_init_impl(pysqlite_Cursor *self, + pysqlite_Connection *connection); + +static int +pysqlite_cursor_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + pysqlite_Connection *connection; + + if (Py_IS_TYPE(self, pysqlite_CursorType) && + !_PyArg_NoKeywords("Cursor", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("Cursor", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), pysqlite_ConnectionType)) { + _PyArg_BadArgument("Cursor", "argument 1", (pysqlite_ConnectionType)->tp_name, PyTuple_GET_ITEM(args, 0)); + goto exit; + } + connection = (pysqlite_Connection *)PyTuple_GET_ITEM(args, 0); + return_value = pysqlite_cursor_init_impl((pysqlite_Cursor *)self, connection); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_execute__doc__, +"execute($self, sql, parameters=(), /)\n" +"--\n" +"\n" +"Executes an SQL statement."); + +#define PYSQLITE_CURSOR_EXECUTE_METHODDEF \ + {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_FASTCALL, pysqlite_cursor_execute__doc__}, + +static PyObject * +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters); + +static PyObject * +pysqlite_cursor_execute(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sql; + PyObject *parameters = NULL; + + if (!_PyArg_CheckPositional("execute", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("execute", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + if (nargs < 2) { + goto skip_optional; + } + parameters = args[1]; +skip_optional: + return_value = pysqlite_cursor_execute_impl(self, sql, parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_executemany__doc__, +"executemany($self, sql, seq_of_parameters, /)\n" +"--\n" +"\n" +"Repeatedly executes an SQL statement."); + +#define PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF \ + {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_FASTCALL, pysqlite_cursor_executemany__doc__}, + +static PyObject * +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *seq_of_parameters); + +static PyObject * +pysqlite_cursor_executemany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sql; + PyObject *seq_of_parameters; + + if (!_PyArg_CheckPositional("executemany", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("executemany", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + seq_of_parameters = args[1]; + return_value = pysqlite_cursor_executemany_impl(self, sql, seq_of_parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_executescript__doc__, +"executescript($self, sql_script, /)\n" +"--\n" +"\n" +"Executes multiple SQL statements at once."); + +#define PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF \ + {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_O, pysqlite_cursor_executescript__doc__}, + +PyDoc_STRVAR(pysqlite_cursor_fetchone__doc__, +"fetchone($self, /)\n" +"--\n" +"\n" +"Fetches one row from the resultset."); + +#define PYSQLITE_CURSOR_FETCHONE_METHODDEF \ + {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, pysqlite_cursor_fetchone__doc__}, + +static PyObject * +pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self); + +static PyObject * +pysqlite_cursor_fetchone(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_cursor_fetchone_impl(self); +} + +PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, +"fetchmany($self, /, size=1)\n" +"--\n" +"\n" +"Fetches several rows from the resultset.\n" +"\n" +" size\n" +" The default value is set by the Cursor.arraysize attribute."); + +#define PYSQLITE_CURSOR_FETCHMANY_METHODDEF \ + {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, + +static PyObject * +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows); + +static PyObject * +pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"size", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "fetchmany", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int maxrows = self->arraysize; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + maxrows = _PyLong_AsInt(args[0]); + if (maxrows == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = pysqlite_cursor_fetchmany_impl(self, maxrows); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_fetchall__doc__, +"fetchall($self, /)\n" +"--\n" +"\n" +"Fetches all rows from the resultset."); + +#define PYSQLITE_CURSOR_FETCHALL_METHODDEF \ + {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, pysqlite_cursor_fetchall__doc__}, + +static PyObject * +pysqlite_cursor_fetchall_impl(pysqlite_Cursor *self); + +static PyObject * +pysqlite_cursor_fetchall(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_cursor_fetchall_impl(self); +} + +PyDoc_STRVAR(pysqlite_cursor_setinputsizes__doc__, +"setinputsizes($self, sizes, /)\n" +"--\n" +"\n" +"Required by DB-API. Does nothing in sqlite3."); + +#define PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF \ + {"setinputsizes", (PyCFunction)pysqlite_cursor_setinputsizes, METH_O, pysqlite_cursor_setinputsizes__doc__}, + +PyDoc_STRVAR(pysqlite_cursor_setoutputsize__doc__, +"setoutputsize($self, size, column=None, /)\n" +"--\n" +"\n" +"Required by DB-API. Does nothing in sqlite3."); + +#define PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF \ + {"setoutputsize", (PyCFunction)(void(*)(void))pysqlite_cursor_setoutputsize, METH_FASTCALL, pysqlite_cursor_setoutputsize__doc__}, + +static PyObject * +pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, + PyObject *column); + +static PyObject * +pysqlite_cursor_setoutputsize(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *size; + PyObject *column = Py_None; + + if (!_PyArg_CheckPositional("setoutputsize", nargs, 1, 2)) { + goto exit; + } + size = args[0]; + if (nargs < 2) { + goto skip_optional; + } + column = args[1]; +skip_optional: + return_value = pysqlite_cursor_setoutputsize_impl(self, size, column); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Closes the cursor."); + +#define PYSQLITE_CURSOR_CLOSE_METHODDEF \ + {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, pysqlite_cursor_close__doc__}, + +static PyObject * +pysqlite_cursor_close_impl(pysqlite_Cursor *self); + +static PyObject * +pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_cursor_close_impl(self); +} +/*[clinic end generated code: output=9879e3a5d4ee3847 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_sqlite/clinic/module.c.h b/contrib/tools/python3/src/Modules/_sqlite/clinic/module.c.h new file mode 100644 index 00000000000..2118cb7c424 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_sqlite/clinic/module.c.h @@ -0,0 +1,225 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(pysqlite_complete_statement__doc__, +"complete_statement($module, /, statement)\n" +"--\n" +"\n" +"Checks if a string contains a complete SQL statement."); + +#define PYSQLITE_COMPLETE_STATEMENT_METHODDEF \ + {"complete_statement", (PyCFunction)(void(*)(void))pysqlite_complete_statement, METH_FASTCALL|METH_KEYWORDS, pysqlite_complete_statement__doc__}, + +static PyObject * +pysqlite_complete_statement_impl(PyObject *module, const char *statement); + +static PyObject * +pysqlite_complete_statement(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"statement", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "complete_statement", 0}; + PyObject *argsbuf[1]; + const char *statement; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("complete_statement", "argument 'statement'", "str", args[0]); + goto exit; + } + Py_ssize_t statement_length; + statement = PyUnicode_AsUTF8AndSize(args[0], &statement_length); + if (statement == NULL) { + goto exit; + } + if (strlen(statement) != (size_t)statement_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = pysqlite_complete_statement_impl(module, statement); + +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)(void(*)(void))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, caster, /)\n" +"--\n" +"\n" +"Registers an adapter with sqlite3\'s adapter registry."); + +#define PYSQLITE_REGISTER_ADAPTER_METHODDEF \ + {"register_adapter", (PyCFunction)(void(*)(void))pysqlite_register_adapter, METH_FASTCALL, pysqlite_register_adapter__doc__}, + +static PyObject * +pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, + PyObject *caster); + +static PyObject * +pysqlite_register_adapter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + PyObject *caster; + + if (!_PyArg_CheckPositional("register_adapter", nargs, 2, 2)) { + goto exit; + } + type = (PyTypeObject *)args[0]; + caster = args[1]; + return_value = pysqlite_register_adapter_impl(module, type, caster); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_register_converter__doc__, +"register_converter($module, name, converter, /)\n" +"--\n" +"\n" +"Registers a converter with sqlite3."); + +#define PYSQLITE_REGISTER_CONVERTER_METHODDEF \ + {"register_converter", (PyCFunction)(void(*)(void))pysqlite_register_converter, METH_FASTCALL, pysqlite_register_converter__doc__}, + +static PyObject * +pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, + PyObject *callable); + +static PyObject * +pysqlite_register_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *orig_name; + PyObject *callable; + + if (!_PyArg_CheckPositional("register_converter", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("register_converter", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + orig_name = args[0]; + callable = args[1]; + return_value = pysqlite_register_converter_impl(module, orig_name, callable); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_enable_callback_trace__doc__, +"enable_callback_tracebacks($module, enable, /)\n" +"--\n" +"\n" +"Enable or disable callback functions throwing errors to stderr."); + +#define PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF \ + {"enable_callback_tracebacks", (PyCFunction)pysqlite_enable_callback_trace, METH_O, pysqlite_enable_callback_trace__doc__}, + +static PyObject * +pysqlite_enable_callback_trace_impl(PyObject *module, int enable); + +static PyObject * +pysqlite_enable_callback_trace(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int enable; + + enable = _PyLong_AsInt(arg); + if (enable == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = pysqlite_enable_callback_trace_impl(module, enable); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_adapt__doc__, +"adapt($module, obj, proto=PrepareProtocolType, alt=, /)\n" +"--\n" +"\n" +"Adapt given object to given protocol."); + +#define PYSQLITE_ADAPT_METHODDEF \ + {"adapt", (PyCFunction)(void(*)(void))pysqlite_adapt, METH_FASTCALL, pysqlite_adapt__doc__}, + +static PyObject * +pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, + PyObject *alt); + +static PyObject * +pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *proto = (PyObject*)pysqlite_PrepareProtocolType; + PyObject *alt = NULL; + + if (!_PyArg_CheckPositional("adapt", nargs, 1, 3)) { + goto exit; + } + obj = args[0]; + if (nargs < 2) { + goto skip_optional; + } + proto = args[1]; + if (nargs < 3) { + goto skip_optional; + } + alt = args[2]; +skip_optional: + return_value = pysqlite_adapt_impl(module, obj, proto, alt); + +exit: + return return_value; +} +/*[clinic end generated code: output=6939849a4371122d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_sqlite/clinic/row.c.h b/contrib/tools/python3/src/Modules/_sqlite/clinic/row.c.h new file mode 100644 index 00000000000..7ff110940d0 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_sqlite/clinic/row.c.h @@ -0,0 +1,56 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static PyObject * +pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, + PyObject *data); + +static PyObject * +pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + pysqlite_Cursor *cursor; + PyObject *data; + + if ((type == pysqlite_RowType) && + !_PyArg_NoKeywords("Row", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("Row", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), pysqlite_CursorType)) { + _PyArg_BadArgument("Row", "argument 1", (pysqlite_CursorType)->tp_name, PyTuple_GET_ITEM(args, 0)); + goto exit; + } + cursor = (pysqlite_Cursor *)PyTuple_GET_ITEM(args, 0); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 1))) { + _PyArg_BadArgument("Row", "argument 2", "tuple", PyTuple_GET_ITEM(args, 1)); + goto exit; + } + data = PyTuple_GET_ITEM(args, 1); + return_value = pysqlite_row_new_impl(type, cursor, data); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_row_keys__doc__, +"keys($self, /)\n" +"--\n" +"\n" +"Returns the keys of the row."); + +#define PYSQLITE_ROW_KEYS_METHODDEF \ + {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, pysqlite_row_keys__doc__}, + +static PyObject * +pysqlite_row_keys_impl(pysqlite_Row *self); + +static PyObject * +pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_row_keys_impl(self); +} +/*[clinic end generated code: output=8d29220b9cde035d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_sqlite/connection.c b/contrib/tools/python3/src/Modules/_sqlite/connection.c index 67688e87537..c9c10b41398 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/connection.c +++ b/contrib/tools/python3/src/Modules/_sqlite/connection.c @@ -33,15 +33,16 @@ #define ACTION_FINALIZE 1 #define ACTION_RESET 2 -#if SQLITE_VERSION_NUMBER >= 3003008 -#ifndef SQLITE_OMIT_LOAD_EXTENSION -#define HAVE_LOAD_EXTENSION -#endif +#if SQLITE_VERSION_NUMBER >= 3014000 +#define HAVE_TRACE_V2 #endif -#if SQLITE_VERSION_NUMBER >= 3006011 -#define HAVE_BACKUP_API -#endif +#include "clinic/connection.c.h" +/*[clinic input] +module _sqlite3 +class _sqlite3.Connection "pysqlite_Connection *" "pysqlite_ConnectionType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa796073bd8f69db]*/ _Py_IDENTIFIER(cursor); @@ -56,20 +57,9 @@ static const char * const begin_statements[] = { static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored)); static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); - -static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len) -{ - /* in older SQLite versions, calling sqlite3_result_error in callbacks - * triggers a bug in SQLite that leads either to irritating results or - * segfaults, depending on the SQLite version */ -#if SQLITE_VERSION_NUMBER >= 3003003 - sqlite3_result_error(ctx, errmsg, len); -#else - PyErr_SetString(pysqlite_OperationalError, errmsg); -#endif -} - -int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +static int +pysqlite_connection_init(pysqlite_Connection *self, PyObject *args, + PyObject *kwargs) { static char *kwlist[] = { "database", "timeout", "detect_types", "isolation_level", @@ -115,21 +105,10 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject Py_INCREF(&PyUnicode_Type); Py_XSETREF(self->text_factory, (PyObject*)&PyUnicode_Type); -#ifdef SQLITE_OPEN_URI Py_BEGIN_ALLOW_THREADS rc = sqlite3_open_v2(database, &self->db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | (uri ? SQLITE_OPEN_URI : 0), NULL); -#else - if (uri) { - PyErr_SetString(pysqlite_NotSupportedError, "URIs not supported"); - return -1; - } - Py_BEGIN_ALLOW_THREADS - /* No need to use sqlite3_open_v2 as sqlite3_open(filename, db) is the - same as sqlite3_open_v2(filename, db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL). */ - rc = sqlite3_open(database, &self->db); -#endif Py_END_ALLOW_THREADS Py_DECREF(database_obj); @@ -158,7 +137,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject } Py_DECREF(isolation_level); - self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); + self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)pysqlite_CacheType, "Oi", self, cached_statements); if (PyErr_Occurred()) { return -1; } @@ -185,10 +164,6 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); self->thread_ident = PyThread_get_thread_ident(); - if (!check_same_thread && sqlite3_libversion_number() < 3003001) { - PyErr_SetString(pysqlite_NotSupportedError, "shared connections not available"); - return -1; - } self->check_same_thread = check_same_thread; self->function_pinboard_trace_callback = NULL; @@ -211,13 +186,19 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject self->ProgrammingError = pysqlite_ProgrammingError; self->NotSupportedError = pysqlite_NotSupportedError; + if (PySys_Audit("sqlite3.connect/handle", "O", self) < 0) { + return -1; + } + self->initialized = 1; return 0; } /* action in (ACTION_RESET, ACTION_FINALIZE) */ -void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset_cursors) +static void +pysqlite_do_all_statements(pysqlite_Connection *self, int action, + int reset_cursors) { int i; PyObject* weakref; @@ -249,25 +230,53 @@ void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset } } -void pysqlite_connection_dealloc(pysqlite_Connection* self) +static int +connection_traverse(pysqlite_Connection *self, visitproc visit, void *arg) { - Py_XDECREF(self->statement_cache); + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->isolation_level); + Py_VISIT(self->statement_cache); + Py_VISIT(self->statements); + Py_VISIT(self->cursors); + Py_VISIT(self->row_factory); + Py_VISIT(self->text_factory); + Py_VISIT(self->function_pinboard_trace_callback); + Py_VISIT(self->function_pinboard_progress_handler); + Py_VISIT(self->function_pinboard_authorizer_cb); + Py_VISIT(self->collations); + return 0; +} + +static int +connection_clear(pysqlite_Connection *self) +{ + Py_CLEAR(self->isolation_level); + Py_CLEAR(self->statement_cache); + Py_CLEAR(self->statements); + Py_CLEAR(self->cursors); + Py_CLEAR(self->row_factory); + Py_CLEAR(self->text_factory); + Py_CLEAR(self->function_pinboard_trace_callback); + Py_CLEAR(self->function_pinboard_progress_handler); + Py_CLEAR(self->function_pinboard_authorizer_cb); + Py_CLEAR(self->collations); + return 0; +} + +static void +connection_dealloc(pysqlite_Connection *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear((PyObject *)self); /* Clean up if user has not called .close() explicitly. */ if (self->db) { - SQLITE3_CLOSE(self->db); - } - - Py_XDECREF(self->isolation_level); - Py_XDECREF(self->function_pinboard_trace_callback); - Py_XDECREF(self->function_pinboard_progress_handler); - Py_XDECREF(self->function_pinboard_authorizer_cb); - Py_XDECREF(self->row_factory); - Py_XDECREF(self->text_factory); - Py_XDECREF(self->collations); - Py_XDECREF(self->statements); - Py_XDECREF(self->cursors); - Py_TYPE(self)->tp_free((PyObject*)self); + sqlite3_close_v2(self->db); + } + + tp->tp_free(self); + Py_DECREF(tp); } /* @@ -296,29 +305,32 @@ error: return 0; } -PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +/*[clinic input] +_sqlite3.Connection.cursor as pysqlite_connection_cursor + + factory: object = NULL + +Return a cursor for the connection. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) +/*[clinic end generated code: output=562432a9e6af2aa1 input=4127345aa091b650]*/ { - static char *kwlist[] = {"factory", NULL}; - PyObject* factory = NULL; PyObject* cursor; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, - &factory)) { - return NULL; - } - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (factory == NULL) { - factory = (PyObject*)&pysqlite_CursorType; + factory = (PyObject*)pysqlite_CursorType; } cursor = PyObject_CallOneArg(factory, (PyObject *)self); if (cursor == NULL) return NULL; - if (!PyObject_TypeCheck(cursor, &pysqlite_CursorType)) { + if (!PyObject_TypeCheck(cursor, pysqlite_CursorType)) { PyErr_Format(PyExc_TypeError, "factory must return a cursor, not %.100s", Py_TYPE(cursor)->tp_name); @@ -336,7 +348,15 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, return cursor; } -PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.close as pysqlite_connection_close + +Closes the connection. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_close_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=a546a0da212c9b97 input=3d58064bbffaa3d3]*/ { int rc; @@ -353,7 +373,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); if (self->db) { - rc = SQLITE3_CLOSE(self->db); + rc = sqlite3_close_v2(self->db); if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -389,11 +409,11 @@ int pysqlite_check_connection(pysqlite_Connection* con) PyObject* _pysqlite_connection_begin(pysqlite_Connection* self) { int rc; - const char* tail; sqlite3_stmt* statement; Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement, &tail); + rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement, + NULL); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { @@ -422,10 +442,17 @@ error: } } -PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.commit as pysqlite_connection_commit + +Commit the current transaction. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_commit_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=3da45579e89407f2 input=39c12c04dda276a8]*/ { int rc; - const char* tail; sqlite3_stmt* statement; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { @@ -435,7 +462,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) if (!sqlite3_get_autocommit(self->db)) { Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(self->db, "COMMIT", -1, &statement, &tail); + rc = sqlite3_prepare_v2(self->db, "COMMIT", -1, &statement, NULL); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -464,10 +491,17 @@ error: } } -PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.rollback as pysqlite_connection_rollback + +Roll back the current transaction. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_rollback_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=b66fa0d43e7ef305 input=12d4e8d068942830]*/ { int rc; - const char* tail; sqlite3_stmt* statement; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { @@ -478,7 +512,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args pysqlite_do_all_statements(self, ACTION_RESET, 1); Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(self->db, "ROLLBACK", -1, &statement, &tail); + rc = sqlite3_prepare_v2(self->db, "ROLLBACK", -1, &statement, NULL); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -556,13 +590,14 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) return 0; } -PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv) +static PyObject * +_pysqlite_build_py_params(sqlite3_context *context, int argc, + sqlite3_value **argv) { PyObject* args; int i; sqlite3_value* cur_value; PyObject* cur_py_value; - Py_ssize_t buflen; args = PyTuple_New(argc); if (!args) { @@ -591,23 +626,29 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_ cur_py_value = PyUnicode_FromStringAndSize(text, size); break; } - case SQLITE_BLOB: - buflen = sqlite3_value_bytes(cur_value); - cur_py_value = PyBytes_FromStringAndSize( - sqlite3_value_blob(cur_value), buflen); + case SQLITE_BLOB: { + sqlite3 *db = sqlite3_context_db_handle(context); + const void *blob = sqlite3_value_blob(cur_value); + + if (blob == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { + PyErr_NoMemory(); + goto error; + } + + Py_ssize_t size = sqlite3_value_bytes(cur_value); + cur_py_value = PyBytes_FromStringAndSize(blob, size); break; + } case SQLITE_NULL: default: - Py_INCREF(Py_None); - cur_py_value = Py_None; + cur_py_value = Py_NewRef(Py_None); } if (!cur_py_value) { goto error; } - PyTuple_SetItem(args, i, cur_py_value); - + PyTuple_SET_ITEM(args, i, cur_py_value); } return args; @@ -617,7 +658,8 @@ error: return NULL; } -void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** argv) +static void +_pysqlite_func_callback(sqlite3_context *context, int argc, sqlite3_value **argv) { PyObject* args; PyObject* py_func; @@ -647,7 +689,7 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined function raised exception", -1); + sqlite3_result_error(context, "user-defined function raised exception", -1); } PyGILState_Release(threadstate); @@ -679,7 +721,7 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_ } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); + sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); goto error; } } @@ -703,7 +745,7 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_ } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); + sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); } error: @@ -713,21 +755,25 @@ error: PyGILState_Release(threadstate); } -void _pysqlite_final_callback(sqlite3_context* context) +static void +_pysqlite_final_callback(sqlite3_context *context) { PyObject* function_result; PyObject** aggregate_instance; _Py_IDENTIFIER(finalize); int ok; PyObject *exception, *value, *tb; - int restore; PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); - aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); - if (!*aggregate_instance) { + aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, 0); + if (aggregate_instance == NULL) { + /* No rows matched the query; the step handler was never called. */ + goto error; + } + else if (!*aggregate_instance) { /* this branch is executed if there was an exception in the aggregate's * __init__ */ @@ -736,7 +782,6 @@ void _pysqlite_final_callback(sqlite3_context* context) /* Keep the exception (if any) of the last call to step() */ PyErr_Fetch(&exception, &value, &tb); - restore = 1; function_result = _PyObject_CallMethodIdNoArgs(*aggregate_instance, &PyId_finalize); @@ -753,19 +798,12 @@ void _pysqlite_final_callback(sqlite3_context* context) } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); -#if SQLITE_VERSION_NUMBER < 3003003 - /* with old SQLite versions, _sqlite3_result_error() sets a new Python - exception, so don't restore the previous exception */ - restore = 0; -#endif + sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); } - if (restore) { - /* Restore the exception (if any) of the last call to step(), - but clear also the current exception if finalize() failed */ - PyErr_Restore(exception, value, tb); - } + /* Restore the exception (if any) of the last call to step(), + but clear also the current exception if finalize() failed */ + PyErr_Restore(exception, value, tb); error: PyGILState_Release(threadstate); @@ -835,30 +873,39 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) static void _destructor(void* args) { + // This function may be called without the GIL held, so we need to ensure + // that we destroy 'args' with the GIL + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); Py_DECREF((PyObject*)args); + PyGILState_Release(gstate); } -PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; +/*[clinic input] +_sqlite3.Connection.create_function as pysqlite_connection_create_function - PyObject* func; - char* name; - int narg; + name: str + narg: int + func: object + * + deterministic: bool = False + +Creates a new function. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_create_function_impl(pysqlite_Connection *self, + const char *name, int narg, + PyObject *func, int deterministic) +/*[clinic end generated code: output=07d1877dd98c0308 input=17e16b285ee44819]*/ +{ int rc; - int deterministic = 0; int flags = SQLITE_UTF8; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|$p", kwlist, - &name, &narg, &func, &deterministic)) - { - return NULL; - } - if (deterministic) { #if SQLITE_VERSION_NUMBER < 3008003 PyErr_SetString(pysqlite_NotSupportedError, @@ -873,12 +920,11 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec flags |= SQLITE_DETERMINISTIC; #endif } - Py_INCREF(func); rc = sqlite3_create_function_v2(self->db, name, narg, flags, - (void*)func, + (void*)Py_NewRef(func), _pysqlite_func_callback, NULL, NULL, @@ -892,29 +938,33 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec Py_RETURN_NONE; } -PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* aggregate_class; +/*[clinic input] +_sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate + + name: str + n_arg: int + aggregate_class: object - int n_arg; - char* name; - static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL }; +Creates a new aggregate. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, + const char *name, int n_arg, + PyObject *aggregate_class) +/*[clinic end generated code: output=fbb2f858cfa4d8db input=a17afd1fcc930ecf]*/ +{ int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate", - kwlist, &name, &n_arg, &aggregate_class)) { - return NULL; - } - Py_INCREF(aggregate_class); rc = sqlite3_create_function_v2(self->db, name, n_arg, SQLITE_UTF8, - (void*)aggregate_class, + (void*)Py_NewRef(aggregate_class), 0, &_pysqlite_step_callback, &_pysqlite_final_callback, @@ -993,13 +1043,29 @@ static int _progress_handler(void* user_arg) return rc; } +#ifdef HAVE_TRACE_V2 +/* + * From https://sqlite.org/c3ref/trace_v2.html: + * The integer return value from the callback is currently ignored, though this + * may change in future releases. Callback implementations should return zero + * to ensure future compatibility. + */ +static int _trace_callback(unsigned int type, void* user_arg, void* prepared_statement, void* statement_string) +#else static void _trace_callback(void* user_arg, const char* statement_string) +#endif { PyObject *py_statement = NULL; PyObject *ret = NULL; PyGILState_STATE gilstate; +#ifdef HAVE_TRACE_V2 + if (type != SQLITE_TRACE_STMT) { + return 0; + } +#endif + gilstate = PyGILState_Ensure(); py_statement = PyUnicode_DecodeUTF8(statement_string, strlen(statement_string), "replace"); @@ -1019,24 +1085,30 @@ static void _trace_callback(void* user_arg, const char* statement_string) } PyGILState_Release(gilstate); +#ifdef HAVE_TRACE_V2 + return 0; +#endif } -static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* authorizer_cb; +/*[clinic input] +_sqlite3.Connection.set_authorizer as pysqlite_connection_set_authorizer + + authorizer_callback as authorizer_cb: object - static char *kwlist[] = { "authorizer_callback", NULL }; +Sets authorizer callback. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, + PyObject *authorizer_cb) +/*[clinic end generated code: output=f18ba575d788b35c input=446676a87c949d68]*/ +{ int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer", - kwlist, &authorizer_cb)) { - return NULL; - } - rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); if (rc != SQLITE_OK) { PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); @@ -1049,19 +1121,22 @@ static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, P Py_RETURN_NONE; } -static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* progress_handler; - int n; +/*[clinic input] +_sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_handler - static char *kwlist[] = { "progress_handler", "n", NULL }; + progress_handler: object + n: int - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } +Sets progress handler callback. +[clinic start generated code]*/ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi:set_progress_handler", - kwlist, &progress_handler, &n)) { +static PyObject * +pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, + PyObject *progress_handler, + int n) +/*[clinic end generated code: output=35a7c10364cb1b04 input=d9379b629c7391c7]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } @@ -1077,27 +1152,43 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s Py_RETURN_NONE; } -static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* trace_callback; +/*[clinic input] +_sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback - static char *kwlist[] = { "trace_callback", NULL }; + trace_callback: object - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } +Sets a trace callback called for each SQL statement (passed as unicode). +[clinic start generated code]*/ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_trace_callback", - kwlist, &trace_callback)) { +static PyObject * +pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, + PyObject *trace_callback) +/*[clinic end generated code: output=fb0e307b9924d454 input=885e460ebbf79f0c]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (trace_callback == Py_None) { - /* None clears the trace callback previously set */ + /* + * None clears the trace callback previously set + * + * Ref. + * - https://sqlite.org/c3ref/c_trace.html + * - https://sqlite.org/c3ref/trace_v2.html + */ +#ifdef HAVE_TRACE_V2 + sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, 0, 0); +#else sqlite3_trace(self->db, 0, (void*)0); +#endif Py_XSETREF(self->function_pinboard_trace_callback, NULL); } else { +#ifdef HAVE_TRACE_V2 + sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, _trace_callback, trace_callback); +#else sqlite3_trace(self->db, _trace_callback, trace_callback); +#endif Py_INCREF(trace_callback); Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); } @@ -1105,17 +1196,29 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel Py_RETURN_NONE; } -#ifdef HAVE_LOAD_EXTENSION -static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObject* args) +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/*[clinic input] +_sqlite3.Connection.enable_load_extension as pysqlite_connection_enable_load_extension + + enable as onoff: bool(accept={int}) + / + +Enable dynamic loading of SQLite extension modules. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, + int onoff) +/*[clinic end generated code: output=9cac37190d388baf input=5f00e93f7a9d3540]*/ { int rc; - int onoff; - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + if (PySys_Audit("sqlite3.enable_load_extension", + "OO", self, onoff ? Py_True : Py_False) < 0) { return NULL; } - if (!PyArg_ParseTuple(args, "i", &onoff)) { + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } @@ -1129,17 +1232,28 @@ static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObj } } -static PyObject* pysqlite_load_extension(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.load_extension as pysqlite_connection_load_extension + + name as extension_name: str + / + +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]*/ { int rc; - char* extension_name; char* errmsg; - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + if (PySys_Audit("sqlite3.load_extension", "Os", self, extension_name) < 0) { return NULL; } - if (!PyArg_ParseTuple(args, "s", &extension_name)) { + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } @@ -1173,8 +1287,7 @@ static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* se if (!pysqlite_check_connection(self)) { return NULL; } - Py_INCREF(self->isolation_level); - return self->isolation_level; + return Py_NewRef(self->isolation_level); } static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self, void* unused) @@ -1254,12 +1367,13 @@ pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* iso return 0; } -PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +static PyObject * +pysqlite_connection_call(pysqlite_Connection *self, PyObject *args, + PyObject *kwargs) { PyObject* sql; pysqlite_Statement* statement; PyObject* weakref; - int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1273,31 +1387,11 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py _pysqlite_drop_unused_statement_references(self); - statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); - if (!statement) { + statement = pysqlite_statement_create(self, sql); + if (statement == NULL) { return NULL; } - statement->db = NULL; - statement->st = NULL; - statement->sql = NULL; - statement->in_use = 0; - statement->in_weakreflist = NULL; - - rc = pysqlite_statement_create(statement, self, sql); - if (rc != SQLITE_OK) { - if (rc == PYSQLITE_TOO_MUCH_SQL) { - PyErr_SetString(pysqlite_Warning, "You can only execute one statement at a time."); - } else if (rc == PYSQLITE_SQL_WRONG_TYPE) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_SetString(pysqlite_Warning, "SQL is of wrong type. Must be string."); - } else { - (void)pysqlite_statement_reset(statement); - _pysqlite_seterror(self->db, NULL); - } - goto error; - } - weakref = PyWeakref_NewRef((PyObject*)statement, NULL); if (weakref == NULL) goto error; @@ -1314,89 +1408,108 @@ error: return NULL; } -PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.execute as pysqlite_connection_execute + + sql: unicode + parameters: object = NULL + / + +Executes an SQL statement. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, + PyObject *parameters) +/*[clinic end generated code: output=5be05ae01ee17ee4 input=27aa7792681ddba2]*/ { + _Py_IDENTIFIER(execute); PyObject* cursor = 0; PyObject* result = 0; - PyObject* method = 0; cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } - method = PyObject_GetAttrString(cursor, "execute"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); + result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_execute, sql, parameters, NULL); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); - Py_XDECREF(method); return cursor; } -PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.executemany as pysqlite_connection_executemany + + sql: unicode + parameters: object + / + +Repeatedly executes an SQL statement. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_executemany_impl(pysqlite_Connection *self, + PyObject *sql, PyObject *parameters) +/*[clinic end generated code: output=776cd2fd20bfe71f input=495be76551d525db]*/ { + _Py_IDENTIFIER(executemany); PyObject* cursor = 0; PyObject* result = 0; - PyObject* method = 0; cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } - method = PyObject_GetAttrString(cursor, "executemany"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); + result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_executemany, sql, + parameters, NULL); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); - Py_XDECREF(method); return cursor; } -PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.executescript as pysqlite_connection_executescript + + sql_script as script_obj: object + / + +Executes multiple SQL statements at once. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_executescript(pysqlite_Connection *self, + PyObject *script_obj) +/*[clinic end generated code: output=4c4f9d77aa0ae37d input=f6e5f1ccfa313db4]*/ { + _Py_IDENTIFIER(executescript); PyObject* cursor = 0; PyObject* result = 0; - PyObject* method = 0; cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } - method = PyObject_GetAttrString(cursor, "executescript"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); + result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_executescript, + script_obj, NULL); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); - Py_XDECREF(method); return cursor; } @@ -1456,8 +1569,15 @@ finally: return result; } +/*[clinic input] +_sqlite3.Connection.interrupt as pysqlite_connection_interrupt + +Abort any pending database operation. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_interrupt(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_interrupt_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=f193204bc9e70b47 input=75ad03ade7012859]*/ { PyObject* retval = NULL; @@ -1467,8 +1587,7 @@ pysqlite_connection_interrupt(pysqlite_Connection* self, PyObject* args) sqlite3_interrupt(self->db); - Py_INCREF(Py_None); - retval = Py_None; + retval = Py_NewRef(Py_None); finally: return retval; @@ -1478,8 +1597,15 @@ finally: * Class method of Connection to call the Python function _iterdump * of the sqlite3 module. */ +/*[clinic input] +_sqlite3.Connection.iterdump as pysqlite_connection_iterdump + +Returns iterator to the dump of the database in an SQL text format. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_iterdump_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=586997aaf9808768 input=1911ca756066da89]*/ { _Py_IDENTIFIER(_iterdump); PyObject* retval = NULL; @@ -1517,52 +1643,40 @@ finally: return retval; } -#ifdef HAVE_BACKUP_API +/*[clinic input] +_sqlite3.Connection.backup as pysqlite_connection_backup + + target: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType') + * + pages: int = -1 + progress: object = None + name: str = "main" + sleep: double = 0.250 + +Makes a backup of the database. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *kwds) +pysqlite_connection_backup_impl(pysqlite_Connection *self, + pysqlite_Connection *target, int pages, + PyObject *progress, const char *name, + double sleep) +/*[clinic end generated code: output=306a3e6a38c36334 input=458a0b6997c4960b]*/ { - PyObject *target = NULL; - int pages = -1; - PyObject *progress = Py_None; - const char *name = "main"; int rc; - int callback_error = 0; - PyObject *sleep_obj = NULL; - int sleep_ms = 250; + int sleep_ms = (int)(sleep * 1000.0); sqlite3 *bck_conn; sqlite3_backup *bck_handle; - static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, - &pysqlite_ConnectionType, &target, - &pages, &progress, &name, &sleep_obj)) { - return NULL; - } - - if (sleep_obj != NULL) { - _PyTime_t sleep_secs; - if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj, - _PyTime_ROUND_TIMEOUT)) { - return NULL; - } - _PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs, - _PyTime_ROUND_TIMEOUT); - if (ms < INT_MIN || ms > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "sleep is too large"); - return NULL; - } - sleep_ms = (int)ms; - } if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!pysqlite_check_connection((pysqlite_Connection *)target)) { + if (!pysqlite_check_connection(target)) { return NULL; } - if ((pysqlite_Connection *)target == self) { + if (target == self) { PyErr_SetString(PyExc_ValueError, "target cannot be the same connection instance"); return NULL; } @@ -1570,7 +1684,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * #if SQLITE_VERSION_NUMBER < 3008008 /* Since 3.8.8 this is already done, per commit https://www.sqlite.org/src/info/169b5505498c0a7e */ - if (!sqlite3_get_autocommit(((pysqlite_Connection *)target)->db)) { + if (!sqlite3_get_autocommit(target->db)) { PyErr_SetString(pysqlite_OperationalError, "target is in transaction"); return NULL; } @@ -1585,102 +1699,74 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * pages = -1; } - bck_conn = ((pysqlite_Connection *)target)->db; + bck_conn = target->db; Py_BEGIN_ALLOW_THREADS bck_handle = sqlite3_backup_init(bck_conn, "main", self->db, name); Py_END_ALLOW_THREADS - if (bck_handle) { - do { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_backup_step(bck_handle, pages); - Py_END_ALLOW_THREADS + if (bck_handle == NULL) { + _pysqlite_seterror(bck_conn, NULL); + return NULL; + } - if (progress != Py_None) { - PyObject *res; - - res = PyObject_CallFunction(progress, "iii", rc, - sqlite3_backup_remaining(bck_handle), - sqlite3_backup_pagecount(bck_handle)); - if (res == NULL) { - /* User's callback raised an error: interrupt the loop and - propagate it. */ - callback_error = 1; - rc = -1; - } else { - Py_DECREF(res); - } - } + do { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_backup_step(bck_handle, pages); + Py_END_ALLOW_THREADS - /* Sleep for a while if there are still further pages to copy and - the engine could not make any progress */ - if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { + if (progress != Py_None) { + int remaining = sqlite3_backup_remaining(bck_handle); + int pagecount = sqlite3_backup_pagecount(bck_handle); + PyObject *res = PyObject_CallFunction(progress, "iii", rc, + remaining, pagecount); + if (res == NULL) { + /* Callback failed: abort backup and bail. */ Py_BEGIN_ALLOW_THREADS - sqlite3_sleep(sleep_ms); + sqlite3_backup_finish(bck_handle); Py_END_ALLOW_THREADS + return NULL; } - } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_backup_finish(bck_handle); - Py_END_ALLOW_THREADS - } else { - rc = _pysqlite_seterror(bck_conn, NULL); - } + Py_DECREF(res); + } - if (!callback_error && rc != SQLITE_OK) { - /* We cannot use _pysqlite_seterror() here because the backup APIs do - not set the error status on the connection object, but rather on - the backup handle. */ - if (rc == SQLITE_NOMEM) { - (void)PyErr_NoMemory(); - } else { -#if SQLITE_VERSION_NUMBER > 3007015 - PyErr_SetString(pysqlite_OperationalError, sqlite3_errstr(rc)); -#else - switch (rc) { - case SQLITE_ERROR: - /* Description of SQLITE_ERROR in SQLite 3.7.14 and older - releases. */ - PyErr_SetString(pysqlite_OperationalError, - "SQL logic error or missing database"); - break; - case SQLITE_READONLY: - PyErr_SetString(pysqlite_OperationalError, - "attempt to write a readonly database"); - break; - case SQLITE_BUSY: - PyErr_SetString(pysqlite_OperationalError, "database is locked"); - break; - case SQLITE_LOCKED: - PyErr_SetString(pysqlite_OperationalError, - "database table is locked"); - break; - default: - PyErr_Format(pysqlite_OperationalError, - "unrecognized error code: %d", rc); - break; - } -#endif + /* Sleep for a while if there are still further pages to copy and + the engine could not make any progress */ + if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { + Py_BEGIN_ALLOW_THREADS + sqlite3_sleep(sleep_ms); + Py_END_ALLOW_THREADS } - } + } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); - if (!callback_error && rc == SQLITE_OK) { - Py_RETURN_NONE; - } else { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_backup_finish(bck_handle); + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK) { + _pysqlite_seterror(bck_conn, NULL); return NULL; } + + Py_RETURN_NONE; } -#endif + +/*[clinic input] +_sqlite3.Connection.create_collation as pysqlite_connection_create_collation + + name: unicode + callback as callable: object + / + +Creates a collation function. +[clinic start generated code]*/ static PyObject * -pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_create_collation_impl(pysqlite_Connection *self, + PyObject *name, PyObject *callable) +/*[clinic end generated code: output=0f63b8995565ae22 input=eb2c4328dc493ee8]*/ { - PyObject* callable; PyObject* uppercase_name = 0; - PyObject* name; - PyObject* retval; Py_ssize_t i, len; _Py_IDENTIFIER(upper); const char *uppercase_name_str; @@ -1692,11 +1778,6 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) goto finally; } - if (!PyArg_ParseTuple(args, "UO:create_collation(name, callback)", - &name, &callable)) { - goto finally; - } - uppercase_name = _PyObject_CallMethodIdOneArg((PyObject *)&PyUnicode_Type, &PyId_upper, name); if (!uppercase_name) { @@ -1757,42 +1838,53 @@ finally: Py_XDECREF(uppercase_name); if (PyErr_Occurred()) { - retval = NULL; - } else { - Py_INCREF(Py_None); - retval = Py_None; + return NULL; } - - return retval; + return Py_NewRef(Py_None); } -/* Called when the connection is used as a context manager. Returns itself as a - * convenience to the caller. */ +/*[clinic input] +_sqlite3.Connection.__enter__ as pysqlite_connection_enter + +Called when the connection is used as a context manager. + +Returns itself as a convenience to the caller. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_enter(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_enter_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=457b09726d3e9dcd input=127d7a4f17e86d8f]*/ { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef((PyObject *)self); } -/** Called when the connection is used as a context manager. If there was any - * exception, a rollback takes place; otherwise we commit. */ +/*[clinic input] +_sqlite3.Connection.__exit__ as pysqlite_connection_exit + + type as exc_type: object + value as exc_value: object + traceback as exc_tb: object + / + +Called when the connection is used as a context manager. + +If there was any exception, a rollback takes place; otherwise we commit. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=0705200e9321202a input=bd66f1532c9c54a7]*/ { - PyObject *exc_type, *exc_value, *exc_tb; - if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &exc_tb)) { - return NULL; - } - int commit = 0; - PyObject *result; + PyObject* result; + if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) { commit = 1; - result = pysqlite_connection_commit(self, NULL); + result = pysqlite_connection_commit_impl(self); } else { - result = pysqlite_connection_rollback(self, NULL); + result = pysqlite_connection_rollback_impl(self); } if (result == NULL) { @@ -1801,7 +1893,7 @@ pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) * If rollback also fails, chain the exceptions. */ PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); - result = pysqlite_connection_rollback(self, NULL); + result = pysqlite_connection_rollback_impl(self); if (result == NULL) { _PyErr_ChainExceptions(exc, val, tb); } @@ -1828,50 +1920,26 @@ static PyGetSetDef connection_getset[] = { }; static PyMethodDef connection_methods[] = { - {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Return a cursor for the connection.")}, - {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, - PyDoc_STR("Closes the connection.")}, - {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, - PyDoc_STR("Commit the current transaction.")}, - {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, - PyDoc_STR("Roll back the current transaction.")}, - {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new function.")}, - {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new aggregate.")}, - {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets authorizer callback.")}, - #ifdef HAVE_LOAD_EXTENSION - {"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS, - PyDoc_STR("Enable dynamic loading of SQLite extension modules.")}, - {"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS, - PyDoc_STR("Load SQLite extension module.")}, - #endif - {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets progress handler callback.")}, - {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets a trace callback called for each SQL statement (passed as unicode).")}, - {"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS, - PyDoc_STR("Executes an SQL statement.")}, - {"executemany", (PyCFunction)pysqlite_connection_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes an SQL statement.")}, - {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once.")}, - {"create_collation", (PyCFunction)pysqlite_connection_create_collation, METH_VARARGS, - PyDoc_STR("Creates a collation function.")}, - {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, - PyDoc_STR("Abort any pending database operation.")}, - {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, - PyDoc_STR("Returns iterator to the dump of the database in an SQL text format.")}, - #ifdef HAVE_BACKUP_API - {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Makes a backup of the database.")}, - #endif - {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, - PyDoc_STR("For context manager.")}, - {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS, - PyDoc_STR("For context manager.")}, + PYSQLITE_CONNECTION_BACKUP_METHODDEF + PYSQLITE_CONNECTION_CLOSE_METHODDEF + PYSQLITE_CONNECTION_COMMIT_METHODDEF + PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF + PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF + PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF + PYSQLITE_CONNECTION_CURSOR_METHODDEF + PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF + PYSQLITE_CONNECTION_ENTER_METHODDEF + PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF + PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF + PYSQLITE_CONNECTION_EXECUTE_METHODDEF + PYSQLITE_CONNECTION_EXIT_METHODDEF + PYSQLITE_CONNECTION_INTERRUPT_METHODDEF + PYSQLITE_CONNECTION_ITERDUMP_METHODDEF + PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF + PYSQLITE_CONNECTION_ROLLBACK_METHODDEF + PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF + PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF + PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF {NULL, NULL} }; @@ -1892,50 +1960,35 @@ static struct PyMemberDef connection_members[] = {NULL} }; -PyTypeObject pysqlite_ConnectionType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Connection", /* tp_name */ - sizeof(pysqlite_Connection), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_connection_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 */ - (ternaryfunc)pysqlite_connection_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - connection_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - connection_methods, /* tp_methods */ - connection_members, /* tp_members */ - connection_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_connection_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot connection_slots[] = { + {Py_tp_dealloc, connection_dealloc}, + {Py_tp_doc, (void *)connection_doc}, + {Py_tp_methods, connection_methods}, + {Py_tp_members, connection_members}, + {Py_tp_getset, connection_getset}, + {Py_tp_init, pysqlite_connection_init}, + {Py_tp_call, pysqlite_connection_call}, + {Py_tp_traverse, connection_traverse}, + {Py_tp_clear, connection_clear}, + {0, NULL}, +}; + +static PyType_Spec connection_spec = { + .name = MODULE_NAME ".Connection", + .basicsize = sizeof(pysqlite_Connection), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = connection_slots, }; -extern int pysqlite_connection_setup_types(void) +PyTypeObject *pysqlite_ConnectionType = NULL; + +int +pysqlite_connection_setup_types(PyObject *module) { - pysqlite_ConnectionType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_ConnectionType); + pysqlite_ConnectionType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &connection_spec, NULL); + if (pysqlite_ConnectionType == NULL) { + return -1; + } + return 0; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/connection.h b/contrib/tools/python3/src/Modules/_sqlite/connection.h index 206085e00a0..8773c9eac08 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/connection.h +++ b/contrib/tools/python3/src/Modules/_sqlite/connection.h @@ -93,7 +93,7 @@ typedef struct /* a dictionary of registered collation name => collation callable mappings */ PyObject* collations; - /* Exception objects */ + /* Exception objects: borrowed refs. */ PyObject* Warning; PyObject* Error; PyObject* InterfaceError; @@ -106,22 +106,14 @@ typedef struct PyObject* NotSupportedError; } pysqlite_Connection; -extern PyTypeObject pysqlite_ConnectionType; +extern PyTypeObject *pysqlite_ConnectionType; -PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); -void pysqlite_connection_dealloc(pysqlite_Connection* self); -PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); -PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args); PyObject* _pysqlite_connection_begin(pysqlite_Connection* self); -PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw); -int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor); int pysqlite_check_thread(pysqlite_Connection* self); int pysqlite_check_connection(pysqlite_Connection* con); -int pysqlite_connection_setup_types(void); +int pysqlite_connection_setup_types(PyObject *module); #endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/cursor.c b/contrib/tools/python3/src/Modules/_sqlite/cursor.c index e2635e18c73..85267cc9e77 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cursor.c +++ b/contrib/tools/python3/src/Modules/_sqlite/cursor.c @@ -24,20 +24,29 @@ #include "cursor.h" #include "module.h" #include "util.h" +#include "clinic/cursor.c.h" -PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); +/*[clinic input] +module _sqlite3 +class _sqlite3.Cursor "pysqlite_Cursor *" "pysqlite_CursorType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b2072d8db95411d5]*/ static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; -static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) -{ - pysqlite_Connection* connection; +/*[clinic input] +_sqlite3.Cursor.__init__ as pysqlite_cursor_init - if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) - { - return -1; - } + connection: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType') + / + +[clinic start generated code]*/ +static int +pysqlite_cursor_init_impl(pysqlite_Cursor *self, + pysqlite_Connection *connection) +/*[clinic end generated code: output=ac59dce49a809ca8 input=a8a4f75ac90999b2]*/ +{ Py_INCREF(connection); Py_XSETREF(self->connection, connection); Py_CLEAR(self->statement); @@ -72,26 +81,49 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* return 0; } -static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) +static int +cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->connection); + Py_VISIT(self->description); + Py_VISIT(self->row_cast_map); + Py_VISIT(self->lastrowid); + Py_VISIT(self->row_factory); + Py_VISIT(self->statement); + Py_VISIT(self->next_row); + return 0; +} + +static int +cursor_clear(pysqlite_Cursor *self) { - /* Reset the statement if the user has not closed the cursor */ + Py_CLEAR(self->connection); + Py_CLEAR(self->description); + Py_CLEAR(self->row_cast_map); + Py_CLEAR(self->lastrowid); + Py_CLEAR(self->row_factory); if (self->statement) { + /* Reset the statement if the user has not closed the cursor */ pysqlite_statement_reset(self->statement); - Py_DECREF(self->statement); + Py_CLEAR(self->statement); } + Py_CLEAR(self->next_row); - Py_XDECREF(self->connection); - Py_XDECREF(self->row_cast_map); - Py_XDECREF(self->description); - Py_XDECREF(self->lastrowid); - Py_XDECREF(self->row_factory); - Py_XDECREF(self->next_row); + return 0; +} +static void +cursor_dealloc(pysqlite_Cursor *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); } - - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_clear((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } static PyObject * @@ -123,7 +155,6 @@ pysqlite_build_row_cast_map(pysqlite_Cursor* self) { int i; const char* pos; - const char* colname; const char* decltype; PyObject* converter; @@ -140,21 +171,24 @@ pysqlite_build_row_cast_map(pysqlite_Cursor* self) converter = NULL; if (self->connection->detect_types & PARSE_COLNAMES) { - colname = sqlite3_column_name(self->statement->st, i); - if (colname) { - const char *type_start = NULL; - for (pos = colname; *pos != 0; pos++) { - if (*pos == '[') { - type_start = pos + 1; - } - else if (*pos == ']' && type_start != NULL) { - converter = _pysqlite_get_converter(type_start, pos - type_start); - if (!converter && PyErr_Occurred()) { - Py_CLEAR(self->row_cast_map); - return -1; - } - break; + const char *colname = sqlite3_column_name(self->statement->st, i); + if (colname == NULL) { + PyErr_NoMemory(); + Py_CLEAR(self->row_cast_map); + return -1; + } + const char *type_start = NULL; + for (pos = colname; *pos != 0; pos++) { + if (*pos == '[') { + type_start = pos + 1; + } + else if (*pos == ']' && type_start != NULL) { + converter = _pysqlite_get_converter(type_start, pos - type_start); + if (!converter && PyErr_Occurred()) { + Py_CLEAR(self->row_cast_map); + return -1; } + break; } } } @@ -198,10 +232,6 @@ _pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname) const char* pos; Py_ssize_t len; - if (!colname) { - Py_RETURN_NONE; - } - if (self->connection->detect_types & PARSE_COLNAMES) { for (pos = colname; *pos; pos++) { if (*pos == '[') { @@ -230,12 +260,10 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) { int i, numcols; PyObject* row; - PyObject* item = NULL; int coltype; PyObject* converter; PyObject* converted; Py_ssize_t nbytes; - const char* val_str; char buf[200]; const char* colname; PyObject* error_msg; @@ -253,6 +281,7 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) if (!row) return NULL; + sqlite3 *db = self->connection->db; for (i = 0; i < numcols; i++) { if (self->connection->detect_types && self->row_cast_map != NULL @@ -264,16 +293,27 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) converter = Py_None; } + /* + * Note, sqlite3_column_bytes() must come after sqlite3_column_blob() + * or sqlite3_column_text(). + * + * See https://sqlite.org/c3ref/column_blob.html for details. + */ if (converter != Py_None) { - nbytes = sqlite3_column_bytes(self->statement->st, i); - val_str = (const char*)sqlite3_column_blob(self->statement->st, i); - if (!val_str) { - Py_INCREF(Py_None); - converted = Py_None; - } else { - item = PyBytes_FromStringAndSize(val_str, nbytes); - if (!item) + const void *blob = sqlite3_column_blob(self->statement->st, i); + if (blob == NULL) { + if (sqlite3_errcode(db) == SQLITE_NOMEM) { + PyErr_NoMemory(); + goto error; + } + converted = Py_NewRef(Py_None); + } + else { + nbytes = sqlite3_column_bytes(self->statement->st, i); + PyObject *item = PyBytes_FromStringAndSize(blob, nbytes); + if (item == NULL) { goto error; + } converted = PyObject_CallOneArg(converter, item); Py_DECREF(item); } @@ -282,25 +322,30 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) coltype = sqlite3_column_type(self->statement->st, i); Py_END_ALLOW_THREADS if (coltype == SQLITE_NULL) { - Py_INCREF(Py_None); - converted = Py_None; + converted = Py_NewRef(Py_None); } else if (coltype == SQLITE_INTEGER) { converted = PyLong_FromLongLong(sqlite3_column_int64(self->statement->st, i)); } else if (coltype == SQLITE_FLOAT) { converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i)); } else if (coltype == SQLITE_TEXT) { - val_str = (const char*)sqlite3_column_text(self->statement->st, i); + const char *text = (const char*)sqlite3_column_text(self->statement->st, i); + if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { + PyErr_NoMemory(); + goto error; + } + nbytes = sqlite3_column_bytes(self->statement->st, i); if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) { - converted = PyUnicode_FromStringAndSize(val_str, nbytes); + converted = PyUnicode_FromStringAndSize(text, nbytes); if (!converted && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { PyErr_Clear(); colname = sqlite3_column_name(self->statement->st, i); - if (!colname) { - colname = ""; + if (colname == NULL) { + PyErr_NoMemory(); + goto error; } PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'", - colname , val_str); + colname , text); error_msg = PyUnicode_Decode(buf, strlen(buf), "ascii", "replace"); if (!error_msg) { PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8"); @@ -310,24 +355,29 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) } } } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) { - converted = PyBytes_FromStringAndSize(val_str, nbytes); + converted = PyBytes_FromStringAndSize(text, nbytes); } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) { - converted = PyByteArray_FromStringAndSize(val_str, nbytes); + converted = PyByteArray_FromStringAndSize(text, nbytes); } else { - converted = PyObject_CallFunction(self->connection->text_factory, "y#", val_str, nbytes); + converted = PyObject_CallFunction(self->connection->text_factory, "y#", text, nbytes); } } else { /* coltype == SQLITE_BLOB */ + const void *blob = sqlite3_column_blob(self->statement->st, i); + if (blob == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { + PyErr_NoMemory(); + goto error; + } + nbytes = sqlite3_column_bytes(self->statement->st, i); - converted = PyBytes_FromStringAndSize( - sqlite3_column_blob(self->statement->st, i), nbytes); + converted = PyBytes_FromStringAndSize(blob, nbytes); } } if (!converted) { goto error; } - PyTuple_SetItem(row, i, converted); + PyTuple_SET_ITEM(row, i, converted); } if (PyErr_Occurred()) @@ -366,9 +416,8 @@ static int check_cursor(pysqlite_Cursor* cur) } static PyObject * -_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) +_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) { - PyObject* operation; PyObject* parameters_list = NULL; PyObject* parameters_iter = NULL; PyObject* parameters = NULL; @@ -377,9 +426,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) PyObject* func_args; PyObject* result; int numcols; - PyObject* descriptor; PyObject* column_name; - PyObject* second_argument = NULL; sqlite_int64 lastrowid; if (!check_cursor(self)) { @@ -392,15 +439,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) Py_CLEAR(self->next_row); if (multiple) { - /* executemany() */ - if (!PyArg_ParseTuple(args, "UO", &operation, &second_argument)) { - goto error; - } - if (PyIter_Check(second_argument)) { /* iterator */ - Py_INCREF(second_argument); - parameters_iter = second_argument; + parameters_iter = Py_NewRef(second_argument); } else { /* sequence */ parameters_iter = PyObject_GetIter(second_argument); @@ -409,11 +450,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) } } } else { - /* execute() */ - if (!PyArg_ParseTuple(args, "U|O", &operation, &second_argument)) { - goto error; - } - parameters_list = PyList_New(0); if (!parameters_list) { goto error; @@ -453,8 +489,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) if (!func_args) { goto error; } - Py_INCREF(operation); - if (PyTuple_SetItem(func_args, 0, operation) != 0) { + if (PyTuple_SetItem(func_args, 0, Py_NewRef(operation)) != 0) { goto error; } @@ -472,13 +507,8 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) if (self->statement->in_use) { Py_SETREF(self->statement, - PyObject_New(pysqlite_Statement, &pysqlite_StatementType)); - if (!self->statement) { - goto error; - } - rc = pysqlite_statement_create(self->statement, self->connection, operation); - if (rc != SQLITE_OK) { - Py_CLEAR(self->statement); + pysqlite_statement_create(self->connection, operation)); + if (self->statement == NULL) { goto error; } } @@ -541,24 +571,24 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) goto error; } for (i = 0; i < numcols; i++) { - descriptor = PyTuple_New(7); - if (!descriptor) { + const char *colname; + colname = sqlite3_column_name(self->statement->st, i); + if (colname == NULL) { + PyErr_NoMemory(); goto error; } - column_name = _pysqlite_build_column_name(self, - sqlite3_column_name(self->statement->st, i)); - if (!column_name) { - Py_DECREF(descriptor); + column_name = _pysqlite_build_column_name(self, colname); + if (column_name == NULL) { goto error; } - PyTuple_SetItem(descriptor, 0, column_name); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None); - PyTuple_SetItem(self->description, i, descriptor); + PyObject *descriptor = PyTuple_Pack(7, column_name, + Py_None, Py_None, Py_None, + Py_None, Py_None, Py_None); + Py_DECREF(column_name); + if (descriptor == NULL) { + goto error; + } + PyTuple_SET_ITEM(self->description, i, descriptor); } } @@ -609,34 +639,65 @@ error: self->rowcount = -1L; return NULL; } else { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef((PyObject *)self); } } -PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.execute as pysqlite_cursor_execute + + sql: unicode + parameters: object(c_default = 'NULL') = () + / + +Executes an SQL statement. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters) +/*[clinic end generated code: output=d81b4655c7c0bbad input=a8e0200a11627f94]*/ { - return _pysqlite_query_execute(self, 0, args); + return _pysqlite_query_execute(self, 0, sql, parameters); } -PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.executemany as pysqlite_cursor_executemany + + sql: unicode + seq_of_parameters: object + / + +Repeatedly executes an SQL statement. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *seq_of_parameters) +/*[clinic end generated code: output=2c65a3c4733fb5d8 input=0d0a52e5eb7ccd35]*/ { - return _pysqlite_query_execute(self, 1, args); + return _pysqlite_query_execute(self, 1, sql, seq_of_parameters); } +/*[clinic input] +_sqlite3.Cursor.executescript as pysqlite_cursor_executescript + + sql_script as script_obj: object + / + +Executes multiple SQL statements at once. +[clinic start generated code]*/ + static PyObject * -pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) +pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) +/*[clinic end generated code: output=115a8132b0f200fe input=75270e5bcdb4d6aa]*/ { - PyObject* script_obj; + _Py_IDENTIFIER(commit); const char* script_cstr; sqlite3_stmt* statement; int rc; PyObject* result; - if (!PyArg_ParseTuple(args, "O", &script_obj)) { - return NULL; - } - if (!check_cursor(self)) { return NULL; } @@ -654,7 +715,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) } /* commit first */ - result = pysqlite_connection_commit(self->connection, NULL); + result = _PyObject_CallMethodIdNoArgs((PyObject *)self->connection, &PyId_commit); if (!result) { goto error; } @@ -674,14 +735,13 @@ pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) } /* execute statement, and ignore results of SELECT statements */ - rc = SQLITE_ROW; - while (rc == SQLITE_ROW) { + do { rc = pysqlite_step(statement, self->connection); if (PyErr_Occurred()) { (void)sqlite3_finalize(statement); goto error; } - } + } while (rc == SQLITE_ROW); if (rc != SQLITE_DONE) { (void)sqlite3_finalize(statement); @@ -704,12 +764,12 @@ error: if (PyErr_Occurred()) { return NULL; } else { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef((PyObject *)self); } } -PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) +static PyObject * +pysqlite_cursor_iternext(pysqlite_Cursor *self) { PyObject* next_row_tuple; PyObject* next_row; @@ -773,7 +833,15 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) return next_row; } -PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.fetchone as pysqlite_cursor_fetchone + +Fetches one row from the resultset. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) +/*[clinic end generated code: output=4bd2eabf5baaddb0 input=e78294ec5980fdba]*/ { PyObject* row; @@ -785,19 +853,23 @@ PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) return row; } -PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) -{ - static char *kwlist[] = {"size", NULL}; +/*[clinic input] +_sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany + + size as maxrows: int(c_default='self->arraysize') = 1 + The default value is set by the Cursor.arraysize attribute. + +Fetches several rows from the resultset. +[clinic start generated code]*/ +static PyObject * +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) +/*[clinic end generated code: output=a8ef31fea64d0906 input=c26e6ca3f34debd0]*/ +{ PyObject* row; PyObject* list; - int maxrows = self->arraysize; int counter = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:fetchmany", kwlist, &maxrows)) { - return NULL; - } - list = PyList_New(0); if (!list) { return NULL; @@ -823,7 +895,15 @@ PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObj } } -PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.fetchall as pysqlite_cursor_fetchall + +Fetches all rows from the resultset. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_fetchall_impl(pysqlite_Cursor *self) +/*[clinic end generated code: output=d5da12aca2da4b27 input=f5d401086a8df25a]*/ { PyObject* row; PyObject* list; @@ -849,13 +929,49 @@ PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) } } -PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.setinputsizes as pysqlite_cursor_setinputsizes + + sizes: object + / + +Required by DB-API. Does nothing in sqlite3. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_setinputsizes(pysqlite_Cursor *self, PyObject *sizes) +/*[clinic end generated code: output=893c817afe9d08ad input=de7950a3aec79bdf]*/ +{ + Py_RETURN_NONE; +} + +/*[clinic input] +_sqlite3.Cursor.setoutputsize as pysqlite_cursor_setoutputsize + + size: object + column: object = None + / + +Required by DB-API. Does nothing in sqlite3. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, + PyObject *column) +/*[clinic end generated code: output=018d7e9129d45efe input=607a6bece8bbb273]*/ { - /* don't care, return None */ Py_RETURN_NONE; } -PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.close as pysqlite_cursor_close + +Closes the cursor. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_close_impl(pysqlite_Cursor *self) +/*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/ { if (!self->connection) { PyErr_SetString(pysqlite_ProgrammingError, @@ -877,24 +993,15 @@ PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) } static PyMethodDef cursor_methods[] = { - {"execute", (PyCFunction)pysqlite_cursor_execute, METH_VARARGS, - PyDoc_STR("Executes an SQL statement.")}, - {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes an SQL statement.")}, - {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, - PyDoc_STR("Executes multiple SQL statements at once.")}, - {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, - PyDoc_STR("Fetches one row from the resultset.")}, - {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Fetches several rows from the resultset.")}, - {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, - PyDoc_STR("Fetches all rows from the resultset.")}, - {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, - PyDoc_STR("Closes the cursor.")}, - {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in sqlite3.")}, - {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in sqlite3.")}, + PYSQLITE_CURSOR_CLOSE_METHODDEF + PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF + PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF + PYSQLITE_CURSOR_EXECUTE_METHODDEF + PYSQLITE_CURSOR_FETCHALL_METHODDEF + PYSQLITE_CURSOR_FETCHMANY_METHODDEF + PYSQLITE_CURSOR_FETCHONE_METHODDEF + PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF + PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF {NULL, NULL} }; @@ -906,56 +1013,42 @@ static struct PyMemberDef cursor_members[] = {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY}, {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY}, {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Cursor, in_weakreflist), READONLY}, {NULL} }; static const char cursor_doc[] = PyDoc_STR("SQLite database cursor class."); -PyTypeObject pysqlite_CursorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cursor", /* tp_name */ - sizeof(pysqlite_Cursor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cursor_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 */ - cursor_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */ - cursor_methods, /* tp_methods */ - cursor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_cursor_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot cursor_slots[] = { + {Py_tp_dealloc, cursor_dealloc}, + {Py_tp_doc, (void *)cursor_doc}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, pysqlite_cursor_iternext}, + {Py_tp_methods, cursor_methods}, + {Py_tp_members, cursor_members}, + {Py_tp_init, pysqlite_cursor_init}, + {Py_tp_traverse, cursor_traverse}, + {Py_tp_clear, cursor_clear}, + {0, NULL}, }; -extern int pysqlite_cursor_setup_types(void) +static PyType_Spec cursor_spec = { + .name = MODULE_NAME ".Cursor", + .basicsize = sizeof(pysqlite_Cursor), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = cursor_slots, +}; + +PyTypeObject *pysqlite_CursorType = NULL; + +int +pysqlite_cursor_setup_types(PyObject *module) { - pysqlite_CursorType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_CursorType); + pysqlite_CursorType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &cursor_spec, NULL); + if (pysqlite_CursorType == NULL) { + return -1; + } + return 0; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/cursor.h b/contrib/tools/python3/src/Modules/_sqlite/cursor.h index 4a20e756f78..b26b2886746 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cursor.h +++ b/contrib/tools/python3/src/Modules/_sqlite/cursor.h @@ -52,19 +52,9 @@ typedef struct PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Cursor; -extern PyTypeObject pysqlite_CursorType; +extern PyTypeObject *pysqlite_CursorType; -PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self); -PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self); -PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs); -PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args); - -int pysqlite_cursor_setup_types(void); +int pysqlite_cursor_setup_types(PyObject *module); #define UNKNOWN (-1) #endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c index 3b2d7f42b87..e219a7239f8 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c +++ b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c @@ -29,7 +29,6 @@ #include "microprotocols.h" #include "prepare_protocol.h" - /** the adapters registry **/ static PyObject *psyco_adapters = NULL; @@ -37,14 +36,17 @@ static PyObject *psyco_adapters = NULL; /* pysqlite_microprotocols_init - initialize the adapters dictionary */ int -pysqlite_microprotocols_init(PyObject *dict) +pysqlite_microprotocols_init(PyObject *module) { /* create adapters dictionary and put it in module namespace */ if ((psyco_adapters = PyDict_New()) == NULL) { return -1; } - return PyDict_SetItemString(dict, "adapters", psyco_adapters); + int res = PyModule_AddObjectRef(module, "adapters", psyco_adapters); + Py_DECREF(psyco_adapters); + + return res; } @@ -56,7 +58,7 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) PyObject* key; int rc; - if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType; + if (proto == NULL) proto = (PyObject*)pysqlite_PrepareProtocolType; key = Py_BuildValue("(OO)", (PyObject*)type, proto); if (!key) { @@ -138,22 +140,9 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) } if (alt) { - Py_INCREF(alt); - return alt; + return Py_NewRef(alt); } /* else set the right exception and return NULL */ PyErr_SetString(pysqlite_ProgrammingError, "can't adapt"); return NULL; } - -/** module-level functions **/ - -PyObject * -pysqlite_adapt(pysqlite_Cursor *self, PyObject *args) -{ - PyObject *obj, *alt = NULL; - PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; - - if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL; - return pysqlite_microprotocols_adapt(obj, proto, alt); -} diff --git a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h index 68c18d9355a..e9adef916e7 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h +++ b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h @@ -38,15 +38,10 @@ /** exported functions **/ /* used by module.c to init the microprotocols system */ -extern int pysqlite_microprotocols_init(PyObject *dict); +extern int pysqlite_microprotocols_init(PyObject *module); extern int pysqlite_microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); extern PyObject *pysqlite_microprotocols_adapt( PyObject *obj, PyObject *proto, PyObject *alt); -extern PyObject * - pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); -#define pysqlite_adapt_doc \ - "adapt(obj, protocol, alternate) -> adapt obj to given protocol." - #endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ diff --git a/contrib/tools/python3/src/Modules/_sqlite/module.c b/contrib/tools/python3/src/Modules/_sqlite/module.c index 98909369e75..8cff4e224d5 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/module.c +++ b/contrib/tools/python3/src/Modules/_sqlite/module.c @@ -29,10 +29,16 @@ #include "microprotocols.h" #include "row.h" -#if SQLITE_VERSION_NUMBER >= 3003003 -#define HAVE_SHARED_CACHE +#if SQLITE_VERSION_NUMBER < 3007015 +#error "SQLite 3.7.15 or higher required" #endif +#include "clinic/module.c.h" +/*[clinic input] +module _sqlite3 +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ + /* static objects at module-level */ PyObject *pysqlite_Error = NULL; @@ -80,7 +86,7 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* } if (factory == NULL) { - factory = (PyObject*)&pysqlite_ConnectionType; + factory = (PyObject*)pysqlite_ConnectionType; } return PyObject_Call(factory, args, kwargs); @@ -94,48 +100,44 @@ Opens a connection to the SQLite database file *database*. You can use\n\ \":memory:\" to open a database connection to a database that resides in\n\ RAM instead of on disk."); -static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* - kwargs) -{ - static char *kwlist[] = {"statement", NULL}; - char* statement; +/*[clinic input] +_sqlite3.complete_statement as pysqlite_complete_statement - PyObject* result; + statement: str - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement)) - { - return NULL; - } +Checks if a string contains a complete SQL statement. +[clinic start generated code]*/ +static PyObject * +pysqlite_complete_statement_impl(PyObject *module, const char *statement) +/*[clinic end generated code: output=e55f1ff1952df558 input=ac45d257375bb828]*/ +{ if (sqlite3_complete(statement)) { - result = Py_True; + return Py_NewRef(Py_True); } else { - result = Py_False; + return Py_NewRef(Py_False); } +} - Py_INCREF(result); +/*[clinic input] +_sqlite3.enable_shared_cache as pysqlite_enable_shared_cache - return result; -} + do_enable: int -PyDoc_STRVAR(module_complete_doc, -"complete_statement(sql)\n\ -\n\ -Checks if a string contains a complete SQL statement."); +Enable or disable shared cache mode for the calling thread. -#ifdef HAVE_SHARED_CACHE -static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject* - kwargs) +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]*/ { - static char *kwlist[] = {"do_enable", NULL}; - int do_enable; int rc; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable)) - { - return NULL; - } - rc = sqlite3_enable_shared_cache(do_enable); if (rc != SQLITE_OK) { @@ -146,22 +148,23 @@ static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyOb } } -PyDoc_STRVAR(module_enable_shared_cache_doc, -"enable_shared_cache(do_enable)\n\ -\n\ -Enable or disable shared cache mode for the calling thread."); -#endif /* HAVE_SHARED_CACHE */ +/*[clinic input] +_sqlite3.register_adapter as pysqlite_register_adapter + + type: object(type='PyTypeObject *') + caster: object + / + +Registers an adapter with sqlite3's adapter registry. +[clinic start generated code]*/ -static PyObject* module_register_adapter(PyObject* self, PyObject* args) +static PyObject * +pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, + PyObject *caster) +/*[clinic end generated code: output=a287e8db18e8af23 input=b4bd87afcadc535d]*/ { - PyTypeObject* type; - PyObject* caster; int rc; - if (!PyArg_ParseTuple(args, "OO", &type, &caster)) { - return NULL; - } - /* a basic type is adapted; there's a performance optimization if that's not the case * (99 % of all usages) */ if (type == &PyLong_Type || type == &PyFloat_Type @@ -169,30 +172,32 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args) pysqlite_BaseTypeAdapted = 1; } - rc = pysqlite_microprotocols_add(type, (PyObject*)&pysqlite_PrepareProtocolType, caster); + rc = pysqlite_microprotocols_add(type, (PyObject*)pysqlite_PrepareProtocolType, caster); if (rc == -1) return NULL; Py_RETURN_NONE; } -PyDoc_STRVAR(module_register_adapter_doc, -"register_adapter(type, callable)\n\ -\n\ -Registers an adapter with sqlite3's adapter registry."); +/*[clinic input] +_sqlite3.register_converter as pysqlite_register_converter + + name as orig_name: unicode + converter as callable: object + / + +Registers a converter with sqlite3. +[clinic start generated code]*/ -static PyObject* module_register_converter(PyObject* self, PyObject* args) +static PyObject * +pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, + PyObject *callable) +/*[clinic end generated code: output=a2f2bfeed7230062 input=90f645419425d6c4]*/ { - PyObject* orig_name; PyObject* name = NULL; - PyObject* callable; PyObject* retval = NULL; _Py_IDENTIFIER(upper); - if (!PyArg_ParseTuple(args, "UO", &orig_name, &callable)) { - return NULL; - } - /* convert the name to upper case */ name = _PyObject_CallMethodIdNoArgs(orig_name, &PyId_upper); if (!name) { @@ -203,127 +208,127 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args) goto error; } - Py_INCREF(Py_None); - retval = Py_None; + retval = Py_NewRef(Py_None); error: Py_XDECREF(name); return retval; } -PyDoc_STRVAR(module_register_converter_doc, -"register_converter(typename, callable)\n\ -\n\ -Registers a converter with sqlite3."); +/*[clinic input] +_sqlite3.enable_callback_tracebacks as pysqlite_enable_callback_trace -static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args) + enable: int + / + +Enable or disable callback functions throwing errors to stderr. +[clinic start generated code]*/ + +static PyObject * +pysqlite_enable_callback_trace_impl(PyObject *module, int enable) +/*[clinic end generated code: output=4ff1d051c698f194 input=cb79d3581eb77c40]*/ { - if (!PyArg_ParseTuple(args, "i", &_pysqlite_enable_callback_tracebacks)) { - return NULL; - } + _pysqlite_enable_callback_tracebacks = enable; Py_RETURN_NONE; } -PyDoc_STRVAR(enable_callback_tracebacks_doc, -"enable_callback_tracebacks(flag)\n\ -\n\ -Enable or disable callback functions throwing errors to stderr."); +/*[clinic input] +_sqlite3.adapt as pysqlite_adapt + + obj: object + proto: object(c_default='(PyObject*)pysqlite_PrepareProtocolType') = PrepareProtocolType + alt: object = NULL + / -static void converters_init(PyObject* dict) +Adapt given object to given protocol. +[clinic start generated code]*/ + +static PyObject * +pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, + PyObject *alt) +/*[clinic end generated code: output=0c3927c5fcd23dd9 input=46ca9564710ba48a]*/ +{ + return pysqlite_microprotocols_adapt(obj, proto, alt); +} + +static int converters_init(PyObject* module) { _pysqlite_converters = PyDict_New(); if (!_pysqlite_converters) { - return; + return -1; } - PyDict_SetItemString(dict, "converters", _pysqlite_converters); + int res = PyModule_AddObjectRef(module, "converters", _pysqlite_converters); + Py_DECREF(_pysqlite_converters); + + return res; } static PyMethodDef module_methods[] = { {"connect", (PyCFunction)(void(*)(void))module_connect, METH_VARARGS | METH_KEYWORDS, module_connect_doc}, - {"complete_statement", (PyCFunction)(void(*)(void))module_complete, - METH_VARARGS | METH_KEYWORDS, module_complete_doc}, -#ifdef HAVE_SHARED_CACHE - {"enable_shared_cache", (PyCFunction)(void(*)(void))module_enable_shared_cache, - METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc}, -#endif - {"register_adapter", (PyCFunction)module_register_adapter, - METH_VARARGS, module_register_adapter_doc}, - {"register_converter", (PyCFunction)module_register_converter, - METH_VARARGS, module_register_converter_doc}, - {"adapt", (PyCFunction)pysqlite_adapt, METH_VARARGS, - pysqlite_adapt_doc}, - {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, - METH_VARARGS, enable_callback_tracebacks_doc}, + PYSQLITE_ADAPT_METHODDEF + PYSQLITE_COMPLETE_STATEMENT_METHODDEF + PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF + PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF + PYSQLITE_REGISTER_ADAPTER_METHODDEF + PYSQLITE_REGISTER_CONVERTER_METHODDEF {NULL, NULL} }; -struct _IntConstantPair { - const char *constant_name; - int constant_value; -}; - -typedef struct _IntConstantPair IntConstantPair; - -static const IntConstantPair _int_constants[] = { - {"PARSE_DECLTYPES", PARSE_DECLTYPES}, - {"PARSE_COLNAMES", PARSE_COLNAMES}, - - {"SQLITE_OK", SQLITE_OK}, - {"SQLITE_DENY", SQLITE_DENY}, - {"SQLITE_IGNORE", SQLITE_IGNORE}, - {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX}, - {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE}, - {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX}, - {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE}, - {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER}, - {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW}, - {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER}, - {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW}, - {"SQLITE_DELETE", SQLITE_DELETE}, - {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX}, - {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE}, - {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX}, - {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE}, - {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER}, - {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW}, - {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER}, - {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW}, - {"SQLITE_INSERT", SQLITE_INSERT}, - {"SQLITE_PRAGMA", SQLITE_PRAGMA}, - {"SQLITE_READ", SQLITE_READ}, - {"SQLITE_SELECT", SQLITE_SELECT}, - {"SQLITE_TRANSACTION", SQLITE_TRANSACTION}, - {"SQLITE_UPDATE", SQLITE_UPDATE}, - {"SQLITE_ATTACH", SQLITE_ATTACH}, - {"SQLITE_DETACH", SQLITE_DETACH}, -#if SQLITE_VERSION_NUMBER >= 3002001 - {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE}, - {"SQLITE_REINDEX", SQLITE_REINDEX}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003000 - {"SQLITE_ANALYZE", SQLITE_ANALYZE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003007 - {"SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE}, - {"SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003008 - {"SQLITE_FUNCTION", SQLITE_FUNCTION}, -#endif -#if SQLITE_VERSION_NUMBER >= 3006008 - {"SQLITE_SAVEPOINT", SQLITE_SAVEPOINT}, -#endif +static int +add_integer_constants(PyObject *module) { +#define ADD_INT(ival) \ + do { \ + if (PyModule_AddIntConstant(module, #ival, ival) < 0) { \ + return -1; \ + } \ + } while (0); \ + + ADD_INT(PARSE_DECLTYPES); + ADD_INT(PARSE_COLNAMES); + ADD_INT(SQLITE_OK); + ADD_INT(SQLITE_DENY); + ADD_INT(SQLITE_IGNORE); + ADD_INT(SQLITE_CREATE_INDEX); + ADD_INT(SQLITE_CREATE_TABLE); + ADD_INT(SQLITE_CREATE_TEMP_INDEX); + ADD_INT(SQLITE_CREATE_TEMP_TABLE); + ADD_INT(SQLITE_CREATE_TEMP_TRIGGER); + ADD_INT(SQLITE_CREATE_TEMP_VIEW); + ADD_INT(SQLITE_CREATE_TRIGGER); + ADD_INT(SQLITE_CREATE_VIEW); + ADD_INT(SQLITE_DELETE); + ADD_INT(SQLITE_DROP_INDEX); + ADD_INT(SQLITE_DROP_TABLE); + ADD_INT(SQLITE_DROP_TEMP_INDEX); + ADD_INT(SQLITE_DROP_TEMP_TABLE); + ADD_INT(SQLITE_DROP_TEMP_TRIGGER); + ADD_INT(SQLITE_DROP_TEMP_VIEW); + ADD_INT(SQLITE_DROP_TRIGGER); + ADD_INT(SQLITE_DROP_VIEW); + ADD_INT(SQLITE_INSERT); + ADD_INT(SQLITE_PRAGMA); + ADD_INT(SQLITE_READ); + ADD_INT(SQLITE_SELECT); + ADD_INT(SQLITE_TRANSACTION); + ADD_INT(SQLITE_UPDATE); + ADD_INT(SQLITE_ATTACH); + ADD_INT(SQLITE_DETACH); + ADD_INT(SQLITE_ALTER_TABLE); + ADD_INT(SQLITE_REINDEX); + ADD_INT(SQLITE_ANALYZE); + ADD_INT(SQLITE_CREATE_VTABLE); + ADD_INT(SQLITE_DROP_VTABLE); + ADD_INT(SQLITE_FUNCTION); + ADD_INT(SQLITE_SAVEPOINT); #if SQLITE_VERSION_NUMBER >= 3008003 - {"SQLITE_RECURSIVE", SQLITE_RECURSIVE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3006011 - {"SQLITE_DONE", SQLITE_DONE}, + ADD_INT(SQLITE_RECURSIVE); #endif - {(char*)NULL, 0} -}; - + ADD_INT(SQLITE_DONE); +#undef ADD_INT + return 0; +} static struct PyModuleDef _sqlite3module = { PyModuleDef_HEAD_INIT, @@ -340,138 +345,100 @@ static struct PyModuleDef _sqlite3module = { #define ADD_TYPE(module, type) \ do { \ if (PyModule_AddType(module, &type) < 0) { \ - Py_DECREF(module); \ - return NULL; \ + goto error; \ } \ } while (0) +#define ADD_EXCEPTION(module, name, exc, base) \ +do { \ + exc = PyErr_NewException(MODULE_NAME "." name, base, NULL); \ + if (!exc) { \ + goto error; \ + } \ + int res = PyModule_AddObjectRef(module, name, exc); \ + Py_DECREF(exc); \ + if (res < 0) { \ + goto error; \ + } \ +} while (0) + PyMODINIT_FUNC PyInit__sqlite3(void) { - PyObject *module, *dict; - PyObject *tmp_obj; - int i; + PyObject *module; - module = PyModule_Create(&_sqlite3module); - - if (!module || - (pysqlite_row_setup_types() < 0) || - (pysqlite_cursor_setup_types() < 0) || - (pysqlite_connection_setup_types() < 0) || - (pysqlite_cache_setup_types() < 0) || - (pysqlite_statement_setup_types() < 0) || - (pysqlite_prepare_protocol_setup_types() < 0) - ) { - Py_XDECREF(module); + if (sqlite3_libversion_number() < 3007015) { + PyErr_SetString(PyExc_ImportError, MODULE_NAME ": SQLite 3.7.15 or higher required"); return NULL; } - ADD_TYPE(module, pysqlite_ConnectionType); - ADD_TYPE(module, pysqlite_CursorType); - ADD_TYPE(module, pysqlite_PrepareProtocolType); - ADD_TYPE(module, pysqlite_RowType); - - if (!(dict = PyModule_GetDict(module))) { - goto error; + int rc = sqlite3_initialize(); + if (rc != SQLITE_OK) { + PyErr_SetString(PyExc_ImportError, sqlite3_errstr(rc)); + return NULL; } - /*** Create DB-API Exception hierarchy */ - - if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_Exception, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "Error", pysqlite_Error); + module = PyModule_Create(&_sqlite3module); - if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_Exception, NULL))) { + if (!module || + (pysqlite_row_setup_types(module) < 0) || + (pysqlite_cursor_setup_types(module) < 0) || + (pysqlite_connection_setup_types(module) < 0) || + (pysqlite_cache_setup_types(module) < 0) || + (pysqlite_statement_setup_types(module) < 0) || + (pysqlite_prepare_protocol_setup_types(module) < 0) + ) { goto error; } - PyDict_SetItemString(dict, "Warning", pysqlite_Warning); - /* Error subclasses */ + ADD_TYPE(module, *pysqlite_ConnectionType); + ADD_TYPE(module, *pysqlite_CursorType); + ADD_TYPE(module, *pysqlite_PrepareProtocolType); + ADD_TYPE(module, *pysqlite_RowType); - if (!(pysqlite_InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", pysqlite_Error, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "InterfaceError", pysqlite_InterfaceError); + /*** Create DB-API Exception hierarchy */ + ADD_EXCEPTION(module, "Error", pysqlite_Error, PyExc_Exception); + ADD_EXCEPTION(module, "Warning", pysqlite_Warning, PyExc_Exception); - if (!(pysqlite_DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", pysqlite_Error, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "DatabaseError", pysqlite_DatabaseError); + /* Error subclasses */ + ADD_EXCEPTION(module, "InterfaceError", pysqlite_InterfaceError, pysqlite_Error); + ADD_EXCEPTION(module, "DatabaseError", pysqlite_DatabaseError, pysqlite_Error); /* pysqlite_DatabaseError subclasses */ + ADD_EXCEPTION(module, "InternalError", pysqlite_InternalError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "OperationalError", pysqlite_OperationalError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "ProgrammingError", pysqlite_ProgrammingError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "IntegrityError", pysqlite_IntegrityError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "DataError", pysqlite_DataError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "NotSupportedError", pysqlite_NotSupportedError, pysqlite_DatabaseError); - if (!(pysqlite_InternalError = PyErr_NewException(MODULE_NAME ".InternalError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "InternalError", pysqlite_InternalError); - - if (!(pysqlite_OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "OperationalError", pysqlite_OperationalError); - - if (!(pysqlite_ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "ProgrammingError", pysqlite_ProgrammingError); - - if (!(pysqlite_IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", pysqlite_DatabaseError,NULL))) { + /* Set integer constants */ + if (add_integer_constants(module) < 0) { goto error; } - PyDict_SetItemString(dict, "IntegrityError", pysqlite_IntegrityError); - if (!(pysqlite_DataError = PyErr_NewException(MODULE_NAME ".DataError", pysqlite_DatabaseError, NULL))) { + if (PyModule_AddStringConstant(module, "version", PYSQLITE_VERSION) < 0) { goto error; } - PyDict_SetItemString(dict, "DataError", pysqlite_DataError); - if (!(pysqlite_NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", pysqlite_DatabaseError, NULL))) { + if (PyModule_AddStringConstant(module, "sqlite_version", sqlite3_libversion())) { goto error; } - PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError); - - /* In Python 2.x, setting Connection.text_factory to - OptimizedUnicode caused Unicode objects to be returned for - non-ASCII data and bytestrings to be returned for ASCII data. - Now OptimizedUnicode is an alias for str, so it has no - effect. */ - Py_INCREF((PyObject*)&PyUnicode_Type); - PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type); - - /* Set integer constants */ - for (i = 0; _int_constants[i].constant_name != NULL; i++) { - tmp_obj = PyLong_FromLong(_int_constants[i].constant_value); - if (!tmp_obj) { - goto error; - } - PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj); - Py_DECREF(tmp_obj); - } - if (!(tmp_obj = PyUnicode_FromString(PYSQLITE_VERSION))) { + /* initialize microprotocols layer */ + if (pysqlite_microprotocols_init(module) < 0) { goto error; } - PyDict_SetItemString(dict, "version", tmp_obj); - Py_DECREF(tmp_obj); - if (!(tmp_obj = PyUnicode_FromString(sqlite3_libversion()))) { + /* initialize the default converters */ + if (converters_init(module) < 0) { goto error; } - PyDict_SetItemString(dict, "sqlite_version", tmp_obj); - Py_DECREF(tmp_obj); - - /* initialize microprotocols layer */ - pysqlite_microprotocols_init(dict); - /* initialize the default converters */ - converters_init(dict); + return module; error: - if (PyErr_Occurred()) - { - PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed"); - Py_DECREF(module); - module = NULL; - } - return module; + sqlite3_shutdown(); + PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed"); + Py_XDECREF(module); + return NULL; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/module.h b/contrib/tools/python3/src/Modules/_sqlite/module.h index 3185ec97888..9aede92ea33 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/module.h +++ b/contrib/tools/python3/src/Modules/_sqlite/module.h @@ -27,6 +27,7 @@ #include "Python.h" #define PYSQLITE_VERSION "2.6.0" +#define MODULE_NAME "sqlite3" extern PyObject* pysqlite_Error; extern PyObject* pysqlite_Warning; diff --git a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c index 05a2ca5a652..800eef8794b 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c +++ b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c @@ -23,61 +23,52 @@ #include "prepare_protocol.h" -int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs) +static int +pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol *self, PyObject *args, + PyObject *kwargs) { return 0; } -void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) +static int +pysqlite_prepare_protocol_traverse(PyObject *self, visitproc visit, void *arg) { - Py_TYPE(self)->tp_free((PyObject*)self); + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static void +pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_free(self); + Py_DECREF(tp); } -PyTypeObject pysqlite_PrepareProtocolType= { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".PrepareProtocol", /* tp_name */ - sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_prepare_protocol_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, /* 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, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_prepare_protocol_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot type_slots[] = { + {Py_tp_dealloc, pysqlite_prepare_protocol_dealloc}, + {Py_tp_init, pysqlite_prepare_protocol_init}, + {Py_tp_traverse, pysqlite_prepare_protocol_traverse}, + {0, NULL}, }; -extern int pysqlite_prepare_protocol_setup_types(void) +static PyType_Spec type_spec = { + .name = MODULE_NAME ".PrepareProtocol", + .basicsize = sizeof(pysqlite_PrepareProtocol), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = type_slots, +}; + +PyTypeObject *pysqlite_PrepareProtocolType = NULL; + +int +pysqlite_prepare_protocol_setup_types(PyObject *module) { - pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; - Py_SET_TYPE(&pysqlite_PrepareProtocolType, &PyType_Type); - return PyType_Ready(&pysqlite_PrepareProtocolType); + pysqlite_PrepareProtocolType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &type_spec, NULL); + if (pysqlite_PrepareProtocolType == NULL) { + return -1; + } + return 0; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h index 3998a55e51c..593961331c9 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h +++ b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h @@ -23,20 +23,16 @@ #ifndef PYSQLITE_PREPARE_PROTOCOL_H #define PYSQLITE_PREPARE_PROTOCOL_H -#define PY_SSIZE_T_CLEAN -#include "Python.h" +#include "module.h" typedef struct { PyObject_HEAD } pysqlite_PrepareProtocol; -extern PyTypeObject pysqlite_PrepareProtocolType; +extern PyTypeObject *pysqlite_PrepareProtocolType; -int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs); -void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self); - -int pysqlite_prepare_protocol_setup_types(void); +int pysqlite_prepare_protocol_setup_types(PyObject *module); #define UNKNOWN (-1) #endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/row.c b/contrib/tools/python3/src/Modules/_sqlite/row.c index 4b47108278a..643194df040 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/row.c +++ b/contrib/tools/python3/src/Modules/_sqlite/row.c @@ -23,57 +23,74 @@ #include "row.h" #include "cursor.h" +#include "clinic/row.c.h" -void pysqlite_row_dealloc(pysqlite_Row* self) +/*[clinic input] +module _sqlite3 +class _sqlite3.Row "pysqlite_Row *" "pysqlite_RowType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=384227da65f250fd]*/ + +static int +row_clear(pysqlite_Row *self) { - Py_XDECREF(self->data); - Py_XDECREF(self->description); + Py_CLEAR(self->data); + Py_CLEAR(self->description); + return 0; +} - Py_TYPE(self)->tp_free((PyObject*)self); +static int +row_traverse(pysqlite_Row *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->data); + Py_VISIT(self->description); + return 0; } -static PyObject * -pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +static void +pysqlite_row_dealloc(PyObject *self) { - pysqlite_Row *self; - PyObject* data; - pysqlite_Cursor* cursor; + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear(self); + tp->tp_free(self); + Py_DECREF(tp); +} - assert(type != NULL && type->tp_alloc != NULL); +/*[clinic input] +@classmethod +_sqlite3.Row.__new__ as pysqlite_row_new - if (!_PyArg_NoKeywords("Row", kwargs)) - return NULL; - if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) - return NULL; + cursor: object(type='pysqlite_Cursor *', subclass_of='pysqlite_CursorType') + data: object(subclass_of='&PyTuple_Type') + / - if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) { - PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); - return NULL; - } +[clinic start generated code]*/ - if (!PyTuple_Check(data)) { - PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); - return NULL; - } +static PyObject * +pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, + PyObject *data) +/*[clinic end generated code: output=10d58b09a819a4c1 input=f6cd7e6e0935828d]*/ +{ + pysqlite_Row *self; + + assert(type != NULL && type->tp_alloc != NULL); self = (pysqlite_Row *) type->tp_alloc(type, 0); if (self == NULL) return NULL; - Py_INCREF(data); - self->data = data; - - Py_INCREF(cursor->description); - self->description = cursor->description; + self->data = Py_NewRef(data); + self->description = Py_NewRef(cursor->description); return (PyObject *) self; } PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx) { - PyObject* item = PyTuple_GetItem(self->data, idx); - Py_XINCREF(item); - return item; + PyObject *item = PyTuple_GetItem(self->data, idx); + return Py_XNewRef(item); } static int @@ -104,11 +121,11 @@ equal_ignore_case(PyObject *left, PyObject *right) return 1; } -PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) +static PyObject * +pysqlite_row_subscript(pysqlite_Row *self, PyObject *idx) { Py_ssize_t _idx; Py_ssize_t nitems, i; - PyObject* item; if (PyLong_Check(idx)) { _idx = PyNumber_AsSsize_t(idx, PyExc_IndexError); @@ -116,9 +133,9 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) return NULL; if (_idx < 0) _idx += PyTuple_GET_SIZE(self->data); - item = PyTuple_GetItem(self->data, _idx); - Py_XINCREF(item); - return item; + + PyObject *item = PyTuple_GetItem(self->data, _idx); + return Py_XNewRef(item); } else if (PyUnicode_Check(idx)) { nitems = PyTuple_Size(self->description); @@ -132,9 +149,8 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) } if (eq) { /* found item */ - item = PyTuple_GetItem(self->data, i); - Py_INCREF(item); - return item; + PyObject *item = PyTuple_GetItem(self->data, i); + return Py_XNewRef(item); } } @@ -156,7 +172,15 @@ pysqlite_row_length(pysqlite_Row* self) return PyTuple_GET_SIZE(self->data); } -PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject *Py_UNUSED(ignored)) +/*[clinic input] +_sqlite3.Row.keys as pysqlite_row_keys + +Returns the keys of the row. +[clinic start generated code]*/ + +static PyObject * +pysqlite_row_keys_impl(pysqlite_Row *self) +/*[clinic end generated code: output=efe3dfb3af6edc07 input=7549a122827c5563]*/ { PyObject* list; Py_ssize_t nitems, i; @@ -192,7 +216,7 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, if (opid != Py_EQ && opid != Py_NE) Py_RETURN_NOTIMPLEMENTED; - if (PyObject_TypeCheck(_other, &pysqlite_RowType)) { + if (PyObject_TypeCheck(_other, pysqlite_RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ); if (eq < 0) { @@ -206,73 +230,43 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, Py_RETURN_NOTIMPLEMENTED; } -PyMappingMethods pysqlite_row_as_mapping = { - /* mp_length */ (lenfunc)pysqlite_row_length, - /* mp_subscript */ (binaryfunc)pysqlite_row_subscript, - /* mp_ass_subscript */ (objobjargproc)0, +static PyMethodDef row_methods[] = { + PYSQLITE_ROW_KEYS_METHODDEF + {NULL, NULL} }; -static PySequenceMethods pysqlite_row_as_sequence = { - /* sq_length */ (lenfunc)pysqlite_row_length, - /* sq_concat */ 0, - /* sq_repeat */ 0, - /* sq_item */ (ssizeargfunc)pysqlite_row_item, +static PyType_Slot row_slots[] = { + {Py_tp_dealloc, pysqlite_row_dealloc}, + {Py_tp_hash, pysqlite_row_hash}, + {Py_tp_methods, row_methods}, + {Py_tp_richcompare, pysqlite_row_richcompare}, + {Py_tp_iter, pysqlite_iter}, + {Py_mp_length, pysqlite_row_length}, + {Py_mp_subscript, pysqlite_row_subscript}, + {Py_sq_length, pysqlite_row_length}, + {Py_sq_item, pysqlite_row_item}, + {Py_tp_new, pysqlite_row_new}, + {Py_tp_traverse, row_traverse}, + {Py_tp_clear, row_clear}, + {0, NULL}, }; - -static PyMethodDef pysqlite_row_methods[] = { - {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, - PyDoc_STR("Returns the keys of the row.")}, - {NULL, NULL} +static PyType_Spec row_spec = { + .name = MODULE_NAME ".Row", + .basicsize = sizeof(pysqlite_Row), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = row_slots, }; +PyTypeObject *pysqlite_RowType = NULL; -PyTypeObject pysqlite_RowType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Row", /* tp_name */ - sizeof(pysqlite_Row), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_row_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 */ - (hashfunc)pysqlite_row_hash, /* 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 */ - (traverseproc)0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - (getiterfunc)pysqlite_iter, /* tp_iter */ - 0, /* tp_iternext */ - pysqlite_row_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 */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -extern int pysqlite_row_setup_types(void) +int +pysqlite_row_setup_types(PyObject *module) { - pysqlite_RowType.tp_new = pysqlite_row_new; - pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; - pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence; - return PyType_Ready(&pysqlite_RowType); + pysqlite_RowType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &row_spec, NULL); + if (pysqlite_RowType == NULL) { + return -1; + } + return 0; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/row.h b/contrib/tools/python3/src/Modules/_sqlite/row.h index 4ad506f8dd9..2dac41e89e1 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/row.h +++ b/contrib/tools/python3/src/Modules/_sqlite/row.h @@ -33,8 +33,8 @@ typedef struct _Row PyObject* description; } pysqlite_Row; -extern PyTypeObject pysqlite_RowType; +extern PyTypeObject *pysqlite_RowType; -int pysqlite_row_setup_types(void); +int pysqlite_row_setup_types(PyObject *module); #endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/statement.c b/contrib/tools/python3/src/Modules/_sqlite/statement.c index 0272ce11207..3bc86420aa0 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/statement.c +++ b/contrib/tools/python3/src/Modules/_sqlite/statement.c @@ -48,7 +48,8 @@ typedef enum { TYPE_UNKNOWN } parameter_type; -int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql) +pysqlite_Statement * +pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) { const char* tail; int rc; @@ -56,28 +57,36 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con Py_ssize_t sql_cstr_len; const char* p; - self->st = NULL; - self->in_use = 0; - assert(PyUnicode_Check(sql)); sql_cstr = PyUnicode_AsUTF8AndSize(sql, &sql_cstr_len); if (sql_cstr == NULL) { - rc = PYSQLITE_SQL_WRONG_TYPE; - return rc; + PyErr_Format(pysqlite_Warning, + "SQL is of wrong type ('%s'). Must be string.", + Py_TYPE(sql)->tp_name); + return NULL; } if (strlen(sql_cstr) != (size_t)sql_cstr_len) { - PyErr_SetString(PyExc_ValueError, "the query contains a null character"); - return PYSQLITE_SQL_WRONG_TYPE; + PyErr_SetString(PyExc_ValueError, + "the query contains a null character"); + return NULL; + } + + pysqlite_Statement *self = PyObject_GC_New(pysqlite_Statement, + pysqlite_StatementType); + if (self == NULL) { + return NULL; } + self->db = connection->db; + self->st = NULL; + self->sql = Py_NewRef(sql); + self->in_use = 0; + self->is_dml = 0; self->in_weakreflist = NULL; - Py_INCREF(sql); - self->sql = sql; /* Determine if the statement is a DML statement. SELECT is the only exception. See #9924. */ - self->is_dml = 0; for (p = sql_cstr; *p != 0; p++) { switch (*p) { case ' ': @@ -95,22 +104,33 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con } Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(connection->db, + rc = sqlite3_prepare_v2(self->db, sql_cstr, -1, &self->st, &tail); Py_END_ALLOW_THREADS - self->db = connection->db; + PyObject_GC_Track(self); + + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + goto error; + } if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) { (void)sqlite3_finalize(self->st); self->st = NULL; - rc = PYSQLITE_TOO_MUCH_SQL; + PyErr_SetString(pysqlite_Warning, + "You can only execute one statement at a time."); + goto error; } - return rc; + return self; + +error: + Py_DECREF(self); + return NULL; } int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) @@ -247,11 +267,11 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para } for (i = 0; i < num_params; i++) { if (PyTuple_CheckExact(parameters)) { - current_param = PyTuple_GET_ITEM(parameters, i); - Py_INCREF(current_param); + PyObject *item = PyTuple_GET_ITEM(parameters, i); + current_param = Py_NewRef(item); } else if (PyList_CheckExact(parameters)) { - current_param = PyList_GetItem(parameters, i); - Py_XINCREF(current_param); + PyObject *item = PyList_GetItem(parameters, i); + current_param = Py_XNewRef(item); } else { current_param = PySequence_GetItem(parameters, i); } @@ -262,7 +282,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; @@ -297,15 +317,15 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para return; } if (PyDict_CheckExact(parameters)) { - current_param = PyDict_GetItemWithError(parameters, binding_name_obj); - Py_XINCREF(current_param); + PyObject *item = PyDict_GetItemWithError(parameters, binding_name_obj); + current_param = Py_XNewRef(item); } else { current_param = PyObject_GetItem(parameters, binding_name_obj); } Py_DECREF(binding_name_obj); if (!current_param) { if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) { - PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i); + PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding parameter :%s.", binding_name); } return; } @@ -313,7 +333,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; @@ -376,23 +396,38 @@ void pysqlite_statement_mark_dirty(pysqlite_Statement* self) self->in_use = 1; } -void pysqlite_statement_dealloc(pysqlite_Statement* self) +static void +stmt_dealloc(pysqlite_Statement *self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + if (self->in_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } if (self->st) { Py_BEGIN_ALLOW_THREADS sqlite3_finalize(self->st); Py_END_ALLOW_THREADS + self->st = 0; } + tp->tp_clear((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); +} - self->st = NULL; - - Py_XDECREF(self->sql); - - if (self->in_weakreflist != NULL) { - PyObject_ClearWeakRefs((PyObject*)self); - } +static int +stmt_clear(pysqlite_Statement *self) +{ + Py_CLEAR(self->sql); + return 0; +} - Py_TYPE(self)->tp_free((PyObject*)self); +static int +stmt_traverse(pysqlite_Statement *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->sql); + return 0; } /* @@ -465,50 +500,33 @@ static int pysqlite_check_remaining_sql(const char* tail) return 0; } -PyTypeObject pysqlite_StatementType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Statement", /* tp_name */ - sizeof(pysqlite_Statement), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_statement_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, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Statement, in_weakreflist), /* 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)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyMemberDef stmt_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Statement, in_weakreflist), READONLY}, + {NULL}, +}; +static PyType_Slot stmt_slots[] = { + {Py_tp_members, stmt_members}, + {Py_tp_dealloc, stmt_dealloc}, + {Py_tp_traverse, stmt_traverse}, + {Py_tp_clear, stmt_clear}, + {0, NULL}, +}; + +static PyType_Spec stmt_spec = { + .name = MODULE_NAME ".Statement", + .basicsize = sizeof(pysqlite_Statement), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = stmt_slots, }; +PyTypeObject *pysqlite_StatementType = NULL; -extern int pysqlite_statement_setup_types(void) +int +pysqlite_statement_setup_types(PyObject *module) { - pysqlite_StatementType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_StatementType); + pysqlite_StatementType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &stmt_spec, NULL); + if (pysqlite_StatementType == NULL) { + return -1; + } + return 0; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/statement.h b/contrib/tools/python3/src/Modules/_sqlite/statement.h index 5002f02dc5b..e8c86a0ec96 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/statement.h +++ b/contrib/tools/python3/src/Modules/_sqlite/statement.h @@ -29,9 +29,6 @@ #include "connection.h" #include "sqlite3.h" -#define PYSQLITE_TOO_MUCH_SQL (-100) -#define PYSQLITE_SQL_WRONG_TYPE (-101) - typedef struct { PyObject_HEAD @@ -43,10 +40,9 @@ typedef struct PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Statement; -extern PyTypeObject pysqlite_StatementType; +extern PyTypeObject *pysqlite_StatementType; -int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql); -void pysqlite_statement_dealloc(pysqlite_Statement* self); +pysqlite_Statement *pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql); int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter); void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters); @@ -55,6 +51,6 @@ int pysqlite_statement_finalize(pysqlite_Statement* self); int pysqlite_statement_reset(pysqlite_Statement* self); void pysqlite_statement_mark_dirty(pysqlite_Statement* self); -int pysqlite_statement_setup_types(void); +int pysqlite_statement_setup_types(PyObject *module); #endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/util.c b/contrib/tools/python3/src/Modules/_sqlite/util.c index 1dbabcdd94a..0f4eba0ab31 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/util.c +++ b/contrib/tools/python3/src/Modules/_sqlite/util.c @@ -28,15 +28,9 @@ int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection) { int rc; - if (statement == NULL) { - /* this is a workaround for SQLite 3.5 and later. it now apparently - * returns NULL for "no-operation" statements */ - rc = SQLITE_OK; - } else { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_step(statement); - Py_END_ALLOW_THREADS - } + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_step(statement); + Py_END_ALLOW_THREADS return rc; } diff --git a/contrib/tools/python3/src/Modules/_sqlite/util.h b/contrib/tools/python3/src/Modules/_sqlite/util.h index c5a220e9b0a..cff31cda957 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/util.h +++ b/contrib/tools/python3/src/Modules/_sqlite/util.h @@ -39,10 +39,4 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st); sqlite_int64 _pysqlite_long_as_int64(PyObject * value); -#if SQLITE_VERSION_NUMBER >= 3007014 -#define SQLITE3_CLOSE sqlite3_close_v2 -#else -#define SQLITE3_CLOSE sqlite3_close -#endif - #endif diff --git a/contrib/tools/python3/src/Modules/_sre.c b/contrib/tools/python3/src/Modules/_sre.c index 338530e2dc9..911626dafc9 100644 --- a/contrib/tools/python3/src/Modules/_sre.c +++ b/contrib/tools/python3/src/Modules/_sre.c @@ -41,6 +41,8 @@ static const char copyright[] = #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "structmember.h" // PyMemberDef #include "sre.h" @@ -196,7 +198,7 @@ static void data_stack_dealloc(SRE_STATE* state) { if (state->data_stack) { - PyMem_FREE(state->data_stack); + PyMem_Free(state->data_stack); state->data_stack = NULL; } state->data_stack_size = state->data_stack_base = 0; @@ -211,8 +213,8 @@ data_stack_grow(SRE_STATE* state, Py_ssize_t size) if (cursize < minsize) { void* stack; cursize = minsize+minsize/4+1024; - TRACE(("allocate/grow stack %" PY_FORMAT_SIZE_T "d\n", cursize)); - stack = PyMem_REALLOC(state->data_stack, cursize); + TRACE(("allocate/grow stack %zd\n", cursize)); + stack = PyMem_Realloc(state->data_stack, cursize); if (!stack) { data_stack_dealloc(state); return SRE_ERROR_MEMORY; @@ -247,22 +249,36 @@ data_stack_grow(SRE_STATE* state, Py_ssize_t size) /* -------------------------------------------------------------------- */ /* factories and destructors */ -/* see sre.h for object declarations */ -static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, Py_ssize_t); -static PyObject *pattern_scanner(PatternObject *, PyObject *, Py_ssize_t, Py_ssize_t); +/* module state */ +typedef struct { + PyTypeObject *Pattern_Type; + PyTypeObject *Match_Type; + PyTypeObject *Scanner_Type; +} _sremodulestate; + +static _sremodulestate * +get_sre_module_state(PyObject *m) +{ + _sremodulestate *state = (_sremodulestate *)_PyModule_GetState(m); + assert(state); + return state; +} + +static struct PyModuleDef sremodule; +#define get_sre_module_state_by_class(cls) \ + (get_sre_module_state(PyType_GetModule(cls))) +/* see sre.h for object declarations */ +static PyObject*pattern_new_match(_sremodulestate *, PatternObject*, SRE_STATE*, Py_ssize_t); +static PyObject *pattern_scanner(_sremodulestate *, PatternObject *, PyObject *, Py_ssize_t, Py_ssize_t); /*[clinic input] module _sre -class _sre.SRE_Pattern "PatternObject *" "&Pattern_Type" -class _sre.SRE_Match "MatchObject *" "&Match_Type" -class _sre.SRE_Scanner "ScannerObject *" "&Scanner_Type" +class _sre.SRE_Pattern "PatternObject *" "get_sre_module_state_by_class(tp)->Pattern_Type" +class _sre.SRE_Match "MatchObject *" "get_sre_module_state_by_class(tp)->Match_Type" +class _sre.SRE_Scanner "ScannerObject *" "get_sre_module_state_by_class(tp)->Scanner_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0230ec19a0deac8]*/ - -static PyTypeObject Pattern_Type; -static PyTypeObject Match_Type; -static PyTypeObject Scanner_Type; +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fe2966e32b66a231]*/ /*[clinic input] _sre.getcodesize -> int @@ -457,7 +473,7 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, /* We add an explicit cast here because MSVC has a bug when compiling C code where it believes that `const void**` cannot be safely casted to `void*`, see bpo-39943 for details. */ - PyMem_Del((void*) state->mark); + PyMem_Free((void*) state->mark); state->mark = NULL; if (state->buffer.buf) PyBuffer_Release(&state->buffer); @@ -472,7 +488,7 @@ state_fini(SRE_STATE* state) Py_XDECREF(state->string); data_stack_dealloc(state); /* See above PyMem_Del for why we explicitly cast here. */ - PyMem_Del((void*) state->mark); + PyMem_Free((void*) state->mark); state->mark = NULL; } @@ -546,15 +562,37 @@ pattern_error(Py_ssize_t status) } } +static int +pattern_traverse(PatternObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->groupindex); + Py_VISIT(self->indexgroup); + Py_VISIT(self->pattern); + return 0; +} + +static int +pattern_clear(PatternObject *self) +{ + Py_CLEAR(self->groupindex); + Py_CLEAR(self->indexgroup); + Py_CLEAR(self->pattern); + return 0; +} + static void pattern_dealloc(PatternObject* self) { - if (self->weakreflist != NULL) + PyTypeObject *tp = Py_TYPE(self); + + PyObject_GC_UnTrack(self); + if (self->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); - Py_XDECREF(self->pattern); - Py_XDECREF(self->groupindex); - Py_XDECREF(self->indexgroup); - PyObject_DEL(self); + } + (void)pattern_clear(self); + tp->tp_free(self); + Py_DECREF(tp); } LOCAL(Py_ssize_t) @@ -582,6 +620,8 @@ sre_search(SRE_STATE* state, SRE_CODE* pattern) /*[clinic input] _sre.SRE_Pattern.match + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -590,10 +630,12 @@ Matches zero or more characters at the beginning of the string. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=ea2d838888510661 input=a2ba191647abebe5]*/ +_sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=ec6208ea58a0cca0 input=4bdb9c3e564d13ac]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE state; Py_ssize_t status; PyObject *match; @@ -613,7 +655,7 @@ _sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, return NULL; } - match = pattern_new_match(self, &state, status); + match = pattern_new_match(module_state, self, &state, status); state_fini(&state); return match; } @@ -621,6 +663,8 @@ _sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, /*[clinic input] _sre.SRE_Pattern.fullmatch + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -629,10 +673,12 @@ Matches against all of the string. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=5833c47782a35f4a input=d9fb03a7625b5828]*/ +_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=625b75b027ef94da input=50981172ab0fcfdd]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE state; Py_ssize_t status; PyObject *match; @@ -653,7 +699,7 @@ _sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, return NULL; } - match = pattern_new_match(self, &state, status); + match = pattern_new_match(module_state, self, &state, status); state_fini(&state); return match; } @@ -661,6 +707,8 @@ _sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, /*[clinic input] _sre.SRE_Pattern.search + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -671,10 +719,12 @@ Return None if no position in the string matches. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=25f302a644e951e8 input=4ae5cb7dc38fed1b]*/ +_sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=bd7f2d9d583e1463 input=afa9afb66a74a4b3]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE state; Py_ssize_t status; PyObject *match; @@ -693,7 +743,7 @@ _sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, return NULL; } - match = pattern_new_match(self, &state, status); + match = pattern_new_match(module_state, self, &state, status); state_fini(&state); return match; } @@ -825,6 +875,8 @@ error: /*[clinic input] _sre.SRE_Pattern.finditer + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -835,15 +887,17 @@ For each match, the iterator returns a match object. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=0bbb1a0aeb38bb14 input=612aab69e9fe08e4]*/ +_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=1791dbf3618ade56 input=812e332a4848cbaf]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); PyObject* scanner; PyObject* search; PyObject* iterator; - scanner = pattern_scanner(self, string, pos, endpos); + scanner = pattern_scanner(module_state, self, string, pos, endpos); if (!scanner) return NULL; @@ -861,6 +915,8 @@ _sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, /*[clinic input] _sre.SRE_Pattern.scanner + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -868,11 +924,14 @@ _sre.SRE_Pattern.scanner [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=54ea548aed33890b input=3aacdbde77a3a637]*/ +_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=f70cd506112f1bd9 input=2e487e5151bcee4c]*/ { - return pattern_scanner(self, string, pos, endpos); + _sremodulestate *module_state = get_sre_module_state_by_class(cls); + + return pattern_scanner(module_state, self, string, pos, endpos); } /*[clinic input] @@ -979,8 +1038,12 @@ error: } static PyObject* -pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, - Py_ssize_t count, Py_ssize_t subn) +pattern_subx(_sremodulestate* module_state, + PatternObject* self, + PyObject* ptemplate, + PyObject* string, + Py_ssize_t count, + Py_ssize_t subn) { SRE_STATE state; PyObject* list; @@ -1082,7 +1145,7 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, if (filter_is_callable) { /* pass match object through filter */ - match = pattern_new_match(self, &state, 1); + match = pattern_new_match(module_state, self, &state, 1); if (!match) goto error; item = PyObject_CallOneArg(filter, match); @@ -1162,6 +1225,8 @@ error: /*[clinic input] _sre.SRE_Pattern.sub + cls: defining_class + / repl: object string: object count: Py_ssize_t = 0 @@ -1170,16 +1235,20 @@ Return the string obtained by replacing the leftmost non-overlapping occurrences [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count) -/*[clinic end generated code: output=1dbf2ec3479cba00 input=c53d70be0b3caf86]*/ +_sre_SRE_Pattern_sub_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, Py_ssize_t count) +/*[clinic end generated code: output=4be141ab04bca60d input=d8d1d4ac2311a07c]*/ { - return pattern_subx(self, repl, string, count, 0); + _sremodulestate *module_state = get_sre_module_state_by_class(cls); + + return pattern_subx(module_state, self, repl, string, count, 0); } /*[clinic input] _sre.SRE_Pattern.subn + cls: defining_class + / repl: object string: object count: Py_ssize_t = 0 @@ -1188,11 +1257,14 @@ Return the tuple (new_string, number_of_subs_made) found by replacing the leftmo [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count) -/*[clinic end generated code: output=0d9522cd529e9728 input=e7342d7ce6083577]*/ +_sre_SRE_Pattern_subn_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, + Py_ssize_t count) +/*[clinic end generated code: output=da02fd85258b1e1f input=8b78a65b8302e58d]*/ { - return pattern_subx(self, repl, string, count, 1); + _sremodulestate *module_state = get_sre_module_state_by_class(cls); + + return pattern_subx(module_state, self, repl, string, count, 1); } /*[clinic input] @@ -1337,12 +1409,13 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, { /* "compile" pattern descriptor to pattern object */ + _sremodulestate *module_state = get_sre_module_state(module); PatternObject* self; Py_ssize_t i, n; n = PyList_GET_SIZE(code); /* coverity[ampersand_in_size] */ - self = PyObject_NewVar(PatternObject, &Pattern_Type, n); + self = PyObject_GC_NewVar(PatternObject, module_state->Pattern_Type, n); if (!self) return NULL; self->weakreflist = NULL; @@ -1362,6 +1435,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, break; } } + PyObject_GC_Track(self); if (PyErr_Occurred()) { Py_DECREF(self); @@ -1883,13 +1957,34 @@ _validate(PatternObject *self) /* -------------------------------------------------------------------- */ /* match methods */ +static int +match_traverse(MatchObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->string); + Py_VISIT(self->regs); + Py_VISIT(self->pattern); + return 0; +} + +static int +match_clear(MatchObject *self) +{ + Py_CLEAR(self->string); + Py_CLEAR(self->regs); + Py_CLEAR(self->pattern); + return 0; +} + static void match_dealloc(MatchObject* self) { - Py_XDECREF(self->regs); - Py_XDECREF(self->string); - Py_DECREF(self->pattern); - PyObject_DEL(self); + PyTypeObject *tp = Py_TYPE(self); + + PyObject_GC_UnTrack(self); + (void)match_clear(self); + tp->tp_free(self); + Py_DECREF(tp); } static PyObject* @@ -1999,7 +2094,7 @@ match_group(MatchObject* self, PyObject* args) switch (size) { case 0: - result = match_getslice(self, _PyLong_Zero, Py_None); + result = match_getslice(self, _PyLong_GetZero(), Py_None); break; case 1: result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None); @@ -2318,7 +2413,10 @@ match_repr(MatchObject *self) static PyObject* -pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) +pattern_new_match(_sremodulestate* module_state, + PatternObject* pattern, + SRE_STATE* state, + Py_ssize_t status) { /* create match object (from state object) */ @@ -2331,8 +2429,9 @@ pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) /* create match object (with room for extra group marks) */ /* coverity[ampersand_in_size] */ - match = PyObject_NewVar(MatchObject, &Match_Type, - 2*(pattern->groups+1)); + match = PyObject_GC_NewVar(MatchObject, + module_state->Match_Type, + 2*(pattern->groups+1)); if (!match) return NULL; @@ -2365,6 +2464,7 @@ pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) match->lastindex = state->lastindex; + PyObject_GC_Track(match); return (PyObject*) match; } else if (status == 0) { @@ -2383,12 +2483,31 @@ pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) /* -------------------------------------------------------------------- */ /* scanner methods (experimental) */ +static int +scanner_traverse(ScannerObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->pattern); + return 0; +} + +static int +scanner_clear(ScannerObject *self) +{ + Py_CLEAR(self->pattern); + return 0; +} + static void scanner_dealloc(ScannerObject* self) { + PyTypeObject *tp = Py_TYPE(self); + + PyObject_GC_UnTrack(self); state_fini(&self->state); - Py_XDECREF(self->pattern); - PyObject_DEL(self); + (void)scanner_clear(self); + tp->tp_free(self); + Py_DECREF(tp); } static int @@ -2413,12 +2532,16 @@ scanner_end(ScannerObject* self) /*[clinic input] _sre.SRE_Scanner.match + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self) -/*[clinic end generated code: output=936b30c63d4b81eb input=881a0154f8c13d9a]*/ +_sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=6e22c149dc0f0325 input=b5146e1f30278cb7]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE* state = &self->state; PyObject* match; Py_ssize_t status; @@ -2441,8 +2564,8 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) return NULL; } - match = pattern_new_match((PatternObject*) self->pattern, - state, status); + match = pattern_new_match(module_state, (PatternObject*) self->pattern, + state, status); if (status == 0) state->start = NULL; @@ -2459,12 +2582,16 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) /*[clinic input] _sre.SRE_Scanner.search + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_sre_SRE_Scanner_search_impl(ScannerObject *self) -/*[clinic end generated code: output=7dc211986088f025 input=161223ee92ef9270]*/ +_sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=23e8fc78013f9161 input=056c2d37171d0bf2]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE* state = &self->state; PyObject* match; Py_ssize_t status; @@ -2487,8 +2614,8 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) return NULL; } - match = pattern_new_match((PatternObject*) self->pattern, - state, status); + match = pattern_new_match(module_state, (PatternObject*) self->pattern, + state, status); if (status == 0) state->start = NULL; @@ -2502,12 +2629,16 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) } static PyObject * -pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_t endpos) +pattern_scanner(_sremodulestate *module_state, + PatternObject *self, + PyObject *string, + Py_ssize_t pos, + Py_ssize_t endpos) { ScannerObject* scanner; /* create scanner object */ - scanner = PyObject_New(ScannerObject, &Scanner_Type); + scanner = PyObject_GC_New(ScannerObject, module_state->Scanner_Type); if (!scanner) return NULL; scanner->pattern = NULL; @@ -2522,6 +2653,7 @@ pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_ Py_INCREF(self); scanner->pattern = (PyObject*) self; + PyObject_GC_Track(scanner); return (PyObject*) scanner; } @@ -2551,6 +2683,8 @@ pattern_hash(PatternObject *self) static PyObject* pattern_richcompare(PyObject *lefto, PyObject *righto, int op) { + PyTypeObject *tp = Py_TYPE(lefto); + _sremodulestate *module_state = get_sre_module_state_by_class(tp); PatternObject *left, *right; int cmp; @@ -2558,7 +2692,8 @@ pattern_richcompare(PyObject *lefto, PyObject *righto, int op) Py_RETURN_NOTIMPLEMENTED; } - if (!Py_IS_TYPE(lefto, &Pattern_Type) || !Py_IS_TYPE(righto, &Pattern_Type)) { + if (!Py_IS_TYPE(righto, module_state->Pattern_Type)) + { Py_RETURN_NOTIMPLEMENTED; } @@ -2627,47 +2762,31 @@ static PyMemberDef pattern_members[] = { "The regex matching flags."}, {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY, "The number of capturing groups in the pattern."}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(PatternObject, weakreflist), READONLY}, {NULL} /* Sentinel */ }; -static PyTypeObject Pattern_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "re.Pattern", - sizeof(PatternObject), sizeof(SRE_CODE), - (destructor)pattern_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)pattern_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)pattern_hash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - pattern_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - pattern_richcompare, /* tp_richcompare */ - offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pattern_methods, /* tp_methods */ - pattern_members, /* tp_members */ - pattern_getset, /* tp_getset */ +static PyType_Slot pattern_slots[] = { + {Py_tp_dealloc, (destructor)pattern_dealloc}, + {Py_tp_repr, (reprfunc)pattern_repr}, + {Py_tp_hash, (hashfunc)pattern_hash}, + {Py_tp_doc, (void *)pattern_doc}, + {Py_tp_richcompare, pattern_richcompare}, + {Py_tp_methods, pattern_methods}, + {Py_tp_members, pattern_members}, + {Py_tp_getset, pattern_getset}, + {Py_tp_traverse, pattern_traverse}, + {Py_tp_clear, pattern_clear}, + {0, NULL}, }; -/* Match objects do not support length or assignment, but do support - __getitem__. */ -static PyMappingMethods match_as_mapping = { - NULL, - (binaryfunc)match_getitem, - NULL +static PyType_Spec pattern_spec = { + .name = "re.Pattern", + .basicsize = sizeof(PatternObject), + .itemsize = sizeof(SRE_CODE), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + .slots = pattern_slots, }; static PyMethodDef match_methods[] = { @@ -2709,37 +2828,33 @@ static PyMemberDef match_members[] = { /* FIXME: implement setattr("string", None) as a special case (to detach the associated string, if any */ +static PyType_Slot match_slots[] = { + {Py_tp_dealloc, match_dealloc}, + {Py_tp_repr, match_repr}, + {Py_tp_doc, (void *)match_doc}, + {Py_tp_methods, match_methods}, + {Py_tp_members, match_members}, + {Py_tp_getset, match_getset}, + {Py_tp_traverse, match_traverse}, + {Py_tp_clear, match_clear}, + + /* As mapping. + * + * Match objects do not support length or assignment, but do support + * __getitem__. + */ + {Py_mp_subscript, match_getitem}, + + {0, NULL}, +}; -static PyTypeObject Match_Type = { - PyVarObject_HEAD_INIT(NULL,0) - "re.Match", - sizeof(MatchObject), sizeof(Py_ssize_t), - (destructor)match_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)match_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - &match_as_mapping, /* 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 */ - match_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - match_methods, /* tp_methods */ - match_members, /* tp_members */ - match_getset, /* tp_getset */ +static PyType_Spec match_spec = { + .name = "re.Match", + .basicsize = sizeof(MatchObject), + .itemsize = sizeof(Py_ssize_t), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + .slots = match_slots, }; static PyMethodDef scanner_methods[] = { @@ -2754,36 +2869,21 @@ static PyMemberDef scanner_members[] = { {NULL} /* Sentinel */ }; -static PyTypeObject Scanner_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_" SRE_MODULE ".SRE_Scanner", - sizeof(ScannerObject), 0, - (destructor)scanner_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, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - scanner_methods, /* tp_methods */ - scanner_members, /* tp_members */ - 0, /* tp_getset */ +static PyType_Slot scanner_slots[] = { + {Py_tp_dealloc, scanner_dealloc}, + {Py_tp_methods, scanner_methods}, + {Py_tp_members, scanner_members}, + {Py_tp_traverse, scanner_traverse}, + {Py_tp_clear, scanner_clear}, + {0, NULL}, +}; + +static PyType_Spec scanner_spec = { + .name = "_" SRE_MODULE ".SRE_Scanner", + .basicsize = sizeof(ScannerObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + .slots = scanner_slots, }; static PyMethodDef _functions[] = { @@ -2796,64 +2896,108 @@ static PyMethodDef _functions[] = { {NULL, NULL} }; -static struct PyModuleDef sremodule = { - PyModuleDef_HEAD_INIT, - "_" SRE_MODULE, - NULL, - -1, - _functions, - NULL, - NULL, - NULL, - NULL -}; +static int +sre_traverse(PyObject *module, visitproc visit, void *arg) +{ + _sremodulestate *state = get_sre_module_state(module); + + Py_VISIT(state->Pattern_Type); + Py_VISIT(state->Match_Type); + Py_VISIT(state->Scanner_Type); + + return 0; +} -PyMODINIT_FUNC PyInit__sre(void) +static int +sre_clear(PyObject *module) { - PyObject* m; - PyObject* d; - PyObject* x; + _sremodulestate *state = get_sre_module_state(module); - /* Patch object types */ - if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) || - PyType_Ready(&Scanner_Type)) - return NULL; + Py_CLEAR(state->Pattern_Type); + Py_CLEAR(state->Match_Type); + Py_CLEAR(state->Scanner_Type); - m = PyModule_Create(&sremodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); + return 0; +} - x = PyLong_FromLong(SRE_MAGIC); - if (x) { - PyDict_SetItemString(d, "MAGIC", x); - Py_DECREF(x); - } +static void +sre_free(void *module) +{ + sre_clear((PyObject *)module); +} + +#define CREATE_TYPE(m, type, spec) \ +do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(m, spec, NULL); \ + if (type == NULL) { \ + goto error; \ + } \ +} while (0) + +#define ADD_ULONG_CONSTANT(module, name, value) \ + do { \ + PyObject *o = PyLong_FromUnsignedLong(value); \ + if (!o) \ + goto error; \ + int res = PyModule_AddObjectRef(module, name, o); \ + Py_DECREF(o); \ + if (res < 0) { \ + goto error; \ + } \ +} while (0) - x = PyLong_FromLong(sizeof(SRE_CODE)); - if (x) { - PyDict_SetItemString(d, "CODESIZE", x); - Py_DECREF(x); - } +static int +sre_exec(PyObject *m) +{ + _sremodulestate *state; - x = PyLong_FromUnsignedLong(SRE_MAXREPEAT); - if (x) { - PyDict_SetItemString(d, "MAXREPEAT", x); - Py_DECREF(x); + /* Create heap types */ + state = get_sre_module_state(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); + + if (PyModule_AddIntConstant(m, "MAGIC", SRE_MAGIC) < 0) { + goto error; } - x = PyLong_FromUnsignedLong(SRE_MAXGROUPS); - if (x) { - PyDict_SetItemString(d, "MAXGROUPS", x); - Py_DECREF(x); + if (PyModule_AddIntConstant(m, "CODESIZE", sizeof(SRE_CODE)) < 0) { + goto error; } - x = PyUnicode_FromString(copyright); - if (x) { - PyDict_SetItemString(d, "copyright", x); - Py_DECREF(x); + ADD_ULONG_CONSTANT(m, "MAXREPEAT", SRE_MAXREPEAT); + ADD_ULONG_CONSTANT(m, "MAXGROUPS", SRE_MAXGROUPS); + + if (PyModule_AddStringConstant(m, "copyright", copyright) < 0) { + goto error; } - return m; + + return 0; + +error: + return -1; +} + +static PyModuleDef_Slot sre_slots[] = { + {Py_mod_exec, sre_exec}, + {0, NULL}, +}; + +static struct PyModuleDef sremodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_" SRE_MODULE, + .m_size = sizeof(_sremodulestate), + .m_methods = _functions, + .m_slots = sre_slots, + .m_traverse = sre_traverse, + .m_free = sre_free, + .m_clear = sre_clear, +}; + +PyMODINIT_FUNC +PyInit__sre(void) +{ + return PyModuleDef_Init(&sremodule); } /* vim:ts=4:sw=4:et diff --git a/contrib/tools/python3/src/Modules/_ssl.c b/contrib/tools/python3/src/Modules/_ssl.c index b42e78e916b..983a183382a 100644 --- a/contrib/tools/python3/src/Modules/_ssl.c +++ b/contrib/tools/python3/src/Modules/_ssl.c @@ -25,13 +25,22 @@ #include "Python.h" +/* Include symbols from _socket module */ +#include "socketmodule.h" + +#ifdef _MSC_VER +#include +#endif + +#include "_ssl.h" + /* Redefined below for Windows debug builds after important #includes */ #define _PySSL_FIX_ERRNO #define PySSL_BEGIN_ALLOW_THREADS_S(save) \ - do { if (_ssl_locks_count>0) { (save) = PyEval_SaveThread(); } } while (0) + do { (save) = PyEval_SaveThread(); } while(0) #define PySSL_END_ALLOW_THREADS_S(save) \ - do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } _PySSL_FIX_ERRNO; } while (0) + do { PyEval_RestoreThread(save); _PySSL_FIX_ERRNO; } while(0) #define PySSL_BEGIN_ALLOW_THREADS { \ PyThreadState *_save = NULL; \ PySSL_BEGIN_ALLOW_THREADS_S(_save); @@ -39,10 +48,6 @@ #define PySSL_UNBLOCK_THREADS PySSL_BEGIN_ALLOW_THREADS_S(_save); #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } -/* Include symbols from _socket module */ -#include "socketmodule.h" - -static PySocketModule_APIObject PySocketModule; #if defined(HAVE_POLL_H) #include @@ -50,10 +55,6 @@ static PySocketModule_APIObject PySocketModule; #include #endif -#ifdef _MSC_VER -#include -#endif - /* Include OpenSSL header files */ #include "openssl/rsa.h" #include "openssl/crypto.h" @@ -66,38 +67,17 @@ static PySocketModule_APIObject PySocketModule; #include "openssl/bio.h" #include "openssl/dh.h" -#ifndef HAVE_X509_VERIFY_PARAM_SET1_HOST -# ifdef LIBRESSL_VERSION_NUMBER -# error "LibreSSL is missing X509_VERIFY_PARAM_set1_host(), see https://github.com/libressl-portable/portable/issues/381" -# elif OPENSSL_VERSION_NUMBER > 0x1000200fL -# define HAVE_X509_VERIFY_PARAM_SET1_HOST -# else -# error "libssl is too old and does not support X509_VERIFY_PARAM_set1_host()" -# endif -#endif - #ifndef OPENSSL_THREADS # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" #endif -/* SSL error object */ -static PyObject *PySSLErrorObject; -static PyObject *PySSLCertVerificationErrorObject; -static PyObject *PySSLZeroReturnErrorObject; -static PyObject *PySSLWantReadErrorObject; -static PyObject *PySSLWantWriteErrorObject; -static PyObject *PySSLSyscallErrorObject; -static PyObject *PySSLEOFErrorObject; -/* Error mappings */ -static PyObject *err_codes_to_names; -static PyObject *err_names_to_codes; -static PyObject *lib_codes_to_names; struct py_ssl_error_code { const char *mnemonic; int library, reason; }; + struct py_ssl_library_code { const char *library; int code; @@ -146,15 +126,10 @@ static void _PySSLFixErrno(void) { #include "_ssl_data.h" #endif -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) -# define OPENSSL_VERSION_1_1 1 -# define PY_OPENSSL_1_1_API 1 +/* OpenSSL API 1.1.0+ does not include version methods */ +#ifndef OPENSSL_NO_SSL3_METHOD +extern const SSL_METHOD *SSLv3_method(void); #endif - -/* OpenSSL API 1.1.0+ does not include version methods. Define the methods - * unless OpenSSL is compiled without the methods. It's the easiest way to - * make 1.0.2, 1.1.0, 1.1.1, and 3.0.0 happy without deprecation warnings. - */ #ifndef OPENSSL_NO_TLS1_METHOD extern const SSL_METHOD *TLSv1_method(void); #endif @@ -165,129 +140,12 @@ extern const SSL_METHOD *TLSv1_1_method(void); extern const SSL_METHOD *TLSv1_2_method(void); #endif -/* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ -#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL -# define PY_OPENSSL_1_1_API 1 -#endif - -/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f - * This includes the SSL_set_SSL_CTX() function. - */ -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -# define HAVE_SNI 1 -#else -# define HAVE_SNI 0 -#endif - -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation -# define HAVE_ALPN 1 -#else -# define HAVE_ALPN 0 -#endif - -/* We cannot rely on OPENSSL_NO_NEXTPROTONEG because LibreSSL 2.6.1 dropped - * NPN support but did not set OPENSSL_NO_NEXTPROTONEG for compatibility - * reasons. The check for TLSEXT_TYPE_next_proto_neg works with - * OpenSSL 1.0.1+ and LibreSSL. - * OpenSSL 1.1.1-pre1 dropped NPN but still has TLSEXT_TYPE_next_proto_neg. - */ -#ifdef OPENSSL_NO_NEXTPROTONEG -# define HAVE_NPN 0 -#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) -# define HAVE_NPN 0 -#elif defined(TLSEXT_TYPE_next_proto_neg) -# define HAVE_NPN 1 -#else -# define HAVE_NPN 0 -#endif - -#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) -#define HAVE_OPENSSL_KEYLOG 1 -#endif - #ifndef INVALID_SOCKET /* MS defines this */ #define INVALID_SOCKET (-1) #endif -/* OpenSSL 1.0.2 and LibreSSL needs extra code for locking */ -#ifndef OPENSSL_VERSION_1_1 -#define HAVE_OPENSSL_CRYPTO_LOCK -#endif - -#if defined(OPENSSL_VERSION_1_1) && !defined(OPENSSL_NO_SSL2) +/* OpenSSL 1.1 does not have SSL 2.0 */ #define OPENSSL_NO_SSL2 -#endif - -#ifndef PY_OPENSSL_1_1_API -/* OpenSSL 1.1 API shims for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 */ - -#define TLS_method SSLv23_method -#define TLS_client_method SSLv23_client_method -#define TLS_server_method SSLv23_server_method -#define ASN1_STRING_get0_data ASN1_STRING_data -#define X509_get0_notBefore X509_get_notBefore -#define X509_get0_notAfter X509_get_notAfter -#define OpenSSL_version_num SSLeay -#define OpenSSL_version SSLeay_version -#define OPENSSL_VERSION SSLEAY_VERSION - -static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) -{ - return ne->set; -} - -#ifndef OPENSSL_NO_COMP -/* LCOV_EXCL_START */ -static int COMP_get_type(const COMP_METHOD *meth) -{ - return meth->type; -} -/* LCOV_EXCL_STOP */ -#endif - -static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) -{ - return ctx->default_passwd_callback; -} - -static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) -{ - return ctx->default_passwd_callback_userdata; -} - -static int X509_OBJECT_get_type(X509_OBJECT *x) -{ - return x->type; -} - -static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x) -{ - return x->data.x509; -} - -static int BIO_up_ref(BIO *b) -{ - CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO); - return 1; -} - -static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) { - return store->objs; -} - -static int -SSL_SESSION_has_ticket(const SSL_SESSION *s) -{ - return (s->tlsext_ticklen > 0) ? 1 : 0; -} - -static unsigned long -SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) -{ - return s->tlsext_tick_lifetime_hint; -} - -#endif /* OpenSSL < 1.1.0 or LibreSSL < 2.7.0 */ /* Default cipher suites */ #ifndef PY_SSL_DEFAULT_CIPHERS @@ -298,15 +156,27 @@ SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) #ifndef PY_SSL_DEFAULT_CIPHER_STRING #error "Py_SSL_DEFAULT_CIPHERS 0 needs Py_SSL_DEFAULT_CIPHER_STRING" #endif + #ifndef PY_SSL_MIN_PROTOCOL + #define PY_SSL_MIN_PROTOCOL TLS1_2_VERSION + #endif #elif PY_SSL_DEFAULT_CIPHERS == 1 /* Python custom selection of sensible cipher suites - * DEFAULT: OpenSSL's default cipher list. Since 1.0.2 the list is in sensible order. + * @SECLEVEL=2: security level 2 with 112 bits minimum security (e.g. 2048 bits RSA key) + * ECDH+*: enable ephemeral elliptic curve Diffie-Hellman + * DHE+*: fallback to ephemeral finite field Diffie-Hellman + * encryption order: AES AEAD (GCM), ChaCha AEAD, AES CBC * !aNULL:!eNULL: really no NULL ciphers - * !MD5:!3DES:!DES:!RC4:!IDEA:!SEED: no weak or broken algorithms on old OpenSSL versions. * !aDSS: no authentication with discrete logarithm DSA algorithm - * !SRP:!PSK: no secure remote password or pre-shared key authentication + * !SHA1: no weak SHA1 MAC + * !AESCCM: no CCM mode, it's uncommon and slow + * + * Based on Hynek's excellent blog post (update 2021-02-11) + * https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ */ - #define PY_SSL_DEFAULT_CIPHER_STRING "DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK" + #define PY_SSL_DEFAULT_CIPHER_STRING "DEFAULT:ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES:DHE+AES:!aNULL:!eNULL:!aDSS:!SHA1:!AESCCM" + #ifndef PY_SSL_MIN_PROTOCOL + #define PY_SSL_MIN_PROTOCOL TLS1_2_VERSION + #endif #elif PY_SSL_DEFAULT_CIPHERS == 2 /* Ignored in SSLContext constructor, only used to as _ssl.DEFAULT_CIPHER_STRING */ #define PY_SSL_DEFAULT_CIPHER_STRING SSL_DEFAULT_CIPHER_LIST @@ -399,24 +269,10 @@ enum py_proto_version { #endif }; - -/* serves as a flag to see whether we've initialized the SSL thread support. */ -/* 0 means no, greater than 0 means yes */ - -static unsigned int _ssl_locks_count = 0; - /* SSL socket object */ #define X509_NAME_MAXLEN 256 -/* SSL_CTX_clear_options() and SSL_clear_options() were first added in - * OpenSSL 0.9.8m but do not appear in some 0.9.9-dev versions such the - * 0.9.9 from "May 2008" that NetBSD 5.0 uses. */ -#if OPENSSL_VERSION_NUMBER >= 0x009080dfL && OPENSSL_VERSION_NUMBER != 0x00909000L -# define HAVE_SSL_CTX_CLEAR_OPTIONS -#else -# undef HAVE_SSL_CTX_CLEAR_OPTIONS -#endif /* In case of 'tls-unique' it will be 12 bytes for TLS, 36 bytes for * older SSL, but let's be safe */ @@ -426,17 +282,9 @@ static unsigned int _ssl_locks_count = 0; typedef struct { PyObject_HEAD SSL_CTX *ctx; -#if HAVE_NPN - unsigned char *npn_protocols; - int npn_protocols_len; -#endif -#if HAVE_ALPN unsigned char *alpn_protocols; unsigned int alpn_protocols_len; -#endif -#ifndef OPENSSL_NO_TLSEXT PyObject *set_sni_cb; -#endif int check_hostname; /* OpenSSL has no API to get hostflags from X509_VERIFY_PARAM* struct. * We have to maintain our own copy. OpenSSL's hostflags default to 0. @@ -447,10 +295,10 @@ typedef struct { int post_handshake_auth; #endif PyObject *msg_cb; -#ifdef HAVE_OPENSSL_KEYLOG PyObject *keylog_filename; BIO *keylog_bio; -#endif + /* Cached module state, also used in SSLSocket and SSLSession code. */ + _sslmodulestate *state; } PySSLContext; typedef struct { @@ -492,11 +340,6 @@ typedef struct { PySSLContext *ctx; } PySSLSession; -static PyTypeObject PySSLContext_Type; -static PyTypeObject PySSLSocket_Type; -static PyTypeObject PySSLMemoryBIO_Type; -static PyTypeObject PySSLSession_Type; - static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode) { _PySSLError err = { 0 }; @@ -513,12 +356,12 @@ static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode) /*[clinic input] module _ssl -class _ssl._SSLContext "PySSLContext *" "&PySSLContext_Type" -class _ssl._SSLSocket "PySSLSocket *" "&PySSLSocket_Type" -class _ssl.MemoryBIO "PySSLMemoryBIO *" "&PySSLMemoryBIO_Type" -class _ssl.SSLSession "PySSLSession *" "&PySSLSession_Type" +class _ssl._SSLContext "PySSLContext *" "get_state_type(type)->PySSLContext_Type" +class _ssl._SSLSocket "PySSLSocket *" "get_state_type(type)->PySSLSocket_Type" +class _ssl.MemoryBIO "PySSLMemoryBIO *" "get_state_type(type)->PySSLMemoryBIO_Type" +class _ssl.SSLSession "PySSLSession *" "get_state_type(type)->PySSLSession_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bdc67fafeeaa8109]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d293bed8bae240fd]*/ #include "clinic/_ssl.c.h" @@ -526,9 +369,6 @@ static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout); static int PySSL_set_owner(PySSLSocket *, PyObject *, void *); static int PySSL_set_session(PySSLSocket *, PyObject *, void *); -#define PySSLSocket_Check(v) Py_IS_TYPE(v, &PySSLSocket_Type) -#define PySSLMemoryBIO_Check(v) Py_IS_TYPE(v, &PySSLMemoryBIO_Type) -#define PySSLSession_Check(v) Py_IS_TYPE(v, &PySSLSession_Type) typedef enum { SOCKET_IS_NONBLOCKING, @@ -592,22 +432,21 @@ SSLError_str(PyOSErrorObject *self) } static PyType_Slot sslerror_type_slots[] = { - {Py_tp_base, NULL}, /* Filled out in module init as it's not a constant */ {Py_tp_doc, (void*)SSLError_doc}, {Py_tp_str, SSLError_str}, {0, 0}, }; static PyType_Spec sslerror_type_spec = { - "ssl.SSLError", - sizeof(PyOSErrorObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - sslerror_type_slots + .name = "ssl.SSLError", + .basicsize = sizeof(PyOSErrorObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE), + .slots = sslerror_type_slots }; static void -fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, +fill_and_set_sslerror(_sslmodulestate *state, + PySSLSocket *sslsock, PyObject *type, int ssl_errno, const char *errstr, int lineno, unsigned long errcode) { PyObject *err_value = NULL, *reason_obj = NULL, *lib_obj = NULL; @@ -626,7 +465,7 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, key = Py_BuildValue("ii", lib, reason); if (key == NULL) goto fail; - reason_obj = PyDict_GetItemWithError(err_codes_to_names, key); + reason_obj = PyDict_GetItemWithError(state->err_codes_to_names, key); Py_DECREF(key); if (reason_obj == NULL && PyErr_Occurred()) { goto fail; @@ -634,7 +473,7 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, key = PyLong_FromLong(lib); if (key == NULL) goto fail; - lib_obj = PyDict_GetItemWithError(lib_codes_to_names, key); + lib_obj = PyDict_GetItemWithError(state->lib_codes_to_names, key); Py_DECREF(key); if (lib_obj == NULL && PyErr_Occurred()) { goto fail; @@ -646,7 +485,7 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, errstr = "unknown error"; /* verify code for cert validation error */ - if ((sslsock != NULL) && (type == PySSLCertVerificationErrorObject)) { + if ((sslsock != NULL) && (type == state->PySSLCertVerificationErrorObject)) { const char *verify_str = NULL; long verify_code; @@ -657,23 +496,18 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, } switch (verify_code) { -#ifdef X509_V_ERR_HOSTNAME_MISMATCH - /* OpenSSL >= 1.0.2, LibreSSL >= 2.5.3 */ case X509_V_ERR_HOSTNAME_MISMATCH: verify_obj = PyUnicode_FromFormat( "Hostname mismatch, certificate is not valid for '%S'.", sslsock->server_hostname ); break; -#endif -#ifdef X509_V_ERR_IP_ADDRESS_MISMATCH case X509_V_ERR_IP_ADDRESS_MISMATCH: verify_obj = PyUnicode_FromFormat( "IP address mismatch, certificate is not valid for '%S'.", sslsock->server_hostname ); break; -#endif default: verify_str = X509_verify_cert_error_string(verify_code); if (verify_str != NULL) { @@ -723,7 +557,7 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, if (_PyObject_SetAttrId(err_value, &PyId_library, lib_obj)) goto fail; - if ((sslsock != NULL) && (type == PySSLCertVerificationErrorObject)) { + if ((sslsock != NULL) && (type == state->PySSLCertVerificationErrorObject)) { /* Only set verify code / message for SSLCertVerificationError */ if (_PyObject_SetAttrId(err_value, &PyId_verify_code, verify_code_obj)) @@ -754,12 +588,17 @@ PySSL_ChainExceptions(PySSLSocket *sslsock) { static PyObject * PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) { - PyObject *type = PySSLErrorObject; + PyObject *type; char *errstr = NULL; _PySSLError err; enum py_ssl_error p = PY_SSL_ERROR_NONE; unsigned long e = 0; + assert(sslsock != NULL); + + _sslmodulestate *state = get_state_sock(sslsock); + type = state->PySSLErrorObject; + assert(ret <= 0); e = ERR_peek_last_error(); @@ -769,17 +608,17 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) switch (err.ssl) { case SSL_ERROR_ZERO_RETURN: errstr = "TLS/SSL connection has been closed (EOF)"; - type = PySSLZeroReturnErrorObject; + type = state->PySSLZeroReturnErrorObject; p = PY_SSL_ERROR_ZERO_RETURN; break; case SSL_ERROR_WANT_READ: errstr = "The operation did not complete (read)"; - type = PySSLWantReadErrorObject; + type = state->PySSLWantReadErrorObject; p = PY_SSL_ERROR_WANT_READ; break; case SSL_ERROR_WANT_WRITE: p = PY_SSL_ERROR_WANT_WRITE; - type = PySSLWantWriteErrorObject; + type = state->PySSLWantWriteErrorObject; errstr = "The operation did not complete (write)"; break; case SSL_ERROR_WANT_X509_LOOKUP: @@ -796,7 +635,7 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) PySocketSockObject *s = GET_SOCKET(sslsock); if (ret == 0 || (((PyObject *)s) == Py_None)) { p = PY_SSL_ERROR_EOF; - type = PySSLEOFErrorObject; + type = state->PySSLEOFErrorObject; errstr = "EOF occurred in violation of protocol"; } else if (s && ret == -1) { /* underlying BIO reported an I/O error */ @@ -812,12 +651,12 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) } else { p = PY_SSL_ERROR_EOF; - type = PySSLEOFErrorObject; + type = state->PySSLEOFErrorObject; errstr = "EOF occurred in violation of protocol"; } } else { /* possible? */ p = PY_SSL_ERROR_SYSCALL; - type = PySSLSyscallErrorObject; + type = state->PySSLSyscallErrorObject; errstr = "Some I/O error occurred"; } } else { @@ -834,7 +673,7 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) } if (ERR_GET_LIB(e) == ERR_LIB_SSL && ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) { - type = PySSLCertVerificationErrorObject; + type = state->PySSLCertVerificationErrorObject; } break; } @@ -843,24 +682,34 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) errstr = "Invalid error code"; } } - fill_and_set_sslerror(sslsock, type, p, errstr, lineno, e); + fill_and_set_sslerror(state, sslsock, type, p, errstr, lineno, e); ERR_clear_error(); PySSL_ChainExceptions(sslsock); return NULL; } static PyObject * -_setSSLError (const char *errstr, int errcode, const char *filename, int lineno) { - +_setSSLError (_sslmodulestate *state, const char *errstr, int errcode, const char *filename, int lineno) +{ if (errstr == NULL) errcode = ERR_peek_last_error(); else errcode = 0; - fill_and_set_sslerror(NULL, PySSLErrorObject, errcode, errstr, lineno, errcode); + fill_and_set_sslerror(state, NULL, state->PySSLErrorObject, errcode, errstr, lineno, errcode); ERR_clear_error(); return NULL; } +static int +_ssl_deprecated(const char* msg, int stacklevel) { + return PyErr_WarnEx( + PyExc_DeprecationWarning, msg, stacklevel + ); +} + +#define PY_SSL_DEPRECATED(name, stacklevel, ret) \ + if (_ssl_deprecated((name), (stacklevel)) == -1) return (ret) + /* * SSL objects */ @@ -903,7 +752,7 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) /* Only send SNI extension for non-IP hostnames */ if (ip == NULL) { if (!SSL_set_tlsext_host_name(self->ssl, server_hostname)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } } @@ -912,13 +761,13 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) if (ip == NULL) { if (!X509_VERIFY_PARAM_set1_host(param, server_hostname, strlen(server_hostname))) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } } else { if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), ASN1_STRING_length(ip))) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } } @@ -942,7 +791,23 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, SSL_CTX *ctx = sslctx->ctx; _PySSLError err = { 0 }; - self = PyObject_New(PySSLSocket, &PySSLSocket_Type); + if ((socket_type == PY_SSL_SERVER) && + (sslctx->protocol == PY_SSL_VERSION_TLS_CLIENT)) { + _setSSLError(get_state_ctx(sslctx), + "Cannot create a server socket with a " + "PROTOCOL_TLS_CLIENT context", 0, __FILE__, __LINE__); + return NULL; + } + if ((socket_type == PY_SSL_CLIENT) && + (sslctx->protocol == PY_SSL_VERSION_TLS_SERVER)) { + _setSSLError(get_state_ctx(sslctx), + "Cannot create a client socket with a " + "PROTOCOL_TLS_SERVER context", 0, __FILE__, __LINE__); + return NULL; + } + + self = PyObject_GC_New(PySSLSocket, + get_state_ctx(sslctx)->PySSLSocket_Type); if (self == NULL) return NULL; @@ -966,7 +831,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, PySSL_END_ALLOW_THREADS if (self->ssl == NULL) { Py_DECREF(self); - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } /* bpo43522 and OpenSSL < 1.1.1l: copy hostflags manually */ @@ -1049,6 +914,8 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, return NULL; } } + + PyObject_GC_Track(self); return self; } @@ -1071,7 +938,8 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) if (sock) { if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", + _setSSLError(get_state_sock(self), + "Underlying socket connection gone", PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); return NULL; } @@ -1112,15 +980,15 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) } if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, + PyErr_SetString(PyExc_TimeoutError, ERRSTR("The handshake operation timed out")); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_sock(self)->PySSLErrorObject, ERRSTR("Underlying socket has been closed.")); goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_sock(self)->PySSLErrorObject, ERRSTR("Underlying socket too large for select().")); goto error; } else if (sockstate == SOCKET_IS_NONBLOCKING) { @@ -1141,7 +1009,7 @@ error: } static PyObject * -_asn1obj2py(const ASN1_OBJECT *name, int no_name) +_asn1obj2py(_sslmodulestate *state, const ASN1_OBJECT *name, int no_name) { char buf[X509_NAME_MAXLEN]; char *namebuf = buf; @@ -1150,7 +1018,7 @@ _asn1obj2py(const ASN1_OBJECT *name, int no_name) buflen = OBJ_obj2txt(namebuf, X509_NAME_MAXLEN, name, no_name); if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); return NULL; } /* initial buffer is too small for oid + terminating null byte */ @@ -1165,7 +1033,7 @@ _asn1obj2py(const ASN1_OBJECT *name, int no_name) } buflen = OBJ_obj2txt(namebuf, buflen + 1, name, no_name); if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); goto done; } } @@ -1185,24 +1053,37 @@ _asn1obj2py(const ASN1_OBJECT *name, int no_name) } static PyObject * -_create_tuple_for_attribute(ASN1_OBJECT *name, ASN1_STRING *value) +_create_tuple_for_attribute(_sslmodulestate *state, + ASN1_OBJECT *name, ASN1_STRING *value) { Py_ssize_t buflen; - unsigned char *valuebuf = NULL; - PyObject *attr; + PyObject *pyattr; + PyObject *pyname = _asn1obj2py(state, name, 0); - buflen = ASN1_STRING_to_UTF8(&valuebuf, value); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + if (pyname == NULL) { + _setSSLError(state, NULL, 0, __FILE__, __LINE__); return NULL; } - attr = Py_BuildValue("Ns#", _asn1obj2py(name, 0), valuebuf, buflen); - OPENSSL_free(valuebuf); - return attr; + + if (ASN1_STRING_type(value) == V_ASN1_BIT_STRING) { + buflen = ASN1_STRING_length(value); + pyattr = Py_BuildValue("Ny#", pyname, ASN1_STRING_get0_data(value), buflen); + } else { + unsigned char *valuebuf = NULL; + buflen = ASN1_STRING_to_UTF8(&valuebuf, value); + if (buflen < 0) { + _setSSLError(state, NULL, 0, __FILE__, __LINE__); + Py_DECREF(pyname); + return NULL; + } + pyattr = Py_BuildValue("Ns#", pyname, valuebuf, buflen); + OPENSSL_free(valuebuf); + } + return pyattr; } static PyObject * -_create_tuple_for_X509_NAME (X509_NAME *xname) +_create_tuple_for_X509_NAME (_sslmodulestate *state, X509_NAME *xname) { PyObject *dn = NULL; /* tuple which represents the "distinguished name" */ PyObject *rdn = NULL; /* tuple to hold a "relative distinguished name" */ @@ -1254,7 +1135,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname) /* now add this attribute to the current RDN */ name = X509_NAME_ENTRY_get_object(entry); value = X509_NAME_ENTRY_get_data(entry); - attr = _create_tuple_for_attribute(name, value); + attr = _create_tuple_for_attribute(state, name, value); /* fprintf(stderr, "RDN level %d, attribute %s: %s\n", entry->set, @@ -1301,7 +1182,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname) } static PyObject * -_get_peer_alt_names (X509 *certificate) { +_get_peer_alt_names (_sslmodulestate *state, X509 *certificate) { /* this code follows the procedure outlined in OpenSSL's crypto/x509v3/v3_prn.c:X509v3_EXT_print() @@ -1325,7 +1206,7 @@ _get_peer_alt_names (X509 *certificate) { /* get a memory buffer */ biobuf = BIO_new(BIO_s_mem()); if (biobuf == NULL) { - PyErr_SetString(PySSLErrorObject, "failed to allocate BIO"); + PyErr_SetString(state->PySSLErrorObject, "failed to allocate BIO"); return NULL; } @@ -1362,7 +1243,7 @@ _get_peer_alt_names (X509 *certificate) { } PyTuple_SET_ITEM(t, 0, v); - v = _create_tuple_for_X509_NAME (name->d.dirn); + v = _create_tuple_for_X509_NAME(state, name->d.dirn); if (v == NULL) { Py_DECREF(t); goto fail; @@ -1421,7 +1302,7 @@ _get_peer_alt_names (X509 *certificate) { len = i2t_ASN1_OBJECT(buf, sizeof(buf)-1, name->d.rid); if (len < 0) { Py_DECREF(t); - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); goto fail; } else if (len >= (int)sizeof(buf)) { v = PyUnicode_FromString(""); @@ -1504,7 +1385,7 @@ _get_peer_alt_names (X509 *certificate) { GENERAL_NAME_print(biobuf, name); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); goto fail; } vptr = strchr(buf, ':'); @@ -1680,7 +1561,7 @@ _get_crl_dp(X509 *certificate) { } static PyObject * -_decode_certificate(X509 *certificate) { +_decode_certificate(_sslmodulestate *state, X509 *certificate) { PyObject *retval = NULL; BIO *biobuf = NULL; @@ -1701,6 +1582,7 @@ _decode_certificate(X509 *certificate) { return NULL; peer = _create_tuple_for_X509_NAME( + state, X509_get_subject_name(certificate)); if (peer == NULL) goto fail0; @@ -1711,6 +1593,7 @@ _decode_certificate(X509 *certificate) { Py_DECREF(peer); issuer = _create_tuple_for_X509_NAME( + state, X509_get_issuer_name(certificate)); if (issuer == NULL) goto fail0; @@ -1732,7 +1615,7 @@ _decode_certificate(X509 *certificate) { /* get a memory buffer */ biobuf = BIO_new(BIO_s_mem()); if (biobuf == NULL) { - PyErr_SetString(PySSLErrorObject, "failed to allocate BIO"); + PyErr_SetString(state->PySSLErrorObject, "failed to allocate BIO"); goto fail0; } @@ -1742,7 +1625,7 @@ _decode_certificate(X509 *certificate) { i2a_ASN1_INTEGER(biobuf, serialNumber); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); goto fail1; } sn_obj = PyUnicode_FromStringAndSize(buf, len); @@ -1759,7 +1642,7 @@ _decode_certificate(X509 *certificate) { ASN1_TIME_print(biobuf, notBefore); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); goto fail1; } pnotBefore = PyUnicode_FromStringAndSize(buf, len); @@ -1776,7 +1659,7 @@ _decode_certificate(X509 *certificate) { ASN1_TIME_print(biobuf, notAfter); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); goto fail1; } pnotAfter = PyUnicode_FromStringAndSize(buf, len); @@ -1790,7 +1673,7 @@ _decode_certificate(X509 *certificate) { /* Now look for subjectAltName */ - peer_alt_names = _get_peer_alt_names(certificate); + peer_alt_names = _get_peer_alt_names(state, certificate); if (peer_alt_names == NULL) goto fail1; else if (peer_alt_names != Py_None) { @@ -1849,7 +1732,7 @@ _decode_certificate(X509 *certificate) { } static PyObject * -_certificate_to_der(X509 *certificate) +_certificate_to_der(_sslmodulestate *state, X509 *certificate) { unsigned char *bytes_buf = NULL; int len; @@ -1858,7 +1741,7 @@ _certificate_to_der(X509 *certificate) bytes_buf = NULL; len = i2d_X509(certificate, &bytes_buf); if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); return NULL; } /* this is actually an immutable bytes sequence */ @@ -1867,6 +1750,9 @@ _certificate_to_der(X509 *certificate) return retval; } +#include "_ssl/misc.c" +#include "_ssl/cert.c" + /*[clinic input] _ssl._test_decode_cert path: object(converter="PyUnicode_FSConverter") @@ -1881,27 +1767,28 @@ _ssl__test_decode_cert_impl(PyObject *module, PyObject *path) PyObject *retval = NULL; X509 *x=NULL; BIO *cert; + _sslmodulestate *state = get_ssl_state(module); if ((cert=BIO_new(BIO_s_file())) == NULL) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(state->PySSLErrorObject, "Can't malloc memory to read file"); goto fail0; } if (BIO_read_filename(cert, PyBytes_AsString(path)) <= 0) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(state->PySSLErrorObject, "Can't open file"); goto fail0; } x = PEM_read_bio_X509(cert, NULL, NULL, NULL); if (x == NULL) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(state->PySSLErrorObject, "Error decoding PEM-encoded file"); goto fail0; } - retval = _decode_certificate(x); + retval = _decode_certificate(state, x); X509_free(x); fail0: @@ -1946,18 +1833,82 @@ _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) if (binary_mode) { /* return cert in DER-encoded format */ - result = _certificate_to_der(peer_cert); + result = _certificate_to_der(get_state_sock(self), peer_cert); } else { verification = SSL_CTX_get_verify_mode(SSL_get_SSL_CTX(self->ssl)); if ((verification & SSL_VERIFY_PEER) == 0) result = PyDict_New(); else - result = _decode_certificate(peer_cert); + result = _decode_certificate(get_state_sock(self), peer_cert); } X509_free(peer_cert); return result; } +/*[clinic input] +_ssl._SSLSocket.get_verified_chain + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self) +/*[clinic end generated code: output=802421163cdc3110 input=5fb0714f77e2bd51]*/ +{ + /* borrowed reference */ + STACK_OF(X509) *chain = SSL_get0_verified_chain(self->ssl); + if (chain == NULL) { + Py_RETURN_NONE; + } + return _PySSL_CertificateFromX509Stack(self->ctx->state, chain, 1); +} + +/*[clinic input] +_ssl._SSLSocket.get_unverified_chain + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) +/*[clinic end generated code: output=5acdae414e13f913 input=78c33c360c635cb5]*/ +{ + PyObject *retval; + /* borrowed reference */ + /* TODO: include SSL_get_peer_certificate() for server-side sockets */ + STACK_OF(X509) *chain = SSL_get_peer_cert_chain(self->ssl); + if (chain == NULL) { + Py_RETURN_NONE; + } + retval = _PySSL_CertificateFromX509Stack(self->ctx->state, chain, 1); + if (retval == NULL) { + return NULL; + } + /* OpenSSL does not include peer cert for server side connections */ + if (self->socket_type == PY_SSL_SERVER) { + PyObject *peerobj = NULL; + X509 *peer = SSL_get_peer_certificate(self->ssl); + + if (peer == NULL) { + peerobj = Py_None; + Py_INCREF(peerobj); + } else { + /* consume X509 reference on success */ + peerobj = _PySSL_CertificateFromX509(self->ctx->state, peer, 0); + if (peerobj == NULL) { + X509_free(peer); + Py_DECREF(retval); + return NULL; + } + } + int res = PyList_Insert(retval, 0, peerobj); + Py_DECREF(peerobj); + if (res < 0) { + Py_DECREF(retval); + return NULL; + } + } + return retval; +} + static PyObject * cipher_to_tuple(const SSL_CIPHER *cipher) { @@ -2000,7 +1951,6 @@ cipher_to_tuple(const SSL_CIPHER *cipher) return NULL; } -#if OPENSSL_VERSION_NUMBER >= 0x10002000UL static PyObject * cipher_to_dict(const SSL_CIPHER *cipher) { @@ -2009,10 +1959,8 @@ cipher_to_dict(const SSL_CIPHER *cipher) unsigned long cipher_id; int alg_bits, strength_bits, len; char buf[512] = {0}; -#if OPENSSL_VERSION_1_1 int aead, nid; const char *skcipher = NULL, *digest = NULL, *kx = NULL, *auth = NULL; -#endif /* can be NULL */ cipher_name = SSL_CIPHER_get_name(cipher); @@ -2025,7 +1973,6 @@ cipher_to_dict(const SSL_CIPHER *cipher) buf[len-1] = '\0'; strength_bits = SSL_CIPHER_get_bits(cipher, &alg_bits); -#if OPENSSL_VERSION_1_1 aead = SSL_CIPHER_is_aead(cipher); nid = SSL_CIPHER_get_cipher_nid(cipher); skcipher = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; @@ -2035,13 +1982,10 @@ cipher_to_dict(const SSL_CIPHER *cipher) kx = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; nid = SSL_CIPHER_get_auth_nid(cipher); auth = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; -#endif return Py_BuildValue( "{sksssssssisi" -#if OPENSSL_VERSION_1_1 "sOssssssss" -#endif "}", "id", cipher_id, "name", cipher_name, @@ -2049,16 +1993,13 @@ cipher_to_dict(const SSL_CIPHER *cipher) "description", buf, "strength_bits", strength_bits, "alg_bits", alg_bits -#if OPENSSL_VERSION_1_1 ,"aead", aead ? Py_True : Py_False, "symmetric", skcipher, "digest", digest, "kea", kx, "auth", auth -#endif ); } -#endif /*[clinic input] _ssl._SSLSocket.shared_ciphers @@ -2129,28 +2070,6 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self) return PyUnicode_FromString(version); } -#if HAVE_NPN -/*[clinic input] -_ssl._SSLSocket.selected_npn_protocol -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self) -/*[clinic end generated code: output=b91d494cd207ecf6 input=c28fde139204b826]*/ -{ - const unsigned char *out; - unsigned int outlen; - - SSL_get0_next_proto_negotiated(self->ssl, - &out, &outlen); - - if (out == NULL) - Py_RETURN_NONE; - return PyUnicode_FromStringAndSize((char *)out, outlen); -} -#endif - -#if HAVE_ALPN /*[clinic input] _ssl._SSLSocket.selected_alpn_protocol [clinic start generated code]*/ @@ -2168,7 +2087,6 @@ _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self) Py_RETURN_NONE; return PyUnicode_FromStringAndSize((char *)out, outlen); } -#endif /*[clinic input] _ssl._SSLSocket.compression @@ -2204,12 +2122,7 @@ static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) { static int PySSL_set_context(PySSLSocket *self, PyObject *value, void *closure) { - if (PyObject_TypeCheck(value, &PySSLContext_Type)) { -#if !HAVE_SNI - PyErr_SetString(PyExc_NotImplementedError, "setting a socket's " - "context is not supported by your OpenSSL library"); - return -1; -#else + if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) { Py_INCREF(value); Py_SETREF(self->ctx, (PySSLContext *)value); SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); @@ -2218,7 +2131,6 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value, self->ssl, self->ctx->msg_cb ? _PySSL_msg_callback : NULL ); -#endif } else { PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext"); return -1; @@ -2289,6 +2201,7 @@ 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(Py_TYPE(self)); return 0; } @@ -2304,13 +2217,17 @@ PySSL_clear(PySSLSocket *self) static void PySSL_dealloc(PySSLSocket *self) { - if (self->ssl) + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + if (self->ssl) { SSL_free(self->ssl); + } Py_XDECREF(self->Socket); Py_XDECREF(self->ctx); Py_XDECREF(self->server_hostname); Py_XDECREF(self->owner); - PyObject_Del(self); + PyObject_GC_Del(self); + Py_DECREF(tp); } /* If the socket has a timeout, do a select()/poll() on the socket. @@ -2397,7 +2314,8 @@ static PyObject * _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) /*[clinic end generated code: output=aa7a6be5527358d8 input=77262d994fe5100a]*/ { - int len; + size_t count = 0; + int retval; int sockstate; _PySSLError err; int nonblocking; @@ -2407,19 +2325,14 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) if (sock != NULL) { if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", + _setSSLError(get_state_sock(self), + "Underlying socket connection gone", PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); return NULL; } Py_INCREF(sock); } - if (b->len > INT_MAX) { - PyErr_Format(PyExc_OverflowError, - "string longer than %d bytes", INT_MAX); - goto error; - } - if (sock != NULL) { /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); @@ -2434,23 +2347,23 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) sockstate = PySSL_select(sock, 1, timeout); if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, + PyErr_SetString(PyExc_TimeoutError, "The write operation timed out"); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_sock(self)->PySSLErrorObject, "Underlying socket has been closed."); goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_sock(self)->PySSLErrorObject, "Underlying socket too large for select()."); goto error; } do { PySSL_BEGIN_ALLOW_THREADS - len = SSL_write(self->ssl, b->buf, (int)b->len); - err = _PySSL_errno(len <= 0, self->ssl, len); + retval = SSL_write_ex(self->ssl, b->buf, (size_t)b->len, &count); + err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS self->err = err; @@ -2469,11 +2382,11 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) } if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, + PyErr_SetString(PyExc_TimeoutError, "The write operation timed out"); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_sock(self)->PySSLErrorObject, "Underlying socket has been closed."); goto error; } else if (sockstate == SOCKET_IS_NONBLOCKING) { @@ -2483,11 +2396,11 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) err.ssl == SSL_ERROR_WANT_WRITE); Py_XDECREF(sock); - if (len <= 0) - return PySSL_SetError(self, len, __FILE__, __LINE__); + if (retval == 0) + return PySSL_SetError(self, retval, __FILE__, __LINE__); if (PySSL_ChainExceptions(self) < 0) return NULL; - return PyLong_FromLong(len); + return PyLong_FromSize_t(count); error: Py_XDECREF(sock); PySSL_ChainExceptions(self); @@ -2521,7 +2434,7 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) /*[clinic input] _ssl._SSLSocket.read - size as len: int + size as len: Py_ssize_t [ buffer: Py_buffer(accept={rwbuffer}) ] @@ -2531,13 +2444,14 @@ Read up to size bytes from the SSL socket. [clinic start generated code]*/ static PyObject * -_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, - Py_buffer *buffer) -/*[clinic end generated code: output=00097776cec2a0af input=ff157eb918d0905b]*/ +_ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, + int group_right_1, Py_buffer *buffer) +/*[clinic end generated code: output=49b16e6406023734 input=ec48bf622be1c4a1]*/ { PyObject *dest = NULL; char *mem; - int count; + size_t count = 0; + int retval; int sockstate; _PySSLError err; int nonblocking; @@ -2552,7 +2466,8 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, if (sock != NULL) { if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", + _setSSLError(get_state_sock(self), + "Underlying socket connection gone", PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); return NULL; } @@ -2599,8 +2514,8 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, do { PySSL_BEGIN_ALLOW_THREADS - count = SSL_read(self->ssl, mem, len); - err = _PySSL_errno(count <= 0, self->ssl, count); + retval = SSL_read_ex(self->ssl, mem, (size_t)len, &count); + err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS self->err = err; @@ -2624,7 +2539,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, sockstate = SOCKET_OPERATION_OK; if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, + PyErr_SetString(PyExc_TimeoutError, "The read operation timed out"); goto error; } else if (sockstate == SOCKET_IS_NONBLOCKING) { @@ -2633,8 +2548,8 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, } while (err.ssl == SSL_ERROR_WANT_READ || err.ssl == SSL_ERROR_WANT_WRITE); - if (count <= 0) { - PySSL_SetError(self, count, __FILE__, __LINE__); + if (retval == 0) { + PySSL_SetError(self, retval, __FILE__, __LINE__); goto error; } if (self->exc_type != NULL) @@ -2647,7 +2562,7 @@ done: return dest; } else { - return PyLong_FromLong(count); + return PyLong_FromSize_t(count); } error: @@ -2678,7 +2593,8 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) if (sock != NULL) { /* Guard against closed socket */ if ((((PyObject*)sock) == Py_None) || (sock->sock_fd == INVALID_SOCKET)) { - _setSSLError("Underlying socket connection gone", + _setSSLError(get_state_sock(self), + "Underlying socket connection gone", PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); return NULL; } @@ -2739,15 +2655,15 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) if (sockstate == SOCKET_HAS_TIMED_OUT) { if (err.ssl == SSL_ERROR_WANT_READ) - PyErr_SetString(PySocketModule.timeout_error, + PyErr_SetString(PyExc_TimeoutError, "The read operation timed out"); else - PyErr_SetString(PySocketModule.timeout_error, + PyErr_SetString(PyExc_TimeoutError, "The write operation timed out"); goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_sock(self)->PySSLErrorObject, "Underlying socket too large for select()."); goto error; } @@ -2832,7 +2748,7 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) #ifdef TLS1_3_VERSION int err = SSL_verify_client_post_handshake(self->ssl); if (err == 0) - return _setSSLError(NULL, 0, __FILE__, __LINE__); + return _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); else Py_RETURN_NONE; #else @@ -2843,8 +2759,6 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) #endif } -#ifdef OPENSSL_VERSION_1_1 - static SSL_SESSION* _ssl_session_dup(SSL_SESSION *session) { SSL_SESSION *newsession = NULL; @@ -2885,7 +2799,6 @@ _ssl_session_dup(SSL_SESSION *session) { } return NULL; } -#endif static PyObject * PySSL_get_session(PySSLSocket *self, void *closure) { @@ -2894,7 +2807,6 @@ PySSL_get_session(PySSLSocket *self, void *closure) { PySSLSession *pysess; SSL_SESSION *session; -#ifdef OPENSSL_VERSION_1_1 /* duplicate session as workaround for session bug in OpenSSL 1.1.0, * https://github.com/openssl/openssl/issues/1550 */ session = SSL_get0_session(self->ssl); /* borrowed reference */ @@ -2904,13 +2816,11 @@ PySSL_get_session(PySSLSocket *self, void *closure) { if ((session = _ssl_session_dup(session)) == NULL) { return NULL; } -#else session = SSL_get1_session(self->ssl); if (session == NULL) { Py_RETURN_NONE; } -#endif - pysess = PyObject_GC_New(PySSLSession, &PySSLSession_Type); + pysess = PyObject_GC_New(PySSLSession, self->ctx->state->PySSLSession_Type); if (pysess == NULL) { SSL_SESSION_free(session); return NULL; @@ -2928,12 +2838,10 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, void *closure) { PySSLSession *pysess; -#ifdef OPENSSL_VERSION_1_1 SSL_SESSION *session; -#endif int result; - if (!PySSLSession_Check(value)) { + if (!Py_IS_TYPE(value, get_state_sock(self)->PySSLSession_Type)) { PyErr_SetString(PyExc_TypeError, "Value is not a SSLSession."); return -1; } @@ -2954,7 +2862,6 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, "Cannot set session after handshake."); return -1; } -#ifdef OPENSSL_VERSION_1_1 /* duplicate session */ if ((session = _ssl_session_dup(pysess->session)) == NULL) { return -1; @@ -2962,11 +2869,8 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, result = SSL_set_session(self->ssl, session); /* free duplicate, SSL_set_session() bumps ref count */ SSL_SESSION_free(session); -#else - result = SSL_set_session(self->ssl, pysess->session); -#endif if (result == 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); return -1; } return 0; @@ -3015,48 +2919,31 @@ static PyMethodDef PySSLMethods[] = { _SSL__SSLSOCKET_CIPHER_METHODDEF _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF _SSL__SSLSOCKET_VERSION_METHODDEF - _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF _SSL__SSLSOCKET_COMPRESSION_METHODDEF _SSL__SSLSOCKET_SHUTDOWN_METHODDEF _SSL__SSLSOCKET_VERIFY_CLIENT_POST_HANDSHAKE_METHODDEF + _SSL__SSLSOCKET_GET_UNVERIFIED_CHAIN_METHODDEF + _SSL__SSLSOCKET_GET_VERIFIED_CHAIN_METHODDEF {NULL, NULL} }; -static PyTypeObject PySSLSocket_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl._SSLSocket", /*tp_name*/ - sizeof(PySSLSocket), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySSL_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, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc) PySSL_traverse, /*tp_traverse*/ - (inquiry) PySSL_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - PySSLMethods, /*tp_methods*/ - 0, /*tp_members*/ - ssl_getsetlist, /*tp_getset*/ +static PyType_Slot PySSLSocket_slots[] = { + {Py_tp_methods, PySSLMethods}, + {Py_tp_getset, ssl_getsetlist}, + {Py_tp_dealloc, PySSL_dealloc}, + {Py_tp_traverse, PySSL_traverse}, + {Py_tp_clear, PySSL_clear}, + {0, 0}, }; +static PyType_Spec PySSLSocket_spec = { + .name = "_ssl._SSLSocket", + .basicsize = sizeof(PySSLSocket), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_HAVE_GC), + .slots = PySSLSocket_slots, +}; /* * _SSLContext objects @@ -3106,63 +2993,78 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) { PySSLContext *self; long options; + const SSL_METHOD *method = NULL; SSL_CTX *ctx = NULL; X509_VERIFY_PARAM *params; int result; -#if defined(SSL_MODE_RELEASE_BUFFERS) - unsigned long libver; -#endif - PySSL_BEGIN_ALLOW_THREADS + /* slower approach, walk MRO and get borrowed reference to module. + * _PyType_GetModuleByDef is required for SSLContext subclasses */ + PyObject *module = _PyType_GetModuleByDef(type, &_sslmodule_def); + if (module == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "Cannot find internal module state"); + return NULL; + } + switch(proto_version) { #if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) case PY_SSL_VERSION_SSL3: - ctx = SSL_CTX_new(SSLv3_method()); + PY_SSL_DEPRECATED("ssl.PROTOCOL_SSLv3 is deprecated", 2, NULL); + method = SSLv3_method(); break; #endif #if (defined(TLS1_VERSION) && \ !defined(OPENSSL_NO_TLS1) && \ !defined(OPENSSL_NO_TLS1_METHOD)) case PY_SSL_VERSION_TLS1: - ctx = SSL_CTX_new(TLSv1_method()); + PY_SSL_DEPRECATED("ssl.PROTOCOL_TLSv1 is deprecated", 2, NULL); + method = TLSv1_method(); break; #endif #if (defined(TLS1_1_VERSION) && \ !defined(OPENSSL_NO_TLS1_1) && \ !defined(OPENSSL_NO_TLS1_1_METHOD)) case PY_SSL_VERSION_TLS1_1: - ctx = SSL_CTX_new(TLSv1_1_method()); + PY_SSL_DEPRECATED("ssl.PROTOCOL_TLSv1_1 is deprecated", 2, NULL); + method = TLSv1_1_method(); break; #endif #if (defined(TLS1_2_VERSION) && \ !defined(OPENSSL_NO_TLS1_2) && \ !defined(OPENSSL_NO_TLS1_2_METHOD)) case PY_SSL_VERSION_TLS1_2: - ctx = SSL_CTX_new(TLSv1_2_method()); + PY_SSL_DEPRECATED("ssl.PROTOCOL_TLSv1_2 is deprecated", 2, NULL); + method = TLSv1_2_method(); break; #endif case PY_SSL_VERSION_TLS: - /* SSLv23 */ - ctx = SSL_CTX_new(TLS_method()); + PY_SSL_DEPRECATED("ssl.PROTOCOL_TLS is deprecated", 2, NULL); + method = TLS_method(); break; case PY_SSL_VERSION_TLS_CLIENT: - ctx = SSL_CTX_new(TLS_client_method()); + method = TLS_client_method(); break; case PY_SSL_VERSION_TLS_SERVER: - ctx = SSL_CTX_new(TLS_server_method()); + method = TLS_server_method(); break; default: - proto_version = -1; + method = NULL; } - PySSL_END_ALLOW_THREADS - if (proto_version == -1) { - PyErr_SetString(PyExc_ValueError, - "invalid or unsupported protocol version"); + if (method == NULL) { + PyErr_Format(PyExc_ValueError, + "invalid or unsupported protocol version %i", + proto_version); return NULL; } + + PySSL_BEGIN_ALLOW_THREADS + ctx = SSL_CTX_new(method); + PySSL_END_ALLOW_THREADS + if (ctx == NULL) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_ssl_state(module), NULL, 0, __FILE__, __LINE__); return NULL; } @@ -3176,19 +3078,12 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) self->hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; self->protocol = proto_version; self->msg_cb = NULL; -#ifdef HAVE_OPENSSL_KEYLOG self->keylog_filename = NULL; self->keylog_bio = NULL; -#endif -#if HAVE_NPN - self->npn_protocols = NULL; -#endif -#if HAVE_ALPN self->alpn_protocols = NULL; -#endif -#ifndef OPENSSL_NO_TLSEXT self->set_sni_cb = NULL; -#endif + self->state = get_ssl_state(module); + /* Don't check host name by default */ if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { self->check_hostname = 1; @@ -3245,42 +3140,31 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) if (result == 0) { Py_DECREF(self); ERR_clear_error(); - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_ctx(self)->PySSLErrorObject, "No cipher can be selected."); - return NULL; + goto error; } - -#if defined(SSL_MODE_RELEASE_BUFFERS) - /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory - usage for no cost at all. However, don't do this for OpenSSL versions - between 1.0.1 and 1.0.1h or 1.0.0 and 1.0.0m, which are affected by CVE - 2014-0198. I can't find exactly which beta fixed this CVE, so be - conservative and assume it wasn't fixed until release. We do this check - at runtime to avoid problems from the dynamic linker. - See #25672 for more on this. */ - libver = OpenSSL_version_num(); - if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && - !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { - SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); +#ifdef PY_SSL_MIN_PROTOCOL + switch(proto_version) { + case PY_SSL_VERSION_TLS: + case PY_SSL_VERSION_TLS_CLIENT: + case PY_SSL_VERSION_TLS_SERVER: + result = SSL_CTX_set_min_proto_version(ctx, PY_SSL_MIN_PROTOCOL); + if (result == 0) { + PyErr_Format(PyExc_ValueError, + "Failed to set minimum protocol 0x%x", + PY_SSL_MIN_PROTOCOL); + goto error; + } + break; + default: + break; } #endif - -#if !defined(OPENSSL_NO_ECDH) && !defined(OPENSSL_VERSION_1_1) - /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use - prime256v1 by default. This is Apache mod_ssl's initialization - policy, so we should be safe. OpenSSL 1.1 has it enabled by default. - */ -#if defined(SSL_CTX_set_ecdh_auto) - SSL_CTX_set_ecdh_auto(self->ctx, 1); -#else - { - EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - SSL_CTX_set_tmp_ecdh(self->ctx, key); - EC_KEY_free(key); - } -#endif -#endif + /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory + usage for no cost at all. */ + SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); #define SID_CTX "Python" SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX, @@ -3288,11 +3172,9 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) #undef SID_CTX params = SSL_CTX_get0_param(self->ctx); -#ifdef X509_V_FLAG_TRUSTED_FIRST /* Improve trust chain building when cross-signed intermediate certificates are present. See https://bugs.python.org/issue23476. */ X509_VERIFY_PARAM_set_flags(params, X509_V_FLAG_TRUSTED_FIRST); -#endif X509_VERIFY_PARAM_set_hostflags(params, self->hostflags); #ifdef TLS1_3_VERSION @@ -3301,26 +3183,26 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) #endif return (PyObject *)self; + error: + Py_XDECREF(self); + ERR_clear_error(); + return NULL; } static int context_traverse(PySSLContext *self, visitproc visit, void *arg) { -#ifndef OPENSSL_NO_TLSEXT Py_VISIT(self->set_sni_cb); -#endif Py_VISIT(self->msg_cb); + Py_VISIT(Py_TYPE(self)); return 0; } static int context_clear(PySSLContext *self) { -#ifndef OPENSSL_NO_TLSEXT Py_CLEAR(self->set_sni_cb); -#endif Py_CLEAR(self->msg_cb); -#ifdef HAVE_OPENSSL_KEYLOG Py_CLEAR(self->keylog_filename); if (self->keylog_bio != NULL) { PySSL_BEGIN_ALLOW_THREADS @@ -3328,24 +3210,20 @@ context_clear(PySSLContext *self) PySSL_END_ALLOW_THREADS self->keylog_bio = NULL; } -#endif return 0; } static void context_dealloc(PySSLContext *self) { + PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); context_clear(self); SSL_CTX_free(self->ctx); -#if HAVE_NPN - PyMem_FREE(self->npn_protocols); -#endif -#if HAVE_ALPN PyMem_FREE(self->alpn_protocols); -#endif Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); } /*[clinic input] @@ -3364,14 +3242,13 @@ _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) otherwise the error will be reported again when another SSL call is done. */ ERR_clear_error(); - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_ctx(self)->PySSLErrorObject, "No cipher can be selected."); return NULL; } Py_RETURN_NONE; } -#if OPENSSL_VERSION_NUMBER >= 0x10002000UL /*[clinic input] _ssl._SSLContext.get_ciphers [clinic start generated code]*/ @@ -3388,7 +3265,7 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self) ssl = SSL_new(self->ctx); if (ssl == NULL) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); goto exit; } sk = SSL_get_ciphers(ssl); @@ -3414,10 +3291,8 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self) return result; } -#endif -#if HAVE_NPN || HAVE_ALPN static int do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, const unsigned char *server_protocols, unsigned int server_protocols_len, @@ -3441,92 +3316,21 @@ do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, return SSL_TLSEXT_ERR_OK; } -#endif - -#if HAVE_NPN -/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */ -static int -_advertiseNPN_cb(SSL *s, - const unsigned char **data, unsigned int *len, - void *args) -{ - PySSLContext *ssl_ctx = (PySSLContext *) args; - - if (ssl_ctx->npn_protocols == NULL) { - *data = (unsigned char *)""; - *len = 0; - } else { - *data = ssl_ctx->npn_protocols; - *len = ssl_ctx->npn_protocols_len; - } - return SSL_TLSEXT_ERR_OK; -} -/* this callback gets passed to SSL_CTX_set_next_proto_select_cb */ static int -_selectNPN_cb(SSL *s, - unsigned char **out, unsigned char *outlen, - const unsigned char *server, unsigned int server_len, +_selectALPN_cb(SSL *s, + const unsigned char **out, unsigned char *outlen, + const unsigned char *client_protocols, unsigned int client_protocols_len, void *args) { PySSLContext *ctx = (PySSLContext *)args; - return do_protocol_selection(0, out, outlen, server, server_len, - ctx->npn_protocols, ctx->npn_protocols_len); + return do_protocol_selection(1, (unsigned char **)out, outlen, + ctx->alpn_protocols, ctx->alpn_protocols_len, + client_protocols, client_protocols_len); } -#endif /*[clinic input] -_ssl._SSLContext._set_npn_protocols - protos: Py_buffer - / -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, - Py_buffer *protos) -/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/ -{ -#if HAVE_NPN - PyMem_Free(self->npn_protocols); - self->npn_protocols = PyMem_Malloc(protos->len); - if (self->npn_protocols == NULL) - return PyErr_NoMemory(); - memcpy(self->npn_protocols, protos->buf, protos->len); - self->npn_protocols_len = (int) protos->len; - - /* set both server and client callbacks, because the context can - * be used to create both types of sockets */ - SSL_CTX_set_next_protos_advertised_cb(self->ctx, - _advertiseNPN_cb, - self); - SSL_CTX_set_next_proto_select_cb(self->ctx, - _selectNPN_cb, - self); - - Py_RETURN_NONE; -#else - PyErr_SetString(PyExc_NotImplementedError, - "The NPN extension requires OpenSSL 1.0.1 or later."); - return NULL; -#endif -} - -#if HAVE_ALPN -static int -_selectALPN_cb(SSL *s, - const unsigned char **out, unsigned char *outlen, - const unsigned char *client_protocols, unsigned int client_protocols_len, - void *args) -{ - PySSLContext *ctx = (PySSLContext *)args; - return do_protocol_selection(1, (unsigned char **)out, outlen, - ctx->alpn_protocols, ctx->alpn_protocols_len, - client_protocols, client_protocols_len); -} -#endif - -/*[clinic input] -_ssl._SSLContext._set_alpn_protocols +_ssl._SSLContext._set_alpn_protocols protos: Py_buffer / [clinic start generated code]*/ @@ -3536,14 +3340,13 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, Py_buffer *protos) /*[clinic end generated code: output=87599a7f76651a9b input=9bba964595d519be]*/ { -#if HAVE_ALPN if ((size_t)protos->len > UINT_MAX) { PyErr_Format(PyExc_OverflowError, "protocols longer than %u bytes", UINT_MAX); return NULL; } - PyMem_FREE(self->alpn_protocols); + PyMem_Free(self->alpn_protocols); self->alpn_protocols = PyMem_Malloc(protos->len); if (!self->alpn_protocols) return PyErr_NoMemory(); @@ -3555,11 +3358,6 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); Py_RETURN_NONE; -#else - PyErr_SetString(PyExc_NotImplementedError, - "The ALPN extension requires OpenSSL 1.0.2 or later."); - return NULL; -#endif } static PyObject * @@ -3576,7 +3374,7 @@ get_verify_mode(PySSLContext *self, void *c) case SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT: return PyLong_FromLong(PY_SSL_CERT_REQUIRED); } - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_ctx(self)->PySSLErrorObject, "invalid return value from SSL_CTX_get_verify_mode"); return NULL; } @@ -3621,13 +3419,13 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) set = ~flags & new_flags; if (clear) { if (!X509_VERIFY_PARAM_clear_flags(param, clear)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return -1; } } if (set) { if (!X509_VERIFY_PARAM_set_flags(param, set)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return -1; } } @@ -3635,9 +3433,6 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) } /* Getter and setter for protocol version */ -#if defined(SSL_CTRL_GET_MAX_PROTO_VERSION) - - static int set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) { @@ -3665,6 +3460,29 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) return -1; } + /* check for deprecations and supported values */ + switch(v) { + case PY_PROTO_SSLv3: + PY_SSL_DEPRECATED("ssl.TLSVersion.SSLv3 is deprecated", 2, -1); + break; + case PY_PROTO_TLSv1: + PY_SSL_DEPRECATED("ssl.TLSVersion.TLSv1 is deprecated", 2, -1); + break; + case PY_PROTO_TLSv1_1: + PY_SSL_DEPRECATED("ssl.TLSVersion.TLSv1_1 is deprecated", 2, -1); + break; + case PY_PROTO_MINIMUM_SUPPORTED: + case PY_PROTO_MAXIMUM_SUPPORTED: + case PY_PROTO_TLSv1_2: + case PY_PROTO_TLSv1_3: + /* ok */ + break; + default: + PyErr_Format(PyExc_ValueError, + "Unsupported TLS/SSL version 0x%x", v); + return -1; + } + if (what == 0) { switch(v) { case PY_PROTO_MINIMUM_SUPPORTED: @@ -3732,9 +3550,8 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c) { return set_min_max_proto_version(self, arg, 1); } -#endif /* SSL_CTRL_GET_MAX_PROTO_VERSION */ -#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +#ifdef TLS1_3_VERSION static PyObject * get_num_tickets(PySSLContext *self, void *c) { @@ -3765,7 +3582,14 @@ set_num_tickets(PySSLContext *self, PyObject *arg, void *c) PyDoc_STRVAR(PySSLContext_num_tickets_doc, "Control the number of TLSv1.3 session tickets"); -#endif /* OpenSSL 1.1.1 */ +#endif /* TLS1_3_VERSION */ + +static PyObject * +get_security_level(PySSLContext *self, void *c) +{ + return PyLong_FromLong(SSL_CTX_get_security_level(self->ctx)); +} +PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); static PyObject * get_options(PySSLContext *self, void *c) @@ -3777,19 +3601,25 @@ static int set_options(PySSLContext *self, PyObject *arg, void *c) { long new_opts, opts, set, clear; + long 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)) return -1; opts = SSL_CTX_get_options(self->ctx); clear = opts & ~new_opts; set = ~opts & new_opts; + + if ((set & opt_no) != 0) { + if (_ssl_deprecated("ssl.OP_NO_SSL*/ssl.OP_NO_TLS* options are " + "deprecated", 2) < 0) { + return -1; + } + } if (clear) { -#ifdef HAVE_SSL_CTX_CLEAR_OPTIONS SSL_CTX_clear_options(self->ctx, clear); -#else - PyErr_SetString(PyExc_ValueError, - "can't clear options before OpenSSL 0.9.8m"); - return -1; -#endif } if (set) SSL_CTX_set_options(self->ctx, set); @@ -4045,7 +3875,7 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, PyErr_SetFromErrno(PyExc_OSError); } else { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); } goto error; } @@ -4066,7 +3896,7 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, PyErr_SetFromErrno(PyExc_OSError); } else { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); } goto error; } @@ -4074,7 +3904,7 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, r = SSL_CTX_check_private_key(self->ctx); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); if (r != 1) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); goto error; } SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); @@ -4115,7 +3945,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, biobuf = BIO_new_mem_buf(data, (int)len); if (biobuf == NULL) { - _setSSLError("Can't allocate buffer", 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), "Can't allocate buffer", 0, __FILE__, __LINE__); return -1; } @@ -4160,7 +3990,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, } else { msg = "not enough data: cadata does not contain a certificate"; } - _setSSLError(msg, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), msg, 0, __FILE__, __LINE__); retval = -1; } else if ((filetype == SSL_FILETYPE_ASN1) && (ERR_GET_LIB(err) == ERR_LIB_ASN1) && @@ -4175,7 +4005,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, ERR_clear_error(); retval = 0; } else if (err != 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); retval = -1; } else { retval = 0; @@ -4294,7 +4124,7 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, PyErr_SetFromErrno(PyExc_OSError); } else { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); } goto error; } @@ -4342,13 +4172,13 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, filepath); } else { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); } return NULL; } if (!SSL_CTX_set_tmp_dh(self->ctx, dh)) { DH_free(dh); - return _setSSLError(NULL, 0, __FILE__, __LINE__); + return _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); } DH_free(dh); Py_RETURN_NONE; @@ -4356,7 +4186,7 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) /*[clinic input] _ssl._SSLContext._wrap_socket - sock: object(subclass_of="PySocketModule.Sock_Type") + sock: object(subclass_of="get_state_ctx(self)->Sock_Type") server_side: int server_hostname as hostname_obj: object = None * @@ -4369,7 +4199,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=957d5006183d1894]*/ +/*[clinic end generated code: output=f103f238633940b4 input=f5916eadbc6eae81]*/ { char *hostname = NULL; PyObject *res; @@ -4392,8 +4222,8 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, /*[clinic input] _ssl._SSLContext._wrap_bio - incoming: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") - outgoing: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") + 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_hostname as hostname_obj: object = None * @@ -4407,7 +4237,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=8cf22f4d586ac56a]*/ +/*[clinic end generated code: output=5c5d6d9b41f99332 input=331edeec9c738382]*/ { char *hostname = NULL; PyObject *res; @@ -4480,13 +4310,12 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) /*[clinic end generated code: output=0bee74e6e09deaaa input=35f3408021463d74]*/ { if (!SSL_CTX_set_default_verify_paths(self->ctx)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } Py_RETURN_NONE; } -#ifndef OPENSSL_NO_ECDH /*[clinic input] _ssl._SSLContext.set_ecdh_curve name: object @@ -4514,21 +4343,19 @@ _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) } key = EC_KEY_new_by_curve_name(nid); if (key == NULL) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } SSL_CTX_set_tmp_ecdh(self->ctx, key); EC_KEY_free(key); Py_RETURN_NONE; } -#endif -#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) static int _servername_callback(SSL *s, int *al, void *args) { int ret; - PySSLContext *ssl_ctx = (PySSLContext *) args; + PySSLContext *sslctx = (PySSLContext *) args; PySSLSocket *ssl; PyObject *result; /* The high-level ssl.SSLSocket object */ @@ -4536,7 +4363,7 @@ _servername_callback(SSL *s, int *al, void *args) const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); PyGILState_STATE gstate = PyGILState_Ensure(); - if (ssl_ctx->set_sni_cb == NULL) { + if (sslctx->set_sni_cb == NULL) { /* remove race condition in this the call back while if removing the * callback is in progress */ PyGILState_Release(gstate); @@ -4544,7 +4371,7 @@ _servername_callback(SSL *s, int *al, void *args) } ssl = SSL_get_app_data(s); - assert(PySSLSocket_Check(ssl)); + assert(Py_IS_TYPE(ssl, get_state_ctx(sslctx)->PySSLSocket_Type)); /* The servername callback expects an argument that represents the current * SSL connection and that has a .context attribute that can be changed to @@ -4566,8 +4393,8 @@ _servername_callback(SSL *s, int *al, void *args) goto error; if (servername == NULL) { - result = PyObject_CallFunctionObjArgs(ssl_ctx->set_sni_cb, ssl_socket, - Py_None, ssl_ctx, NULL); + result = PyObject_CallFunctionObjArgs(sslctx->set_sni_cb, ssl_socket, + Py_None, sslctx, NULL); } else { PyObject *servername_bytes; @@ -4575,7 +4402,7 @@ _servername_callback(SSL *s, int *al, void *args) servername_bytes = PyBytes_FromString(servername); if (servername_bytes == NULL) { - PyErr_WriteUnraisable((PyObject *) ssl_ctx); + PyErr_WriteUnraisable((PyObject *) sslctx); goto error; } /* server_hostname was encoded to an A-label by our caller; put it @@ -4589,14 +4416,14 @@ _servername_callback(SSL *s, int *al, void *args) } Py_DECREF(servername_bytes); result = PyObject_CallFunctionObjArgs( - ssl_ctx->set_sni_cb, ssl_socket, servername_str, - ssl_ctx, NULL); + sslctx->set_sni_cb, ssl_socket, servername_str, + sslctx, NULL); Py_DECREF(servername_str); } Py_DECREF(ssl_socket); if (result == NULL) { - PyErr_WriteUnraisable(ssl_ctx->set_sni_cb); + PyErr_WriteUnraisable(sslctx->set_sni_cb); *al = SSL_AD_HANDSHAKE_FAILURE; ret = SSL_TLSEXT_ERR_ALERT_FATAL; } @@ -4627,7 +4454,6 @@ error: PyGILState_Release(gstate); return ret; } -#endif static PyObject * get_sni_callback(PySSLContext *self, void *c) @@ -4648,7 +4474,6 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) "sni_callback cannot be set on TLS_CLIENT context"); return -1; } -#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) Py_CLEAR(self->set_sni_cb); if (arg == Py_None) { SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); @@ -4666,13 +4491,6 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) SSL_CTX_set_tlsext_servername_arg(self->ctx, self); } return 0; -#else - PyErr_SetString(PyExc_NotImplementedError, - "The TLS extension servername callback, " - "SSL_CTX_set_tlsext_servername_callback, " - "is not in the current OpenSSL library."); - return -1; -#endif } PyDoc_STRVAR(PySSLContext_sni_callback_doc, @@ -4771,9 +4589,9 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) continue; } if (binary_form) { - ci = _certificate_to_der(cert); + ci = _certificate_to_der(get_state_ctx(self), cert); } else { - ci = _decode_certificate(cert); + ci = _decode_certificate(get_state_ctx(self), cert); } if (ci == NULL) { goto error; @@ -4797,21 +4615,17 @@ static PyGetSetDef context_getsetlist[] = { (setter) set_check_hostname, NULL}, {"_host_flags", (getter) get_host_flags, (setter) set_host_flags, NULL}, -#if SSL_CTRL_GET_MAX_PROTO_VERSION {"minimum_version", (getter) get_minimum_version, (setter) set_minimum_version, NULL}, {"maximum_version", (getter) get_maximum_version, (setter) set_maximum_version, NULL}, -#endif -#ifdef HAVE_OPENSSL_KEYLOG {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, (setter) _PySSLContext_set_keylog_filename, NULL}, -#endif {"_msg_callback", (getter) _PySSLContext_get_msg_callback, (setter) _PySSLContext_set_msg_callback, NULL}, {"sni_callback", (getter) get_sni_callback, (setter) set_sni_callback, PySSLContext_sni_callback_doc}, -#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +#ifdef TLS1_3_VERSION {"num_tickets", (getter) get_num_tickets, (setter) set_num_tickets, PySSLContext_num_tickets_doc}, #endif @@ -4830,6 +4644,8 @@ static PyGetSetDef context_getsetlist[] = { (setter) set_verify_flags, NULL}, {"verify_mode", (getter) get_verify_mode, (setter) set_verify_mode, NULL}, + {"security_level", (getter) get_security_level, + NULL, PySSLContext_security_level_doc}, {NULL}, /* sentinel */ }; @@ -4838,7 +4654,6 @@ static struct PyMethodDef context_methods[] = { _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF - _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF @@ -4851,45 +4666,22 @@ static struct PyMethodDef context_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject PySSLContext_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl._SSLContext", /*tp_name*/ - sizeof(PySSLContext), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)context_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) context_traverse, /*tp_traverse*/ - (inquiry) context_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - context_methods, /*tp_methods*/ - 0, /*tp_members*/ - context_getsetlist, /*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*/ - _ssl__SSLContext, /*tp_new*/ +static PyType_Slot PySSLContext_slots[] = { + {Py_tp_methods, context_methods}, + {Py_tp_getset, context_getsetlist}, + {Py_tp_new, _ssl__SSLContext}, + {Py_tp_dealloc, context_dealloc}, + {Py_tp_traverse, context_traverse}, + {Py_tp_clear, context_clear}, + {0, 0}, +}; + +static PyType_Spec PySSLContext_spec = { + .name = "_ssl._SSLContext", + .basicsize = sizeof(PySSLContext), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = PySSLContext_slots, }; @@ -4912,8 +4704,7 @@ _ssl_MemoryBIO_impl(PyTypeObject *type) bio = BIO_new(BIO_s_mem()); if (bio == NULL) { - PyErr_SetString(PySSLErrorObject, - "failed to allocate BIO"); + PyErr_SetString(PyExc_MemoryError, "failed to allocate BIO"); return NULL; } /* Since our BIO is non-blocking an empty read() does not indicate EOF, @@ -4934,11 +4725,21 @@ _ssl_MemoryBIO_impl(PyTypeObject *type) return (PyObject *) self; } +static int +memory_bio_traverse(PySSLMemoryBIO *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static void memory_bio_dealloc(PySSLMemoryBIO *self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); BIO_free(self->bio); Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); } static PyObject * @@ -4990,8 +4791,9 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) nbytes = BIO_read(self->bio, PyBytes_AS_STRING(result), len); if (nbytes < 0) { + _sslmodulestate *state = get_state_mbio(self); Py_DECREF(result); - _setSSLError(NULL, 0, __FILE__, __LINE__); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); return NULL; } @@ -5026,14 +4828,18 @@ _ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) } if (self->eof_written) { - PyErr_SetString(PySSLErrorObject, + PyObject *module = PyType_GetModule(Py_TYPE(self)); + if (module == NULL) + return NULL; + PyErr_SetString(get_ssl_state(module)->PySSLErrorObject, "cannot write() after write_eof()"); return NULL; } nbytes = BIO_write(self->bio, b->buf, (int)b->len); if (nbytes < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); + _sslmodulestate *state = get_state_mbio(self); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); return NULL; } @@ -5076,47 +4882,22 @@ static struct PyMethodDef memory_bio_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject PySSLMemoryBIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl.MemoryBIO", /*tp_name*/ - sizeof(PySSLMemoryBIO), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)memory_bio_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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - memory_bio_methods, /*tp_methods*/ - 0, /*tp_members*/ - memory_bio_getsetlist, /*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*/ - _ssl_MemoryBIO, /*tp_new*/ +static PyType_Slot PySSLMemoryBIO_slots[] = { + {Py_tp_methods, memory_bio_methods}, + {Py_tp_getset, memory_bio_getsetlist}, + {Py_tp_new, _ssl_MemoryBIO}, + {Py_tp_dealloc, memory_bio_dealloc}, + {Py_tp_traverse, memory_bio_traverse}, + {0, 0}, }; +static PyType_Spec PySSLMemoryBIO_spec = { + .name = "_ssl.MemoryBIO", + .basicsize = sizeof(PySSLMemoryBIO), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_HAVE_GC), + .slots = PySSLMemoryBIO_slots, +}; /* * SSL Session object @@ -5125,6 +4906,7 @@ static PyTypeObject PySSLMemoryBIO_Type = { static void PySSLSession_dealloc(PySSLSession *self) { + PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); Py_XDECREF(self->ctx); @@ -5132,19 +4914,21 @@ PySSLSession_dealloc(PySSLSession *self) SSL_SESSION_free(self->session); } PyObject_GC_Del(self); + Py_DECREF(tp); } static PyObject * PySSLSession_richcompare(PyObject *left, PyObject *right, int op) { int result; + PyTypeObject *sesstype = ((PySSLSession*)left)->ctx->state->PySSLSession_Type; if (left == NULL || right == NULL) { PyErr_BadInternalCall(); return NULL; } - if (!PySSLSession_Check(left) || !PySSLSession_Check(right)) { + if (!Py_IS_TYPE(left, sesstype) || !Py_IS_TYPE(right, sesstype)) { Py_RETURN_NOTIMPLEMENTED; } @@ -5195,6 +4979,7 @@ static int PySSLSession_traverse(PySSLSession *self, visitproc visit, void *arg) { Py_VISIT(self->ctx); + Py_VISIT(Py_TYPE(self)); return 0; } @@ -5273,37 +5058,21 @@ static PyGetSetDef PySSLSession_getsetlist[] = { {NULL}, /* sentinel */ }; -static PyTypeObject PySSLSession_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl.Session", /*tp_name*/ - sizeof(PySSLSession), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)PySSLSession_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)PySSLSession_traverse, /*tp_traverse*/ - (inquiry)PySSLSession_clear, /*tp_clear*/ - PySSLSession_richcompare, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - PySSLSession_getsetlist, /*tp_getset*/ +static PyType_Slot PySSLSession_slots[] = { + {Py_tp_getset,PySSLSession_getsetlist}, + {Py_tp_richcompare, PySSLSession_richcompare}, + {Py_tp_dealloc, PySSLSession_dealloc}, + {Py_tp_traverse, PySSLSession_traverse}, + {Py_tp_clear, PySSLSession_clear}, + {0, 0}, +}; + +static PyType_Spec PySSLSession_spec = { + .name = "_ssl.SSLSession", + .basicsize = sizeof(PySSLSession), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = PySSLSession_slots, }; @@ -5339,7 +5108,7 @@ _ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy) } static PyObject * -PySSL_RAND(int len, int pseudo) +PySSL_RAND(PyObject *module, int len, int pseudo) { int ok; PyObject *bytes; @@ -5356,11 +5125,7 @@ PySSL_RAND(int len, int pseudo) if (bytes == NULL) return NULL; if (pseudo) { -#ifdef PY_OPENSSL_1_1_API ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); -#else - ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); -#endif if (ok == 0 || ok == 1) return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); } @@ -5375,7 +5140,7 @@ PySSL_RAND(int len, int pseudo) errstr = ERR_reason_error_string(err); v = Py_BuildValue("(ks)", err, errstr); if (v != NULL) { - PyErr_SetObject(PySSLErrorObject, v); + PyErr_SetObject(get_ssl_state(module)->PySSLErrorObject, v); Py_DECREF(v); } return NULL; @@ -5393,7 +5158,7 @@ static PyObject * _ssl_RAND_bytes_impl(PyObject *module, int n) /*[clinic end generated code: output=977da635e4838bc7 input=678ddf2872dfebfc]*/ { - return PySSL_RAND(n, 0); + return PySSL_RAND(module, n, 0); } /*[clinic input] @@ -5411,13 +5176,14 @@ static PyObject * _ssl_RAND_pseudo_bytes_impl(PyObject *module, int n) /*[clinic end generated code: output=b1509e937000e52d input=58312bd53f9bbdd0]*/ { - return PySSL_RAND(n, 1); + PY_SSL_DEPRECATED("ssl.RAND_pseudo_bytes() is deprecated", 1, NULL); + return PySSL_RAND(module, n, 1); } /*[clinic input] _ssl.RAND_status -Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not. +Returns True if the OpenSSL PRNG has been seeded with enough data and False if not. It is necessary to seed the PRNG with RAND_add() on some platforms before using the ssl() function. @@ -5425,43 +5191,11 @@ using the ssl() function. static PyObject * _ssl_RAND_status_impl(PyObject *module) -/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=8a774b02d1dc81f3]*/ +/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=d5ae5aea52f36e01]*/ { - return PyLong_FromLong(RAND_status()); + return PyBool_FromLong(RAND_status()); } -#ifndef OPENSSL_NO_EGD -/* LCOV_EXCL_START */ -/*[clinic input] -_ssl.RAND_egd - path: object(converter="PyUnicode_FSConverter") - / - -Queries the entropy gather daemon (EGD) on the socket named by 'path'. - -Returns number of bytes read. Raises SSLError if connection to EGD -fails or if it does not provide enough data to seed PRNG. -[clinic start generated code]*/ - -static PyObject * -_ssl_RAND_egd_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=02a67c7c367f52fa input=1aeb7eb948312195]*/ -{ - int bytes = RAND_egd(PyBytes_AsString(path)); - Py_DECREF(path); - if (bytes == -1) { - PyErr_SetString(PySSLErrorObject, - "EGD connection failed or EGD did not return " - "enough data to seed the PRNG"); - return NULL; - } - return PyLong_FromLong(bytes); -} -/* LCOV_EXCL_STOP */ -#endif /* OPENSSL_NO_EGD */ - - - /*[clinic input] _ssl.get_default_verify_paths @@ -5505,7 +5239,7 @@ _ssl_get_default_verify_paths_impl(PyObject *module) } static PyObject* -asn1obj2py(ASN1_OBJECT *obj) +asn1obj2py(_sslmodulestate *state, ASN1_OBJECT *obj) { int nid; const char *ln, *sn; @@ -5517,7 +5251,7 @@ asn1obj2py(ASN1_OBJECT *obj) } sn = OBJ_nid2sn(nid); ln = OBJ_nid2ln(nid); - return Py_BuildValue("issN", nid, sn, ln, _asn1obj2py(obj, 1)); + return Py_BuildValue("issN", nid, sn, ln, _asn1obj2py(state, obj, 1)); } /*[clinic input] @@ -5543,7 +5277,7 @@ _ssl_txt2obj_impl(PyObject *module, const char *txt, int name) PyErr_Format(PyExc_ValueError, "unknown object '%.100s'", txt); return NULL; } - result = asn1obj2py(obj); + result = asn1obj2py(get_ssl_state(module), obj); ASN1_OBJECT_free(obj); return result; } @@ -5572,7 +5306,7 @@ _ssl_nid2obj_impl(PyObject *module, int nid) PyErr_Format(PyExc_ValueError, "unknown NID %i", nid); return NULL; } - result = asn1obj2py(obj); + result = asn1obj2py(get_ssl_state(module), obj); ASN1_OBJECT_free(obj); return result; } @@ -5904,7 +5638,6 @@ static PyMethodDef PySSL_methods[] = { _SSL_RAND_ADD_METHODDEF _SSL_RAND_BYTES_METHODDEF _SSL_RAND_PSEUDO_BYTES_METHODDEF - _SSL_RAND_EGD_METHODDEF _SSL_RAND_STATUS_METHODDEF _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF _SSL_ENUM_CERTIFICATES_METHODDEF @@ -5915,233 +5648,104 @@ static PyMethodDef PySSL_methods[] = { }; -#ifdef HAVE_OPENSSL_CRYPTO_LOCK - -/* an implementation of OpenSSL threading operations in terms - * of the Python C thread library - * Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code. - */ - -static PyThread_type_lock *_ssl_locks = NULL; - -#if OPENSSL_VERSION_NUMBER >= 0x10000000 -/* use new CRYPTO_THREADID API. */ -static void -_ssl_threadid_callback(CRYPTO_THREADID *id) -{ - CRYPTO_THREADID_set_numeric(id, PyThread_get_thread_ident()); -} -#else -/* deprecated CRYPTO_set_id_callback() API. */ -static unsigned long -_ssl_thread_id_function (void) { - return PyThread_get_thread_ident(); -} -#endif - -static void _ssl_thread_locking_function - (int mode, int n, const char *file, int line) { - /* this function is needed to perform locking on shared data - structures. (Note that OpenSSL uses a number of global data - structures that will be implicitly shared whenever multiple - threads use OpenSSL.) Multi-threaded applications will - crash at random if it is not set. - - locking_function() must be able to handle up to - CRYPTO_num_locks() different mutex locks. It sets the n-th - lock if mode & CRYPTO_LOCK, and releases it otherwise. - - file and line are the file number of the function setting the - lock. They can be useful for debugging. - */ - - if ((_ssl_locks == NULL) || - (n < 0) || ((unsigned)n >= _ssl_locks_count)) - return; - - if (mode & CRYPTO_LOCK) { - PyThread_acquire_lock(_ssl_locks[n], 1); - } else { - PyThread_release_lock(_ssl_locks[n]); - } -} - -static int _setup_ssl_threads(void) { - - unsigned int i; - - if (_ssl_locks == NULL) { - _ssl_locks_count = CRYPTO_num_locks(); - _ssl_locks = PyMem_Calloc(_ssl_locks_count, - sizeof(PyThread_type_lock)); - if (_ssl_locks == NULL) { - PyErr_NoMemory(); - return 0; - } - for (i = 0; i < _ssl_locks_count; i++) { - _ssl_locks[i] = PyThread_allocate_lock(); - if (_ssl_locks[i] == NULL) { - unsigned int j; - for (j = 0; j < i; j++) { - PyThread_free_lock(_ssl_locks[j]); - } - PyMem_Free(_ssl_locks); - return 0; - } - } - CRYPTO_set_locking_callback(_ssl_thread_locking_function); -#if OPENSSL_VERSION_NUMBER >= 0x10000000 - CRYPTO_THREADID_set_callback(_ssl_threadid_callback); -#else - CRYPTO_set_id_callback(_ssl_thread_id_function); -#endif - } - return 1; -} - -#endif /* HAVE_OPENSSL_CRYPTO_LOCK for OpenSSL < 1.1.0 */ - PyDoc_STRVAR(module_doc, "Implementation module for SSL socket operations. See the socket module\n\ for documentation."); +static int +sslmodule_init_exceptions(PyObject *module) +{ + _sslmodulestate *state = get_ssl_state(module); + PyObject *bases = NULL; + +#define add_exception(exc, name, doc, base) \ +do { \ + (exc) = PyErr_NewExceptionWithDoc("ssl." name, (doc), (base), NULL); \ + if ((state) == NULL) goto error; \ + if (PyModule_AddObjectRef(module, name, exc) < 0) goto error; \ +} while(0) + + state->PySSLErrorObject = PyType_FromSpecWithBases( + &sslerror_type_spec, PyExc_OSError); + if (state->PySSLErrorObject == NULL) { + goto error; + } + if (PyModule_AddObjectRef(module, "SSLError", state->PySSLErrorObject) < 0) { + goto error; + } -static struct PyModuleDef _sslmodule = { - PyModuleDef_HEAD_INIT, - "_ssl", - module_doc, - -1, - PySSL_methods, - NULL, - NULL, - NULL, - NULL -}; - + /* ssl.CertificateError used to be a subclass of ValueError */ + bases = PyTuple_Pack(2, state->PySSLErrorObject, PyExc_ValueError); + if (bases == NULL) { + goto error; + } + add_exception( + state->PySSLCertVerificationErrorObject, + "SSLCertVerificationError", + SSLCertVerificationError_doc, + bases + ); + Py_CLEAR(bases); + + add_exception( + state->PySSLZeroReturnErrorObject, + "SSLZeroReturnError", + SSLZeroReturnError_doc, + state->PySSLErrorObject + ); + + add_exception( + state->PySSLWantWriteErrorObject, + "SSLWantWriteError", + SSLWantWriteError_doc, + state->PySSLErrorObject + ); + + add_exception( + state->PySSLWantReadErrorObject, + "SSLWantReadError", + SSLWantReadError_doc, + state->PySSLErrorObject + ); + + add_exception( + state->PySSLSyscallErrorObject, + "SSLSyscallError", + SSLSyscallError_doc, + state->PySSLErrorObject + ); + + add_exception( + state->PySSLEOFErrorObject, + "SSLEOFError", + SSLEOFError_doc, + state->PySSLErrorObject + ); +#undef add_exception -static void -parse_openssl_version(unsigned long libver, - unsigned int *major, unsigned int *minor, - unsigned int *fix, unsigned int *patch, - unsigned int *status) -{ - *status = libver & 0xF; - libver >>= 4; - *patch = libver & 0xFF; - libver >>= 8; - *fix = libver & 0xFF; - libver >>= 8; - *minor = libver & 0xFF; - libver >>= 8; - *major = libver & 0xFF; + return 0; + error: + Py_XDECREF(bases); + return -1; } -PyMODINIT_FUNC -PyInit__ssl(void) +static int +sslmodule_init_socketapi(PyObject *module) { - PyObject *m, *d, *r, *bases; - unsigned long libver; - unsigned int major, minor, fix, patch, status; - PySocketModule_APIObject *socket_api; - struct py_ssl_error_code *errcode; - struct py_ssl_library_code *libcode; + _sslmodulestate *state = get_ssl_state(module); + PySocketModule_APIObject *sockmod = PySocketModule_ImportModuleAndAPI(); - if (PyType_Ready(&PySSLContext_Type) < 0) - return NULL; - if (PyType_Ready(&PySSLSocket_Type) < 0) - return NULL; - if (PyType_Ready(&PySSLMemoryBIO_Type) < 0) - return NULL; - if (PyType_Ready(&PySSLSession_Type) < 0) - return NULL; - - - m = PyModule_Create(&_sslmodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - - /* Load _socket module and its C API */ - socket_api = PySocketModule_ImportModuleAndAPI(); - if (!socket_api) - return NULL; - PySocketModule = *socket_api; - -#ifndef OPENSSL_VERSION_1_1 - /* Load all algorithms and initialize cpuid */ - OPENSSL_add_all_algorithms_noconf(); - /* Init OpenSSL */ - SSL_load_error_strings(); - SSL_library_init(); -#endif - -#ifdef HAVE_OPENSSL_CRYPTO_LOCK - /* note that this will start threading if not already started */ - if (!_setup_ssl_threads()) { - return NULL; + if ((sockmod == NULL) || (sockmod->Sock_Type == NULL)) { + return -1; } -#elif OPENSSL_VERSION_1_1 - /* OpenSSL 1.1.0 builtin thread support is enabled */ - _ssl_locks_count++; -#endif - - /* Add symbols to module dict */ - sslerror_type_slots[0].pfunc = PyExc_OSError; - PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec); - if (PySSLErrorObject == NULL) - return NULL; + state->Sock_Type = sockmod->Sock_Type; + Py_INCREF(state->Sock_Type); + return 0; +} - /* ssl.CertificateError used to be a subclass of ValueError */ - bases = Py_BuildValue("OO", PySSLErrorObject, PyExc_ValueError); - if (bases == NULL) - return NULL; - PySSLCertVerificationErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLCertVerificationError", SSLCertVerificationError_doc, - bases, NULL); - Py_DECREF(bases); - PySSLZeroReturnErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLZeroReturnError", SSLZeroReturnError_doc, - PySSLErrorObject, NULL); - PySSLWantReadErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLWantReadError", SSLWantReadError_doc, - PySSLErrorObject, NULL); - PySSLWantWriteErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLWantWriteError", SSLWantWriteError_doc, - PySSLErrorObject, NULL); - PySSLSyscallErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLSyscallError", SSLSyscallError_doc, - PySSLErrorObject, NULL); - PySSLEOFErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLEOFError", SSLEOFError_doc, - PySSLErrorObject, NULL); - if (PySSLCertVerificationErrorObject == NULL - || PySSLZeroReturnErrorObject == NULL - || PySSLWantReadErrorObject == NULL - || PySSLWantWriteErrorObject == NULL - || PySSLSyscallErrorObject == NULL - || PySSLEOFErrorObject == NULL) - return NULL; - if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0 - || PyDict_SetItemString(d, "SSLCertVerificationError", - PySSLCertVerificationErrorObject) != 0 - || PyDict_SetItemString(d, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantReadError", PySSLWantReadErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0 - || PyDict_SetItemString(d, "SSLSyscallError", PySSLSyscallErrorObject) != 0 - || PyDict_SetItemString(d, "SSLEOFError", PySSLEOFErrorObject) != 0) - return NULL; - if (PyDict_SetItemString(d, "_SSLContext", - (PyObject *)&PySSLContext_Type) != 0) - return NULL; - if (PyDict_SetItemString(d, "_SSLSocket", - (PyObject *)&PySSLSocket_Type) != 0) - return NULL; - if (PyDict_SetItemString(d, "MemoryBIO", - (PyObject *)&PySSLMemoryBIO_Type) != 0) - return NULL; - if (PyDict_SetItemString(d, "SSLSession", - (PyObject *)&PySSLSession_Type) != 0) - return NULL; +static int +sslmodule_init_constants(PyObject *m) +{ PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", PY_SSL_DEFAULT_CIPHER_STRING); @@ -6181,9 +5785,14 @@ PyInit__ssl(void) X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); PyModule_AddIntConstant(m, "VERIFY_X509_STRICT", X509_V_FLAG_X509_STRICT); -#ifdef X509_V_FLAG_TRUSTED_FIRST + PyModule_AddIntConstant(m, "VERIFY_ALLOW_PROXY_CERTS", + X509_V_FLAG_ALLOW_PROXY_CERTS); PyModule_AddIntConstant(m, "VERIFY_X509_TRUSTED_FIRST", X509_V_FLAG_TRUSTED_FIRST); + +#ifdef X509_V_FLAG_PARTIAL_CHAIN + PyModule_AddIntConstant(m, "VERIFY_X509_PARTIAL_CHAIN", + X509_V_FLAG_PARTIAL_CHAIN); #endif /* Alert Descriptions from ssl.h */ @@ -6323,6 +5932,10 @@ PyInit__ssl(void) X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); #endif + /* file types */ + PyModule_AddIntConstant(m, "ENCODING_PEM", PY_SSL_ENCODING_PEM); + PyModule_AddIntConstant(m, "ENCODING_DER", PY_SSL_ENCODING_DER); + /* protocol versions */ PyModule_AddIntConstant(m, "PROTO_MINIMUM_SUPPORTED", PY_PROTO_MINIMUM_SUPPORTED); @@ -6341,31 +5954,11 @@ PyInit__ssl(void) PyModule_AddObject((m), (key), bool_obj); \ } while (0) -#if HAVE_SNI addbool(m, "HAS_SNI", 1); -#else - addbool(m, "HAS_SNI", 0); -#endif - addbool(m, "HAS_TLS_UNIQUE", 1); - -#ifndef OPENSSL_NO_ECDH addbool(m, "HAS_ECDH", 1); -#else - addbool(m, "HAS_ECDH", 0); -#endif - -#if HAVE_NPN - addbool(m, "HAS_NPN", 1); -#else addbool(m, "HAS_NPN", 0); -#endif - -#if HAVE_ALPN addbool(m, "HAS_ALPN", 1); -#else - addbool(m, "HAS_ALPN", 0); -#endif #if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2) addbool(m, "HAS_SSLv2", 1); @@ -6403,49 +5996,91 @@ PyInit__ssl(void) addbool(m, "HAS_TLSv1_3", 0); #endif + return 0; +} + +static int +sslmodule_init_errorcodes(PyObject *module) +{ + _sslmodulestate *state = get_ssl_state(module); + + struct py_ssl_error_code *errcode; + struct py_ssl_library_code *libcode; + /* Mappings for error codes */ - err_codes_to_names = PyDict_New(); - err_names_to_codes = PyDict_New(); - if (err_codes_to_names == NULL || err_names_to_codes == NULL) - return NULL; + 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) - return NULL; - if (PyDict_SetItem(err_codes_to_names, key, mnemo)) - return NULL; - if (PyDict_SetItem(err_names_to_codes, mnemo, key)) - return 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)) + return -1; Py_DECREF(key); Py_DECREF(mnemo); errcode++; } - if (PyModule_AddObject(m, "err_codes_to_names", err_codes_to_names)) - return NULL; - if (PyModule_AddObject(m, "err_names_to_codes", err_names_to_codes)) - return NULL; - lib_codes_to_names = PyDict_New(); - if (lib_codes_to_names == NULL) - return NULL; libcode = library_codes; while (libcode->library != NULL) { PyObject *mnemo, *key; key = PyLong_FromLong(libcode->code); mnemo = PyUnicode_FromString(libcode->library); if (key == NULL || mnemo == NULL) - return NULL; - if (PyDict_SetItem(lib_codes_to_names, key, mnemo)) - return NULL; + return -1; + if (PyDict_SetItem(state->lib_codes_to_names, key, mnemo)) + return -1; Py_DECREF(key); Py_DECREF(mnemo); libcode++; } - if (PyModule_AddObject(m, "lib_codes_to_names", lib_codes_to_names)) - return NULL; + + 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; +} + +static void +parse_openssl_version(unsigned long libver, + unsigned int *major, unsigned int *minor, + unsigned int *fix, unsigned int *patch, + unsigned int *status) +{ + *status = libver & 0xF; + libver >>= 4; + *patch = libver & 0xFF; + libver >>= 8; + *fix = libver & 0xFF; + libver >>= 8; + *minor = libver & 0xFF; + libver >>= 8; + *major = libver & 0xFF; +} + +static int +sslmodule_init_versioninfo(PyObject *m) +{ + PyObject *r; + unsigned long libver; + unsigned int major, minor, fix, patch, status; /* OpenSSL version */ /* SSLeay() gives us the version of the library linked against, @@ -6453,23 +6088,155 @@ PyInit__ssl(void) */ libver = OpenSSL_version_num(); r = PyLong_FromUnsignedLong(libver); - if (r == NULL) - return NULL; - if (PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r)) - return NULL; + if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r)) + 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)) - return NULL; + return -1; + r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) - return NULL; + 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)) - return NULL; + return -1; + + return 0; +} - return m; +static int +sslmodule_init_types(PyObject *module) +{ + _sslmodulestate *state = get_ssl_state(module); + + state->PySSLContext_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &PySSLContext_spec, NULL + ); + if (state->PySSLContext_Type == NULL) + return -1; + + state->PySSLSocket_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &PySSLSocket_spec, NULL + ); + if (state->PySSLSocket_Type == NULL) + return -1; + + state->PySSLMemoryBIO_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &PySSLMemoryBIO_spec, NULL + ); + if (state->PySSLMemoryBIO_Type == NULL) + return -1; + + state->PySSLSession_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &PySSLSession_spec, NULL + ); + if (state->PySSLSession_Type == NULL) + return -1; + + state->PySSLCertificate_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &PySSLCertificate_spec, NULL + ); + if (state->PySSLCertificate_Type == NULL) + return -1; + + if (PyModule_AddType(module, state->PySSLContext_Type)) + return -1; + if (PyModule_AddType(module, state->PySSLSocket_Type)) + return -1; + if (PyModule_AddType(module, state->PySSLMemoryBIO_Type)) + return -1; + if (PyModule_AddType(module, state->PySSLSession_Type)) + return -1; + if (PyModule_AddType(module, state->PySSLCertificate_Type)) + return -1; + return 0; +} + +static PyModuleDef_Slot sslmodule_slots[] = { + {Py_mod_exec, sslmodule_init_types}, + {Py_mod_exec, sslmodule_init_exceptions}, + {Py_mod_exec, sslmodule_init_socketapi}, + {Py_mod_exec, sslmodule_init_errorcodes}, + {Py_mod_exec, sslmodule_init_constants}, + {Py_mod_exec, sslmodule_init_versioninfo}, + {0, NULL} +}; + +static int +sslmodule_traverse(PyObject *m, visitproc visit, void *arg) +{ + _sslmodulestate *state = get_ssl_state(m); + + Py_VISIT(state->PySSLContext_Type); + Py_VISIT(state->PySSLSocket_Type); + Py_VISIT(state->PySSLMemoryBIO_Type); + Py_VISIT(state->PySSLSession_Type); + Py_VISIT(state->PySSLCertificate_Type); + Py_VISIT(state->PySSLErrorObject); + Py_VISIT(state->PySSLCertVerificationErrorObject); + Py_VISIT(state->PySSLZeroReturnErrorObject); + Py_VISIT(state->PySSLWantReadErrorObject); + Py_VISIT(state->PySSLWantWriteErrorObject); + 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); + + return 0; +} + +static int +sslmodule_clear(PyObject *m) +{ + _sslmodulestate *state = get_ssl_state(m); + + Py_CLEAR(state->PySSLContext_Type); + Py_CLEAR(state->PySSLSocket_Type); + Py_CLEAR(state->PySSLMemoryBIO_Type); + Py_CLEAR(state->PySSLSession_Type); + Py_CLEAR(state->PySSLCertificate_Type); + Py_CLEAR(state->PySSLErrorObject); + Py_CLEAR(state->PySSLCertVerificationErrorObject); + Py_CLEAR(state->PySSLZeroReturnErrorObject); + Py_CLEAR(state->PySSLWantReadErrorObject); + Py_CLEAR(state->PySSLWantWriteErrorObject); + 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); + + return 0; +} + +static void +sslmodule_free(void *m) +{ + sslmodule_clear((PyObject *)m); +} + +static struct PyModuleDef _sslmodule_def = { + PyModuleDef_HEAD_INIT, + .m_name = "_ssl", + .m_doc = module_doc, + .m_size = sizeof(_sslmodulestate), + .m_methods = PySSL_methods, + .m_slots = sslmodule_slots, + .m_traverse = sslmodule_traverse, + .m_clear = sslmodule_clear, + .m_free = sslmodule_free +}; + +PyMODINIT_FUNC +PyInit__ssl(void) +{ + return PyModuleDef_Init(&_sslmodule_def); } diff --git a/contrib/tools/python3/src/Modules/_ssl.h b/contrib/tools/python3/src/Modules/_ssl.h new file mode 100644 index 00000000000..5fe6504a9dd --- /dev/null +++ b/contrib/tools/python3/src/Modules/_ssl.h @@ -0,0 +1,74 @@ +#ifndef Py_SSL_H +#define Py_SSL_H + +/* OpenSSL header files */ +#include "openssl/evp.h" +#include "openssl/x509.h" + +/* + * ssl module state + */ +typedef struct { + /* Types */ + PyTypeObject *PySSLContext_Type; + PyTypeObject *PySSLSocket_Type; + PyTypeObject *PySSLMemoryBIO_Type; + PyTypeObject *PySSLSession_Type; + PyTypeObject *PySSLCertificate_Type; + /* SSL error object */ + PyObject *PySSLErrorObject; + PyObject *PySSLCertVerificationErrorObject; + PyObject *PySSLZeroReturnErrorObject; + PyObject *PySSLWantReadErrorObject; + PyObject *PySSLWantWriteErrorObject; + PyObject *PySSLSyscallErrorObject; + 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; +} _sslmodulestate; + +static struct PyModuleDef _sslmodule_def; + +Py_LOCAL_INLINE(_sslmodulestate*) +get_ssl_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_sslmodulestate *)state; +} + +#define get_state_type(type) \ + (get_ssl_state(_PyType_GetModuleByDef(type, &_sslmodule_def))) +#define get_state_ctx(c) (((PySSLContext *)(c))->state) +#define get_state_sock(s) (((PySSLSocket *)(s))->ctx->state) +#define get_state_obj(o) ((_sslmodulestate *)PyType_GetModuleState(Py_TYPE(o))) +#define get_state_mbio(b) get_state_obj(b) +#define get_state_cert(c) get_state_obj(c) + +/* ************************************************************************ + * certificate + */ + +enum py_ssl_encoding { + PY_SSL_ENCODING_PEM=X509_FILETYPE_PEM, + PY_SSL_ENCODING_DER=X509_FILETYPE_ASN1, + PY_SSL_ENCODING_PEM_AUX=X509_FILETYPE_PEM + 0x100, +}; + +typedef struct { + PyObject_HEAD + X509 *cert; + Py_hash_t hash; +} PySSLCertificate; + +/* ************************************************************************ + * helpers and utils + */ +static PyObject *_PySSL_BytesFromBIO(_sslmodulestate *state, BIO *bio); +static PyObject *_PySSL_UnicodeFromBIO(_sslmodulestate *state, BIO *bio, const char *error); + +#endif /* Py_SSL_H */ diff --git a/contrib/tools/python3/src/Modules/_ssl/cert.c b/contrib/tools/python3/src/Modules/_ssl/cert.c new file mode 100644 index 00000000000..bda66dc4d94 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_ssl/cert.c @@ -0,0 +1,245 @@ +#include "Python.h" +#include "../_ssl.h" + +#include "openssl/err.h" +#include "openssl/bio.h" +#include "openssl/pem.h" +#include "openssl/x509.h" + +/*[clinic input] +module _ssl +class _ssl.Certificate "PySSLCertificate *" "PySSLCertificate_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=780fc647948cfffc]*/ + +#include "clinic/cert.c.h" + +static PyObject * +newCertificate(PyTypeObject *type, X509 *cert, int upref) +{ + PySSLCertificate *self; + + assert(type != NULL && type->tp_alloc != NULL); + assert(cert != NULL); + + self = (PySSLCertificate *) type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + if (upref == 1) { + X509_up_ref(cert); + } + self->cert = cert; + self->hash = -1; + + return (PyObject *) self; +} + +static PyObject * +_PySSL_CertificateFromX509(_sslmodulestate *state, X509 *cert, int upref) +{ + return newCertificate(state->PySSLCertificate_Type, cert, upref); +} + +static PyObject* +_PySSL_CertificateFromX509Stack(_sslmodulestate *state, STACK_OF(X509) *stack, int upref) +{ + int len, i; + PyObject *result = NULL; + + len = sk_X509_num(stack); + result = PyList_New(len); + if (result == NULL) { + return NULL; + } + for (i = 0; i < len; i++) { + X509 *cert = sk_X509_value(stack, i); + PyObject *ocert = _PySSL_CertificateFromX509(state, cert, upref); + if (ocert == NULL) { + Py_DECREF(result); + return NULL; + } + PyList_SetItem(result, i, ocert); + } + return result; +} + +/*[clinic input] +_ssl.Certificate.public_bytes + format: int(c_default="PY_SSL_ENCODING_PEM") = Encoding.PEM + +[clinic start generated code]*/ + +static PyObject * +_ssl_Certificate_public_bytes_impl(PySSLCertificate *self, int format) +/*[clinic end generated code: output=c01ddbb697429e12 input=4d38c45e874b0e64]*/ +{ + BIO *bio; + int retcode; + PyObject *result; + _sslmodulestate *state = get_state_cert(self); + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + PyErr_SetString(state->PySSLErrorObject, + "failed to allocate BIO"); + return NULL; + } + switch(format) { + case PY_SSL_ENCODING_PEM: + retcode = PEM_write_bio_X509(bio, self->cert); + break; + case PY_SSL_ENCODING_PEM_AUX: + retcode = PEM_write_bio_X509_AUX(bio, self->cert); + break; + case PY_SSL_ENCODING_DER: + retcode = i2d_X509_bio(bio, self->cert); + break; + default: + PyErr_SetString(PyExc_ValueError, "Unsupported format"); + BIO_free(bio); + return NULL; + } + if (retcode != 1) { + BIO_free(bio); + _setSSLError(state, NULL, 0, __FILE__, __LINE__); + return NULL; + } + if (format == PY_SSL_ENCODING_DER) { + result = _PySSL_BytesFromBIO(state, bio); + } else { + result = _PySSL_UnicodeFromBIO(state, bio, "error"); + } + BIO_free(bio); + return result; +} + + +/*[clinic input] +_ssl.Certificate.get_info + +[clinic start generated code]*/ + +static PyObject * +_ssl_Certificate_get_info_impl(PySSLCertificate *self) +/*[clinic end generated code: output=0f0deaac54f4408b input=ba2c1694b39d0778]*/ +{ + return _decode_certificate(get_state_cert(self), self->cert); +} + +static PyObject* +_x509name_print(_sslmodulestate *state, X509_NAME *name, int indent, unsigned long flags) +{ + PyObject *res; + BIO *biobuf; + + biobuf = BIO_new(BIO_s_mem()); + if (biobuf == NULL) { + PyErr_SetString(PyExc_MemoryError, "failed to allocate BIO"); + return NULL; + } + + if (X509_NAME_print_ex(biobuf, name, indent, flags) <= 0) { + _setSSLError(state, NULL, 0, __FILE__, __LINE__); + BIO_free(biobuf); + return NULL; + } + res = _PySSL_UnicodeFromBIO(state, biobuf, "strict"); + BIO_free(biobuf); + return res; +} + +/* ************************************************************************ + * PySSLCertificate_Type + */ + +static PyObject * +certificate_repr(PySSLCertificate *self) +{ + PyObject *osubject, *result; + + /* subject string is ASCII encoded, UTF-8 chars are quoted */ + osubject = _x509name_print( + get_state_cert(self), + X509_get_subject_name(self->cert), + 0, + XN_FLAG_RFC2253 + ); + if (osubject == NULL) + return NULL; + result = PyUnicode_FromFormat( + "<%s '%U'>", + Py_TYPE(self)->tp_name, osubject + ); + Py_DECREF(osubject); + return result; +} + +static Py_hash_t +certificate_hash(PySSLCertificate *self) +{ + if (self->hash == (Py_hash_t)-1) { + unsigned long hash; + hash = X509_subject_name_hash(self->cert); + if ((Py_hash_t)hash == (Py_hash_t)-1) { + self->hash = -2; + } else { + self->hash = (Py_hash_t)hash; + } + } + return self->hash; +} + +static PyObject * +certificate_richcompare(PySSLCertificate *self, PyObject *other, int op) +{ + int cmp; + _sslmodulestate *state = get_state_cert(self); + + if (Py_TYPE(other) != state->PySSLCertificate_Type) { + Py_RETURN_NOTIMPLEMENTED; + } + /* only support == and != */ + if ((op != Py_EQ) && (op != Py_NE)) { + Py_RETURN_NOTIMPLEMENTED; + } + cmp = X509_cmp(self->cert, ((PySSLCertificate*)other)->cert); + if (((op == Py_EQ) && (cmp == 0)) || ((op == Py_NE) && (cmp != 0))) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +static void +certificate_dealloc(PySSLCertificate *self) +{ + PyTypeObject *tp = Py_TYPE(self); + X509_free(self->cert); + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static PyMethodDef certificate_methods[] = { + /* methods */ + _SSL_CERTIFICATE_PUBLIC_BYTES_METHODDEF + _SSL_CERTIFICATE_GET_INFO_METHODDEF + {NULL, NULL} +}; + +static PyType_Slot PySSLCertificate_slots[] = { + {Py_tp_dealloc, certificate_dealloc}, + {Py_tp_repr, certificate_repr}, + {Py_tp_hash, certificate_hash}, + {Py_tp_richcompare, certificate_richcompare}, + {Py_tp_methods, certificate_methods}, + {0, 0}, +}; + +static PyType_Spec PySSLCertificate_spec = { + "_ssl.Certificate", + sizeof(PySSLCertificate), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, + PySSLCertificate_slots, +}; diff --git a/contrib/tools/python3/src/Modules/_ssl/clinic/cert.c.h b/contrib/tools/python3/src/Modules/_ssl/clinic/cert.c.h new file mode 100644 index 00000000000..c4377128b36 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_ssl/clinic/cert.c.h @@ -0,0 +1,60 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_ssl_Certificate_public_bytes__doc__, +"public_bytes($self, /, format=Encoding.PEM)\n" +"--\n" +"\n"); + +#define _SSL_CERTIFICATE_PUBLIC_BYTES_METHODDEF \ + {"public_bytes", (PyCFunction)(void(*)(void))_ssl_Certificate_public_bytes, METH_FASTCALL|METH_KEYWORDS, _ssl_Certificate_public_bytes__doc__}, + +static PyObject * +_ssl_Certificate_public_bytes_impl(PySSLCertificate *self, int format); + +static PyObject * +_ssl_Certificate_public_bytes(PySSLCertificate *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"format", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "public_bytes", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int format = PY_SSL_ENCODING_PEM; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + format = _PyLong_AsInt(args[0]); + if (format == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = _ssl_Certificate_public_bytes_impl(self, format); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl_Certificate_get_info__doc__, +"get_info($self, /)\n" +"--\n" +"\n"); + +#define _SSL_CERTIFICATE_GET_INFO_METHODDEF \ + {"get_info", (PyCFunction)_ssl_Certificate_get_info, METH_NOARGS, _ssl_Certificate_get_info__doc__}, + +static PyObject * +_ssl_Certificate_get_info_impl(PySSLCertificate *self); + +static PyObject * +_ssl_Certificate_get_info(PySSLCertificate *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl_Certificate_get_info_impl(self); +} +/*[clinic end generated code: output=569d161749ead2da input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_ssl/debughelpers.c b/contrib/tools/python3/src/Modules/_ssl/debughelpers.c index af56f9d28d1..03c125eb44f 100644 --- a/contrib/tools/python3/src/Modules/_ssl/debughelpers.c +++ b/contrib/tools/python3/src/Modules/_ssl/debughelpers.c @@ -21,7 +21,7 @@ _PySSL_msg_callback(int write_p, int version, int content_type, threadstate = PyGILState_Ensure(); ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); - assert(PySSLSocket_Check(ssl_obj)); + assert(Py_IS_TYPE(ssl_obj, get_state_sock(ssl_obj)->PySSLSocket_Type)); if (ssl_obj->ctx->msg_cb == NULL) { PyGILState_Release(threadstate); return; @@ -114,8 +114,6 @@ _PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) { return 0; } -#ifdef HAVE_OPENSSL_KEYLOG - static void _PySSL_keylog_callback(const SSL *ssl, const char *line) { @@ -127,7 +125,7 @@ _PySSL_keylog_callback(const SSL *ssl, const char *line) threadstate = PyGILState_Ensure(); ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); - assert(PySSLSocket_Check(ssl_obj)); + assert(Py_IS_TYPE(ssl_obj, get_state_sock(ssl_obj)->PySSLSocket_Type)); if (ssl_obj->ctx->keylog_bio == NULL) { return; } @@ -201,7 +199,7 @@ _PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { self->keylog_bio = BIO_new_fp(fp, BIO_CLOSE | BIO_FP_TEXT); if (self->keylog_bio == NULL) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(get_state_ctx(self)->PySSLErrorObject, "Can't malloc memory for keylog file"); return -1; } @@ -219,5 +217,3 @@ _PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback); return 0; } - -#endif diff --git a/contrib/tools/python3/src/Modules/_ssl/misc.c b/contrib/tools/python3/src/Modules/_ssl/misc.c new file mode 100644 index 00000000000..4de091d57ef --- /dev/null +++ b/contrib/tools/python3/src/Modules/_ssl/misc.c @@ -0,0 +1,34 @@ +#include "Python.h" +#include "../_ssl.h" + +#include "openssl/bio.h" + +/* BIO_s_mem() to PyBytes + */ +static PyObject * +_PySSL_BytesFromBIO(_sslmodulestate *state, BIO *bio) +{ + long size; + char *data = NULL; + size = BIO_get_mem_data(bio, &data); + if (data == NULL || size < 0) { + PyErr_SetString(PyExc_ValueError, "Not a memory BIO"); + return NULL; + } + return PyBytes_FromStringAndSize(data, size); +} + +/* BIO_s_mem() to PyUnicode + */ +static PyObject * +_PySSL_UnicodeFromBIO(_sslmodulestate *state, BIO *bio, const char *error) +{ + long size; + char *data = NULL; + size = BIO_get_mem_data(bio, &data); + if (data == NULL || size < 0) { + PyErr_SetString(PyExc_ValueError, "Not a memory BIO"); + return NULL; + } + return PyUnicode_DecodeUTF8(data, size, error); +} diff --git a/contrib/tools/python3/src/Modules/_struct.c b/contrib/tools/python3/src/Modules/_struct.c index f759f0b1694..30ad9f2b79d 100644 --- a/contrib/tools/python3/src/Modules/_struct.c +++ b/contrib/tools/python3/src/Modules/_struct.c @@ -6,6 +6,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "structmember.h" // PyMemberDef #include @@ -15,6 +16,7 @@ class Struct "PyStructObject *" "&PyStructType" /*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/ typedef struct { + PyObject *cache; PyObject *PyStructType; PyObject *unpackiter_type; PyObject *StructError; @@ -23,23 +25,26 @@ typedef struct { static inline _structmodulestate* get_struct_state(PyObject *module) { - void *state = PyModule_GetState(module); + void *state = _PyModule_GetState(module); assert(state != NULL); return (_structmodulestate *)state; } static struct PyModuleDef _structmodule; -#define _structmodulestate_global get_struct_state(PyState_FindModule(&_structmodule)) +#define get_struct_state_structinst(self) \ + (get_struct_state(_PyType_GetModuleByDef(Py_TYPE(self), &_structmodule))) +#define get_struct_state_iterinst(self) \ + (get_struct_state(PyType_GetModule(Py_TYPE(self)))) /* The translation function for each format character is table driven */ typedef struct _formatdef { char format; Py_ssize_t size; Py_ssize_t alignment; - PyObject* (*unpack)(const char *, + PyObject* (*unpack)(_structmodulestate *, const char *, const struct _formatdef *); - int (*pack)(char *, PyObject *, + int (*pack)(_structmodulestate *, char *, PyObject *, const struct _formatdef *); } formatdef; @@ -61,10 +66,7 @@ typedef struct { PyObject *weakreflist; /* List of weak references */ } PyStructObject; - -#define PyStruct_Check(op) PyObject_TypeCheck(op, (PyTypeObject *)_structmodulestate_global->PyStructType) -#define PyStruct_CheckExact(op) Py_IS_TYPE(op, (PyTypeObject *)_structmodulestate_global->PyStructType) - +#define PyStruct_Check(op, state) PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType) /* Define various structs to figure out the alignments of types */ @@ -102,12 +104,20 @@ class cache_struct_converter(CConverter): converter = 'cache_struct_converter' c_default = "NULL" + def parse_arg(self, argname, displayname): + return """ + if (!{converter}(module, {argname}, &{paramname})) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.name, + converter=self.converter) + def cleanup(self): return "Py_XDECREF(%s);\n" % self.name [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=d6746621c2fb1a7d]*/ -static int cache_struct_converter(PyObject *, PyStructObject **); +static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **); #include "clinic/_struct.c.h" @@ -115,18 +125,18 @@ static int cache_struct_converter(PyObject *, PyStructObject **); PyLongObject if possible, otherwise fails. Caller should decref. */ static PyObject * -get_pylong(PyObject *v) +get_pylong(_structmodulestate *state, PyObject *v) { assert(v != NULL); if (!PyLong_Check(v)) { /* Not an integer; try to use __index__ to convert. */ if (PyIndex_Check(v)) { - v = PyNumber_Index(v); + v = _PyNumber_Index(v); if (v == NULL) return NULL; } else { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not an integer"); return NULL; } @@ -142,11 +152,11 @@ get_pylong(PyObject *v) one */ static int -get_long(PyObject *v, long *p) +get_long(_structmodulestate *state, PyObject *v, long *p) { long x; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; assert(PyLong_Check(v)); @@ -154,7 +164,7 @@ get_long(PyObject *v, long *p) Py_DECREF(v); if (x == (long)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument out of range"); return -1; } @@ -166,11 +176,11 @@ get_long(PyObject *v, long *p) /* Same, but handling unsigned long */ static int -get_ulong(PyObject *v, unsigned long *p) +get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p) { unsigned long x; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; assert(PyLong_Check(v)); @@ -178,7 +188,7 @@ get_ulong(PyObject *v, unsigned long *p) Py_DECREF(v); if (x == (unsigned long)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument out of range"); return -1; } @@ -189,11 +199,11 @@ get_ulong(PyObject *v, unsigned long *p) /* Same, but handling native long long. */ static int -get_longlong(PyObject *v, long long *p) +get_longlong(_structmodulestate *state, PyObject *v, long long *p) { long long x; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; assert(PyLong_Check(v)); @@ -201,7 +211,7 @@ get_longlong(PyObject *v, long long *p) Py_DECREF(v); if (x == (long long)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument out of range"); return -1; } @@ -212,11 +222,11 @@ get_longlong(PyObject *v, long long *p) /* Same, but handling native unsigned long long. */ static int -get_ulonglong(PyObject *v, unsigned long long *p) +get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p) { unsigned long long x; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; assert(PyLong_Check(v)); @@ -224,7 +234,7 @@ get_ulonglong(PyObject *v, unsigned long long *p) Py_DECREF(v); if (x == (unsigned long long)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument out of range"); return -1; } @@ -235,11 +245,11 @@ get_ulonglong(PyObject *v, unsigned long long *p) /* Same, but handling Py_ssize_t */ static int -get_ssize_t(PyObject *v, Py_ssize_t *p) +get_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p) { Py_ssize_t x; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; assert(PyLong_Check(v)); @@ -247,7 +257,7 @@ get_ssize_t(PyObject *v, Py_ssize_t *p) Py_DECREF(v); if (x == (Py_ssize_t)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument out of range"); return -1; } @@ -258,11 +268,11 @@ get_ssize_t(PyObject *v, Py_ssize_t *p) /* Same, but handling size_t */ static int -get_size_t(PyObject *v, size_t *p) +get_size_t(_structmodulestate *state, PyObject *v, size_t *p) { size_t x; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; assert(PyLong_Check(v)); @@ -270,7 +280,7 @@ get_size_t(PyObject *v, size_t *p) Py_DECREF(v); if (x == (size_t)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument out of range"); return -1; } @@ -279,7 +289,7 @@ get_size_t(PyObject *v, size_t *p) } -#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag) +#define RANGE_ERROR(state, x, f, flag, mask) return _range_error(state, f, flag) /* Floating point helpers */ @@ -298,13 +308,14 @@ unpack_halffloat(const char *p, /* start of 2-byte string */ } static int -pack_halffloat(char *p, /* start of 2-byte string */ +pack_halffloat(_structmodulestate *state, + char *p, /* start of 2-byte string */ PyObject *v, /* value to pack */ int le) /* true for little-endian, false for big-endian */ { double x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not a float"); return -1; } @@ -337,7 +348,7 @@ unpack_double(const char *p, /* start of 8-byte string */ /* Helper to format the range error exceptions */ static int -_range_error(const formatdef *f, int is_unsigned) +_range_error(_structmodulestate *state, const formatdef *f, int is_unsigned) { /* ulargest is the largest unsigned value with f->size bytes. * Note that the simpler: @@ -350,13 +361,13 @@ _range_error(const formatdef *f, int is_unsigned) const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8); assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T); if (is_unsigned) - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "'%c' format requires 0 <= number <= %zu", f->format, ulargest); else { const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1); - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "'%c' format requires %zd <= number <= %zd", f->format, ~ largest, @@ -388,25 +399,25 @@ _range_error(const formatdef *f, int is_unsigned) does this). */ static PyObject * -nu_char(const char *p, const formatdef *f) +nu_char(_structmodulestate *state, const char *p, const formatdef *f) { return PyBytes_FromStringAndSize(p, 1); } static PyObject * -nu_byte(const char *p, const formatdef *f) +nu_byte(_structmodulestate *state, const char *p, const formatdef *f) { return PyLong_FromLong((long) *(signed char *)p); } static PyObject * -nu_ubyte(const char *p, const formatdef *f) +nu_ubyte(_structmodulestate *state, const char *p, const formatdef *f) { return PyLong_FromLong((long) *(unsigned char *)p); } static PyObject * -nu_short(const char *p, const formatdef *f) +nu_short(_structmodulestate *state, const char *p, const formatdef *f) { short x; memcpy((char *)&x, p, sizeof x); @@ -414,7 +425,7 @@ nu_short(const char *p, const formatdef *f) } static PyObject * -nu_ushort(const char *p, const formatdef *f) +nu_ushort(_structmodulestate *state, const char *p, const formatdef *f) { unsigned short x; memcpy((char *)&x, p, sizeof x); @@ -422,7 +433,7 @@ nu_ushort(const char *p, const formatdef *f) } static PyObject * -nu_int(const char *p, const formatdef *f) +nu_int(_structmodulestate *state, const char *p, const formatdef *f) { int x; memcpy((char *)&x, p, sizeof x); @@ -430,7 +441,7 @@ nu_int(const char *p, const formatdef *f) } static PyObject * -nu_uint(const char *p, const formatdef *f) +nu_uint(_structmodulestate *state, const char *p, const formatdef *f) { unsigned int x; memcpy((char *)&x, p, sizeof x); @@ -438,7 +449,7 @@ nu_uint(const char *p, const formatdef *f) } static PyObject * -nu_long(const char *p, const formatdef *f) +nu_long(_structmodulestate *state, const char *p, const formatdef *f) { long x; memcpy((char *)&x, p, sizeof x); @@ -446,7 +457,7 @@ nu_long(const char *p, const formatdef *f) } static PyObject * -nu_ulong(const char *p, const formatdef *f) +nu_ulong(_structmodulestate *state, const char *p, const formatdef *f) { unsigned long x; memcpy((char *)&x, p, sizeof x); @@ -454,7 +465,7 @@ nu_ulong(const char *p, const formatdef *f) } static PyObject * -nu_ssize_t(const char *p, const formatdef *f) +nu_ssize_t(_structmodulestate *state, const char *p, const formatdef *f) { Py_ssize_t x; memcpy((char *)&x, p, sizeof x); @@ -462,7 +473,7 @@ nu_ssize_t(const char *p, const formatdef *f) } static PyObject * -nu_size_t(const char *p, const formatdef *f) +nu_size_t(_structmodulestate *state, const char *p, const formatdef *f) { size_t x; memcpy((char *)&x, p, sizeof x); @@ -470,7 +481,7 @@ nu_size_t(const char *p, const formatdef *f) } static PyObject * -nu_longlong(const char *p, const formatdef *f) +nu_longlong(_structmodulestate *state, const char *p, const formatdef *f) { long long x; memcpy((char *)&x, p, sizeof x); @@ -478,7 +489,7 @@ nu_longlong(const char *p, const formatdef *f) } static PyObject * -nu_ulonglong(const char *p, const formatdef *f) +nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) { unsigned long long x; memcpy((char *)&x, p, sizeof x); @@ -486,7 +497,7 @@ nu_ulonglong(const char *p, const formatdef *f) } static PyObject * -nu_bool(const char *p, const formatdef *f) +nu_bool(_structmodulestate *state, const char *p, const formatdef *f) { _Bool x; memcpy((char *)&x, p, sizeof x); @@ -495,7 +506,7 @@ nu_bool(const char *p, const formatdef *f) static PyObject * -nu_halffloat(const char *p, const formatdef *f) +nu_halffloat(_structmodulestate *state, const char *p, const formatdef *f) { #if PY_LITTLE_ENDIAN return unpack_halffloat(p, 1); @@ -505,7 +516,7 @@ nu_halffloat(const char *p, const formatdef *f) } static PyObject * -nu_float(const char *p, const formatdef *f) +nu_float(_structmodulestate *state, const char *p, const formatdef *f) { float x; memcpy((char *)&x, p, sizeof x); @@ -513,7 +524,7 @@ nu_float(const char *p, const formatdef *f) } static PyObject * -nu_double(const char *p, const formatdef *f) +nu_double(_structmodulestate *state, const char *p, const formatdef *f) { double x; memcpy((char *)&x, p, sizeof x); @@ -521,7 +532,7 @@ nu_double(const char *p, const formatdef *f) } static PyObject * -nu_void_p(const char *p, const formatdef *f) +nu_void_p(_structmodulestate *state, const char *p, const formatdef *f) { void *x; memcpy((char *)&x, p, sizeof x); @@ -529,13 +540,13 @@ nu_void_p(const char *p, const formatdef *f) } static int -np_byte(char *p, PyObject *v, const formatdef *f) +np_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; if (x < -128 || x > 127) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "byte format requires -128 <= number <= 127"); return -1; } @@ -544,13 +555,13 @@ np_byte(char *p, PyObject *v, const formatdef *f) } static int -np_ubyte(char *p, PyObject *v, const formatdef *f) +np_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; if (x < 0 || x > 255) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "ubyte format requires 0 <= number <= 255"); return -1; } @@ -559,10 +570,10 @@ np_ubyte(char *p, PyObject *v, const formatdef *f) } static int -np_char(char *p, PyObject *v, const formatdef *f) +np_char(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "char format requires a bytes object of length 1"); return -1; } @@ -571,14 +582,14 @@ np_char(char *p, PyObject *v, const formatdef *f) } static int -np_short(char *p, PyObject *v, const formatdef *f) +np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; short y; - if (get_long(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; if (x < SHRT_MIN || x > SHRT_MAX) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "short format requires " Py_STRINGIFY(SHRT_MIN) " <= number <= " Py_STRINGIFY(SHRT_MAX)); return -1; @@ -589,14 +600,14 @@ np_short(char *p, PyObject *v, const formatdef *f) } static int -np_ushort(char *p, PyObject *v, const formatdef *f) +np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; unsigned short y; - if (get_long(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; if (x < 0 || x > USHRT_MAX) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "ushort format requires 0 <= number <= " Py_STRINGIFY(USHRT_MAX)); return -1; @@ -607,15 +618,15 @@ np_ushort(char *p, PyObject *v, const formatdef *f) } static int -np_int(char *p, PyObject *v, const formatdef *f) +np_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; int y; - if (get_long(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; #if (SIZEOF_LONG > SIZEOF_INT) if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX))) - RANGE_ERROR(x, f, 0, -1); + RANGE_ERROR(state, x, f, 0, -1); #endif y = (int)x; memcpy(p, (char *)&y, sizeof y); @@ -623,76 +634,76 @@ np_int(char *p, PyObject *v, const formatdef *f) } static int -np_uint(char *p, PyObject *v, const formatdef *f) +np_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long x; unsigned int y; - if (get_ulong(v, &x) < 0) + if (get_ulong(state, v, &x) < 0) return -1; y = (unsigned int)x; #if (SIZEOF_LONG > SIZEOF_INT) if (x > ((unsigned long)UINT_MAX)) - RANGE_ERROR(y, f, 1, -1); + RANGE_ERROR(state, y, f, 1, -1); #endif memcpy(p, (char *)&y, sizeof y); return 0; } static int -np_long(char *p, PyObject *v, const formatdef *f) +np_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); return 0; } static int -np_ulong(char *p, PyObject *v, const formatdef *f) +np_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long x; - if (get_ulong(v, &x) < 0) + if (get_ulong(state, v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); return 0; } static int -np_ssize_t(char *p, PyObject *v, const formatdef *f) +np_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { Py_ssize_t x; - if (get_ssize_t(v, &x) < 0) + if (get_ssize_t(state, v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); return 0; } static int -np_size_t(char *p, PyObject *v, const formatdef *f) +np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { size_t x; - if (get_size_t(v, &x) < 0) + if (get_size_t(state, v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); return 0; } static int -np_longlong(char *p, PyObject *v, const formatdef *f) +np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long long x; - if (get_longlong(v, &x) < 0) + if (get_longlong(state, v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); return 0; } static int -np_ulonglong(char *p, PyObject *v, const formatdef *f) +np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long long x; - if (get_ulonglong(v, &x) < 0) + if (get_ulonglong(state, v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); return 0; @@ -700,7 +711,7 @@ np_ulonglong(char *p, PyObject *v, const formatdef *f) static int -np_bool(char *p, PyObject *v, const formatdef *f) +np_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { int y; _Bool x; @@ -713,21 +724,21 @@ np_bool(char *p, PyObject *v, const formatdef *f) } static int -np_halffloat(char *p, PyObject *v, const formatdef *f) +np_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { #if PY_LITTLE_ENDIAN - return pack_halffloat(p, v, 1); + return pack_halffloat(state, p, v, 1); #else - return pack_halffloat(p, v, 0); + return pack_halffloat(state, p, v, 0); #endif } static int -np_float(char *p, PyObject *v, const formatdef *f) +np_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { float x = (float)PyFloat_AsDouble(v); if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not a float"); return -1; } @@ -736,11 +747,11 @@ np_float(char *p, PyObject *v, const formatdef *f) } static int -np_double(char *p, PyObject *v, const formatdef *f) +np_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { double x = PyFloat_AsDouble(v); if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not a float"); return -1; } @@ -749,11 +760,11 @@ np_double(char *p, PyObject *v, const formatdef *f) } static int -np_void_p(char *p, PyObject *v, const formatdef *f) +np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { void *x; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; assert(PyLong_Check(v)); @@ -793,7 +804,7 @@ static const formatdef native_table[] = { /* Big-endian routines. *****************************************************/ static PyObject * -bu_int(const char *p, const formatdef *f) +bu_int(_structmodulestate *state, const char *p, const formatdef *f) { long x = 0; Py_ssize_t i = f->size; @@ -808,7 +819,7 @@ bu_int(const char *p, const formatdef *f) } static PyObject * -bu_uint(const char *p, const formatdef *f) +bu_uint(_structmodulestate *state, const char *p, const formatdef *f) { unsigned long x = 0; Py_ssize_t i = f->size; @@ -820,7 +831,7 @@ bu_uint(const char *p, const formatdef *f) } static PyObject * -bu_longlong(const char *p, const formatdef *f) +bu_longlong(_structmodulestate *state, const char *p, const formatdef *f) { long long x = 0; Py_ssize_t i = f->size; @@ -835,7 +846,7 @@ bu_longlong(const char *p, const formatdef *f) } static PyObject * -bu_ulonglong(const char *p, const formatdef *f) +bu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) { unsigned long long x = 0; Py_ssize_t i = f->size; @@ -847,44 +858,44 @@ bu_ulonglong(const char *p, const formatdef *f) } static PyObject * -bu_halffloat(const char *p, const formatdef *f) +bu_halffloat(_structmodulestate *state, const char *p, const formatdef *f) { return unpack_halffloat(p, 0); } static PyObject * -bu_float(const char *p, const formatdef *f) +bu_float(_structmodulestate *state, const char *p, const formatdef *f) { return unpack_float(p, 0); } static PyObject * -bu_double(const char *p, const formatdef *f) +bu_double(_structmodulestate *state, const char *p, const formatdef *f) { return unpack_double(p, 0); } static PyObject * -bu_bool(const char *p, const formatdef *f) +bu_bool(_structmodulestate *state, const char *p, const formatdef *f) { return PyBool_FromLong(*p != 0); } static int -bp_int(char *p, PyObject *v, const formatdef *f) +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(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; i = f->size; if (i != SIZEOF_LONG) { if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(x, f, 0, 0xffffL); + RANGE_ERROR(state, x, f, 0, 0xffffL); #if (SIZEOF_LONG != 4) else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(x, f, 0, 0xffffffffL); + RANGE_ERROR(state, x, f, 0, 0xffffffffL); #endif } do { @@ -895,19 +906,19 @@ bp_int(char *p, PyObject *v, const formatdef *f) } static int -bp_uint(char *p, PyObject *v, const formatdef *f) +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(v, &x) < 0) + if (get_ulong(state, v, &x) < 0) return -1; i = f->size; if (i != SIZEOF_LONG) { unsigned long maxint = 1; maxint <<= (unsigned long)(i * 8); if (x >= maxint) - RANGE_ERROR(x, f, 1, maxint - 1); + RANGE_ERROR(state, x, f, 1, maxint - 1); } do { q[--i] = (unsigned char)(x & 0xffUL); @@ -917,10 +928,10 @@ bp_uint(char *p, PyObject *v, const formatdef *f) } static int -bp_longlong(char *p, PyObject *v, const formatdef *f) +bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { int res; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; res = _PyLong_AsByteArray((PyLongObject *)v, @@ -933,10 +944,10 @@ bp_longlong(char *p, PyObject *v, const formatdef *f) } static int -bp_ulonglong(char *p, PyObject *v, const formatdef *f) +bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { int res; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; res = _PyLong_AsByteArray((PyLongObject *)v, @@ -949,17 +960,17 @@ bp_ulonglong(char *p, PyObject *v, const formatdef *f) } static int -bp_halffloat(char *p, PyObject *v, const formatdef *f) +bp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { - return pack_halffloat(p, v, 0); + return pack_halffloat(state, p, v, 0); } static int -bp_float(char *p, PyObject *v, const formatdef *f) +bp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { double x = PyFloat_AsDouble(v); if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not a float"); return -1; } @@ -967,11 +978,11 @@ bp_float(char *p, PyObject *v, const formatdef *f) } static int -bp_double(char *p, PyObject *v, const formatdef *f) +bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { double x = PyFloat_AsDouble(v); if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not a float"); return -1; } @@ -979,7 +990,7 @@ bp_double(char *p, PyObject *v, const formatdef *f) } static int -bp_bool(char *p, PyObject *v, const formatdef *f) +bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { int y; y = PyObject_IsTrue(v); @@ -1014,7 +1025,7 @@ static formatdef bigendian_table[] = { /* Little-endian routines. *****************************************************/ static PyObject * -lu_int(const char *p, const formatdef *f) +lu_int(_structmodulestate *state, const char *p, const formatdef *f) { long x = 0; Py_ssize_t i = f->size; @@ -1029,7 +1040,7 @@ lu_int(const char *p, const formatdef *f) } static PyObject * -lu_uint(const char *p, const formatdef *f) +lu_uint(_structmodulestate *state, const char *p, const formatdef *f) { unsigned long x = 0; Py_ssize_t i = f->size; @@ -1041,7 +1052,7 @@ lu_uint(const char *p, const formatdef *f) } static PyObject * -lu_longlong(const char *p, const formatdef *f) +lu_longlong(_structmodulestate *state, const char *p, const formatdef *f) { long long x = 0; Py_ssize_t i = f->size; @@ -1056,7 +1067,7 @@ lu_longlong(const char *p, const formatdef *f) } static PyObject * -lu_ulonglong(const char *p, const formatdef *f) +lu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) { unsigned long long x = 0; Py_ssize_t i = f->size; @@ -1068,38 +1079,38 @@ lu_ulonglong(const char *p, const formatdef *f) } static PyObject * -lu_halffloat(const char *p, const formatdef *f) +lu_halffloat(_structmodulestate *state, const char *p, const formatdef *f) { return unpack_halffloat(p, 1); } static PyObject * -lu_float(const char *p, const formatdef *f) +lu_float(_structmodulestate *state, const char *p, const formatdef *f) { return unpack_float(p, 1); } static PyObject * -lu_double(const char *p, const formatdef *f) +lu_double(_structmodulestate *state, const char *p, const formatdef *f) { return unpack_double(p, 1); } static int -lp_int(char *p, PyObject *v, const formatdef *f) +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(v, &x) < 0) + if (get_long(state, v, &x) < 0) return -1; i = f->size; if (i != SIZEOF_LONG) { if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(x, f, 0, 0xffffL); + RANGE_ERROR(state, x, f, 0, 0xffffL); #if (SIZEOF_LONG != 4) else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(x, f, 0, 0xffffffffL); + RANGE_ERROR(state, x, f, 0, 0xffffffffL); #endif } do { @@ -1110,19 +1121,19 @@ lp_int(char *p, PyObject *v, const formatdef *f) } static int -lp_uint(char *p, PyObject *v, const formatdef *f) +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(v, &x) < 0) + if (get_ulong(state, v, &x) < 0) return -1; i = f->size; if (i != SIZEOF_LONG) { unsigned long maxint = 1; maxint <<= (unsigned long)(i * 8); if (x >= maxint) - RANGE_ERROR(x, f, 1, maxint - 1); + RANGE_ERROR(state, x, f, 1, maxint - 1); } do { *q++ = (unsigned char)(x & 0xffUL); @@ -1132,10 +1143,10 @@ lp_uint(char *p, PyObject *v, const formatdef *f) } static int -lp_longlong(char *p, PyObject *v, const formatdef *f) +lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { int res; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; res = _PyLong_AsByteArray((PyLongObject*)v, @@ -1148,10 +1159,10 @@ lp_longlong(char *p, PyObject *v, const formatdef *f) } static int -lp_ulonglong(char *p, PyObject *v, const formatdef *f) +lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { int res; - v = get_pylong(v); + v = get_pylong(state, v); if (v == NULL) return -1; res = _PyLong_AsByteArray((PyLongObject*)v, @@ -1164,17 +1175,17 @@ lp_ulonglong(char *p, PyObject *v, const formatdef *f) } static int -lp_halffloat(char *p, PyObject *v, const formatdef *f) +lp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { - return pack_halffloat(p, v, 1); + return pack_halffloat(state, p, v, 1); } static int -lp_float(char *p, PyObject *v, const formatdef *f) +lp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { double x = PyFloat_AsDouble(v); if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not a float"); return -1; } @@ -1182,11 +1193,11 @@ lp_float(char *p, PyObject *v, const formatdef *f) } static int -lp_double(char *p, PyObject *v, const formatdef *f) +lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { double x = PyFloat_AsDouble(v); if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "required argument is not a float"); return -1; } @@ -1246,14 +1257,14 @@ whichtable(const char **pfmt) /* Get the table entry for a format code */ static const formatdef * -getentry(int c, const formatdef *f) +getentry(_structmodulestate *state, int c, const formatdef *f) { for (; f->format != '\0'; f++) { if (f->format == c) { return f; } } - PyErr_SetString(_structmodulestate_global->StructError, "bad char in struct format"); + PyErr_SetString(state->StructError, "bad char in struct format"); return NULL; } @@ -1295,9 +1306,11 @@ prepare_s(PyStructObject *self) Py_ssize_t size, len, num, itemsize; size_t ncodes; + _structmodulestate *state = get_struct_state_structinst(self); + fmt = PyBytes_AS_STRING(self->s_format); if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "embedded null character"); return -1; } @@ -1323,7 +1336,7 @@ prepare_s(PyStructObject *self) num = num*10 + (c - '0'); } if (c == '\0') { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "repeat count given without format specifier"); return -1; } @@ -1331,7 +1344,7 @@ prepare_s(PyStructObject *self) else num = 1; - e = getentry(c, f); + e = getentry(state, c, f); if (e == NULL) return -1; @@ -1361,14 +1374,14 @@ prepare_s(PyStructObject *self) self->s_size = size; self->s_len = len; - codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode)); + codes = PyMem_Malloc((ncodes + 1) * sizeof(formatcode)); if (codes == NULL) { PyErr_NoMemory(); return -1; } /* Free any s_codes value left over from a previous initialization. */ if (self->s_codes != NULL) - PyMem_FREE(self->s_codes); + PyMem_Free(self->s_codes); self->s_codes = codes; s = fmt; @@ -1384,7 +1397,7 @@ prepare_s(PyStructObject *self) else num = 1; - e = getentry(c, f); + e = getentry(state, c, f); size = align(size, c, e); if (c == 's' || c == 'p') { @@ -1413,7 +1426,7 @@ prepare_s(PyStructObject *self) return 0; overflow: - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "total struct size too long"); return -1; } @@ -1430,8 +1443,7 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self = alloc_func(type, 0); if (self != NULL) { PyStructObject *s = (PyStructObject*)self; - Py_INCREF(Py_None); - s->s_format = Py_None; + s->s_format = Py_NewRef(Py_None); s->s_codes = NULL; s->s_size = -1; s->s_len = -1; @@ -1490,7 +1502,7 @@ s_dealloc(PyStructObject *s) if (s->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)s); if (s->s_codes != NULL) { - PyMem_FREE(s->s_codes); + PyMem_Free(s->s_codes); } Py_XDECREF(s->s_format); freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free); @@ -1499,7 +1511,8 @@ s_dealloc(PyStructObject *s) } static PyObject * -s_unpack_internal(PyStructObject *soself, const char *startfrom) { +s_unpack_internal(PyStructObject *soself, const char *startfrom, + _structmodulestate *state) { formatcode *code; Py_ssize_t i = 0; PyObject *result = PyTuple_New(soself->s_len); @@ -1520,7 +1533,7 @@ s_unpack_internal(PyStructObject *soself, const char *startfrom) { n = code->size - 1; v = PyBytes_FromStringAndSize(res + 1, n); } else { - v = e->unpack(res, e); + v = e->unpack(state, res, e); } if (v == NULL) goto fail; @@ -1554,14 +1567,15 @@ static PyObject * Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer) /*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/ { + _structmodulestate *state = get_struct_state_structinst(self); assert(self->s_codes != NULL); if (buffer->len != self->s_size) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "unpack requires a buffer of %zd bytes", self->s_size); return NULL; } - return s_unpack_internal(self, buffer->buf); + return s_unpack_internal(self, buffer->buf, state); } /*[clinic input] @@ -1585,11 +1599,12 @@ Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, Py_ssize_t offset) /*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/ { + _structmodulestate *state = get_struct_state_structinst(self); assert(self->s_codes != NULL); if (offset < 0) { if (offset + self->s_size > 0) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "not enough data to unpack %zd bytes at offset %zd", self->s_size, offset); @@ -1597,7 +1612,7 @@ Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, } if (offset + buffer->len < 0) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "offset %zd out of range for %zd-byte buffer", offset, buffer->len); @@ -1607,7 +1622,7 @@ Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, } if ((buffer->len - offset) < self->s_size) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "unpack_from requires a buffer of at least %zu bytes for " "unpacking %zd bytes at offset %zd " "(actual buffer size is %zd)", @@ -1617,7 +1632,7 @@ Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, buffer->len); return NULL; } - return s_unpack_internal(self, (char*)buffer->buf + offset); + return s_unpack_internal(self, (char*)buffer->buf + offset, state); } @@ -1671,6 +1686,7 @@ static PyMethodDef unpackiter_methods[] = { static PyObject * unpackiter_iternext(unpackiterobject *self) { + _structmodulestate *state = get_struct_state_iterinst(self); PyObject *result; if (self->so == NULL) return NULL; @@ -1682,7 +1698,8 @@ unpackiter_iternext(unpackiterobject *self) } assert(self->index + self->so->s_size <= self->buf.len); result = s_unpack_internal(self->so, - (char*) self->buf.buf + self->index); + (char*) self->buf.buf + self->index, + state); self->index += self->so->s_size; return result; } @@ -1729,17 +1746,18 @@ static PyObject * Struct_iter_unpack(PyStructObject *self, PyObject *buffer) /*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/ { + _structmodulestate *state = get_struct_state_structinst(self); unpackiterobject *iter; assert(self->s_codes != NULL); if (self->s_size == 0) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "cannot iteratively unpack with a struct of length 0"); return NULL; } - iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)_structmodulestate_global->unpackiter_type, 0); + iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)state->unpackiter_type, 0); if (iter == NULL) return NULL; @@ -1748,7 +1766,7 @@ Struct_iter_unpack(PyStructObject *self, PyObject *buffer) return NULL; } if (iter->buf.len % self->s_size != 0) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "iterative unpacking requires a buffer of " "a multiple of %zd bytes", self->s_size); @@ -1773,7 +1791,8 @@ Struct_iter_unpack(PyStructObject *self, PyObject *buffer) * */ static int -s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf) +s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, + char* buf, _structmodulestate *state) { formatcode *code; /* XXX(nnorwitz): why does i need to be a local? can we use @@ -1794,7 +1813,7 @@ s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* const void *p; isstring = PyBytes_Check(v); if (!isstring && !PyByteArray_Check(v)) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument for 's' must be a bytes object"); return -1; } @@ -1816,7 +1835,7 @@ s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* const void *p; isstring = PyBytes_Check(v); if (!isstring && !PyByteArray_Check(v)) { - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "argument for 'p' must be a bytes object"); return -1; } @@ -1836,9 +1855,9 @@ s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* n = 255; *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char); } else { - if (e->pack(res, v, e) < 0) { + if (e->pack(state, res, v, e) < 0) { if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(_structmodulestate_global->StructError, + PyErr_SetString(state->StructError, "int too large to convert"); return -1; } @@ -1864,14 +1883,15 @@ s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { char *buf; PyStructObject *soself; + _structmodulestate *state = get_struct_state_structinst(self); /* Validate arguments. */ soself = (PyStructObject *)self; - assert(PyStruct_Check(self)); + assert(PyStruct_Check(self, state)); assert(soself->s_codes != NULL); if (nargs != soself->s_len) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "pack expected %zd items for packing (got %zd)", soself->s_len, nargs); return NULL; } @@ -1886,7 +1906,7 @@ s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } /* Call the guts */ - if ( s_pack_internal(soself, args, 0, buf) != 0 ) { + if ( s_pack_internal(soself, args, 0, buf, state) != 0 ) { _PyBytesWriter_Dealloc(&writer); return NULL; } @@ -1908,23 +1928,24 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) PyStructObject *soself; Py_buffer buffer; Py_ssize_t offset; + _structmodulestate *state = get_struct_state_structinst(self); /* Validate arguments. +1 is for the first arg as buffer. */ soself = (PyStructObject *)self; - assert(PyStruct_Check(self)); + assert(PyStruct_Check(self, state)); assert(soself->s_codes != NULL); if (nargs != (soself->s_len + 2)) { if (nargs == 0) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "pack_into expected buffer argument"); } else if (nargs == 1) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "pack_into expected offset argument"); } else { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "pack_into expected %zd items for packing (got %zd)", soself->s_len, (nargs - 2)); } @@ -1947,7 +1968,7 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (offset < 0) { /* Check that negative offset is low enough to fit data */ if (offset + soself->s_size > 0) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "no space to pack %zd bytes at offset %zd", soself->s_size, offset); @@ -1957,7 +1978,7 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) /* Check that negative offset is not crossing buffer boundary */ if (offset + buffer.len < 0) { - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "offset %zd out of range for %zd-byte buffer", offset, buffer.len); @@ -1973,7 +1994,7 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) assert(offset >= 0); assert(soself->s_size >= 0); - PyErr_Format(_structmodulestate_global->StructError, + PyErr_Format(state->StructError, "pack_into requires a buffer of at least %zu bytes for " "packing %zd bytes at offset %zd " "(actual buffer size is %zd)", @@ -1986,7 +2007,7 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } /* Call the guts */ - if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) { + if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset, state) != 0) { PyBuffer_Release(&buffer); return NULL; } @@ -2080,12 +2101,12 @@ static PyType_Spec PyStructType_spec = { /* ---- Standalone functions ---- */ #define MAXCACHE 100 -static PyObject *cache = NULL; static int -cache_struct_converter(PyObject *fmt, PyStructObject **ptr) +cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr) { PyObject * s_object; + _structmodulestate *state = get_struct_state(module); if (fmt == NULL) { Py_DECREF(*ptr); @@ -2093,13 +2114,13 @@ cache_struct_converter(PyObject *fmt, PyStructObject **ptr) return 1; } - if (cache == NULL) { - cache = PyDict_New(); - if (cache == NULL) + if (state->cache == NULL) { + state->cache = PyDict_New(); + if (state->cache == NULL) return 0; } - s_object = PyDict_GetItemWithError(cache, fmt); + s_object = PyDict_GetItemWithError(state->cache, fmt); if (s_object != NULL) { Py_INCREF(s_object); *ptr = (PyStructObject *)s_object; @@ -2109,12 +2130,12 @@ cache_struct_converter(PyObject *fmt, PyStructObject **ptr) return 0; } - s_object = PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt); + s_object = PyObject_CallOneArg(state->PyStructType, fmt); if (s_object != NULL) { - if (PyDict_GET_SIZE(cache) >= MAXCACHE) - PyDict_Clear(cache); + if (PyDict_GET_SIZE(state->cache) >= MAXCACHE) + PyDict_Clear(state->cache); /* Attempt to cache the result */ - if (PyDict_SetItem(cache, fmt, s_object) == -1) + if (PyDict_SetItem(state->cache, fmt, s_object) == -1) PyErr_Clear(); *ptr = (PyStructObject *)s_object; return Py_CLEANUP_SUPPORTED; @@ -2132,7 +2153,7 @@ static PyObject * _clearcache_impl(PyObject *module) /*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/ { - Py_CLEAR(cache); + Py_CLEAR(get_struct_state(module)->cache); Py_RETURN_NONE; } @@ -2160,7 +2181,7 @@ Return a bytes object containing the values v1, v2, ... packed according\n\ to the format string. See help(struct) for more on format strings."); static PyObject * -pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *s_object = NULL; PyObject *format, *result; @@ -2171,7 +2192,7 @@ pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } format = args[0]; - if (!cache_struct_converter(format, (PyStructObject **)&s_object)) { + if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) { return NULL; } result = s_pack(s_object, args + 1, nargs - 1); @@ -2188,7 +2209,7 @@ that the offset is a required argument. See help(struct) for more\n\ on format strings."); static PyObject * -pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +pack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *s_object = NULL; PyObject *format, *result; @@ -2199,7 +2220,7 @@ pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } format = args[0]; - if (!cache_struct_converter(format, (PyStructObject **)&s_object)) { + if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) { return NULL; } result = s_pack_into(s_object, args + 1, nargs - 1); @@ -2322,8 +2343,9 @@ The variable struct.error is an exception raised on errors.\n"); static int _structmodule_traverse(PyObject *module, visitproc visit, void *arg) { - _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module); + _structmodulestate *state = get_struct_state(module); if (state) { + Py_VISIT(state->cache); Py_VISIT(state->PyStructType); Py_VISIT(state->unpackiter_type); Py_VISIT(state->StructError); @@ -2334,8 +2356,9 @@ _structmodule_traverse(PyObject *module, visitproc visit, void *arg) static int _structmodule_clear(PyObject *module) { - _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module); + _structmodulestate *state = get_struct_state(module); if (state) { + Py_CLEAR(state->cache); Py_CLEAR(state->PyStructType); Py_CLEAR(state->unpackiter_type); Py_CLEAR(state->StructError); @@ -2349,40 +2372,25 @@ _structmodule_free(void *module) _structmodule_clear((PyObject *)module); } -static struct PyModuleDef _structmodule = { - PyModuleDef_HEAD_INIT, - "_struct", - module_doc, - sizeof(_structmodulestate), - module_functions, - NULL, - _structmodule_traverse, - _structmodule_clear, - _structmodule_free, -}; - -PyMODINIT_FUNC -PyInit__struct(void) +static int +_structmodule_exec(PyObject *m) { - PyObject *m; + _structmodulestate *state = get_struct_state(m); - m = PyModule_Create(&_structmodule); - if (m == NULL) - return NULL; - - PyObject *PyStructType = PyType_FromSpec(&PyStructType_spec); - if (PyStructType == NULL) { - return NULL; + state->PyStructType = PyType_FromModuleAndSpec( + m, &PyStructType_spec, NULL); + if (state->PyStructType == NULL) { + return -1; + } + if (PyModule_AddType(m, (PyTypeObject *)state->PyStructType) < 0) { + return -1; } - Py_INCREF(PyStructType); - PyModule_AddObject(m, "Struct", PyStructType); - get_struct_state(m)->PyStructType = PyStructType; - PyObject *unpackiter_type = PyType_FromSpec(&unpackiter_type_spec); - if (unpackiter_type == NULL) { - return NULL; + state->unpackiter_type = PyType_FromModuleAndSpec( + m, &unpackiter_type_spec, NULL); + if (state->unpackiter_type == NULL) { + return -1; } - get_struct_state(m)->unpackiter_type = unpackiter_type; /* Check endian and swap in faster functions */ { @@ -2427,12 +2435,36 @@ PyInit__struct(void) } /* Add some symbolic constants to the module */ - PyObject *StructError = PyErr_NewException("struct.error", NULL, NULL); - if (StructError == NULL) - return NULL; - Py_INCREF(StructError); - PyModule_AddObject(m, "error", StructError); - get_struct_state(m)->StructError = StructError; + state->StructError = PyErr_NewException("struct.error", NULL, NULL); + if (state->StructError == NULL) { + return -1; + } + if (PyModule_AddObjectRef(m, "error", state->StructError) < 0) { + return -1; + } + + return 0; +} - return m; +static PyModuleDef_Slot _structmodule_slots[] = { + {Py_mod_exec, _structmodule_exec}, + {0, NULL} +}; + +static struct PyModuleDef _structmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_struct", + .m_doc = module_doc, + .m_size = sizeof(_structmodulestate), + .m_methods = module_functions, + .m_slots = _structmodule_slots, + .m_traverse = _structmodule_traverse, + .m_clear = _structmodule_clear, + .m_free = _structmodule_free, +}; + +PyMODINIT_FUNC +PyInit__struct(void) +{ + return PyModuleDef_Init(&_structmodule); } diff --git a/contrib/tools/python3/src/Modules/_threadmodule.c b/contrib/tools/python3/src/Modules/_threadmodule.c index a370352238d..813d7ec232c 100644 --- a/contrib/tools/python3/src/Modules/_threadmodule.c +++ b/contrib/tools/python3/src/Modules/_threadmodule.c @@ -3,17 +3,45 @@ /* Interface to Sjoerd's portable C thread library */ #include "Python.h" -#include "pycore_pylifecycle.h" #include "pycore_interp.h" // _PyInterpreterState.num_threads +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_pylifecycle.h" #include "pycore_pystate.h" // _PyThreadState_Init() #include // offsetof() +#include "structmember.h" // PyMemberDef + +#ifdef HAVE_SIGNAL_H +# include // SIGINT +#endif -static PyObject *ThreadError; -static PyObject *str_dict; +// ThreadError is just an alias to PyExc_RuntimeError +#define ThreadError PyExc_RuntimeError + +_Py_IDENTIFIER(__dict__); _Py_IDENTIFIER(stderr); _Py_IDENTIFIER(flush); + +// Forward declarations +static struct PyModuleDef thread_module; + + +typedef struct { + PyTypeObject *lock_type; + PyTypeObject *local_type; + PyTypeObject *local_dummy_type; +} thread_module_state; + +static inline thread_module_state* +get_thread_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (thread_module_state *)state; +} + + /* Lock objects */ typedef struct { @@ -23,18 +51,28 @@ typedef struct { char locked; /* for sanity checking */ } lockobject; +static int +lock_traverse(lockobject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static void lock_dealloc(lockobject *self) { - if (self->in_weakreflist != NULL) + if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); + } if (self->lock_lock != NULL) { /* Unlock the lock so it's safe to free it */ if (self->locked) PyThread_release_lock(self->lock_lock); PyThread_free_lock(self->lock_lock); } - PyObject_Del(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free((PyObject*)self); + Py_DECREF(tp); } /* Helper to acquire an interruptible lock with a timeout. If the lock acquire @@ -48,12 +86,13 @@ acquire_timed(PyThread_type_lock lock, _PyTime_t timeout) { PyLockStatus r; _PyTime_t endtime = 0; - _PyTime_t microseconds; - if (timeout > 0) + if (timeout > 0) { endtime = _PyTime_GetMonotonicClock() + timeout; + } do { + _PyTime_t microseconds; microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING); /* first a simple non-blocking try without releasing the GIL */ @@ -138,12 +177,10 @@ static PyObject * lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds) { _PyTime_t timeout; - PyLockStatus r; - if (lock_acquire_parse_args(args, kwds, &timeout) < 0) return NULL; - r = acquire_timed(self->lock_lock, timeout); + PyLockStatus r = acquire_timed(self->lock_lock, timeout); if (r == PY_LOCK_INTR) { return NULL; } @@ -245,36 +282,39 @@ static PyMethodDef lock_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject Locktype = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_thread.lock", /*tp_name*/ - sizeof(lockobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)lock_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)lock_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*/ - offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - lock_methods, /*tp_methods*/ +PyDoc_STRVAR(lock_doc, +"A lock object is a synchronization primitive. To create a lock,\n\ +call threading.Lock(). Methods are:\n\ +\n\ +acquire() -- lock the lock, possibly blocking until it can be obtained\n\ +release() -- unlock of the lock\n\ +locked() -- test whether the lock is currently locked\n\ +\n\ +A lock is not owned by the thread that locked it; another thread may\n\ +unlock it. A thread attempting to lock a lock that it has already locked\n\ +will block until another thread unlocks it. Deadlocks may ensue."); + +static PyMemberDef lock_type_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(lockobject, in_weakreflist), READONLY}, + {NULL}, +}; + +static PyType_Slot lock_type_slots[] = { + {Py_tp_dealloc, (destructor)lock_dealloc}, + {Py_tp_repr, (reprfunc)lock_repr}, + {Py_tp_doc, (void *)lock_doc}, + {Py_tp_methods, lock_methods}, + {Py_tp_traverse, lock_traverse}, + {Py_tp_members, lock_type_members}, + {0, 0} +}; + +static PyType_Spec lock_type_spec = { + .name = "_thread.lock", + .basicsize = sizeof(lockobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = lock_type_slots, }; /* Recursive lock objects */ @@ -287,6 +327,14 @@ typedef struct { PyObject *in_weakreflist; } rlockobject; +static int +rlock_traverse(rlockobject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + + static void rlock_dealloc(rlockobject *self) { @@ -301,7 +349,9 @@ rlock_dealloc(rlockobject *self) PyThread_free_lock(self->rlock_lock); } - Py_TYPE(self)->tp_free(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + Py_DECREF(tp); } static PyObject * @@ -525,58 +575,45 @@ static PyMethodDef rlock_methods[] = { }; -static PyTypeObject RLocktype = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_thread.RLock", /*tp_name*/ - sizeof(rlockobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)rlock_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)rlock_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, /* tp_flags */ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - rlock_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 */ - PyType_GenericAlloc, /* tp_alloc */ - rlock_new /* tp_new */ +static PyMemberDef rlock_type_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(rlockobject, in_weakreflist), READONLY}, + {NULL}, +}; + +static PyType_Slot rlock_type_slots[] = { + {Py_tp_dealloc, (destructor)rlock_dealloc}, + {Py_tp_repr, (reprfunc)rlock_repr}, + {Py_tp_methods, rlock_methods}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, rlock_new}, + {Py_tp_members, rlock_type_members}, + {Py_tp_traverse, rlock_traverse}, + {0, 0}, +}; + +static PyType_Spec rlock_type_spec = { + .name = "_thread.RLock", + .basicsize = sizeof(rlockobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = rlock_type_slots, }; static lockobject * -newlockobject(void) +newlockobject(PyObject *module) { - lockobject *self; - self = PyObject_New(lockobject, &Locktype); - if (self == NULL) + thread_module_state *state = get_thread_state(module); + + PyTypeObject *type = state->lock_type; + lockobject *self = (lockobject *)type->tp_alloc(type, 0); + if (self == NULL) { return NULL; + } + self->lock_lock = PyThread_allocate_lock(); self->locked = 0; self->in_weakreflist = NULL; + if (self->lock_lock == NULL) { Py_DECREF(self); PyErr_SetString(ThreadError, "can't allocate lock"); @@ -637,35 +674,29 @@ localdummy_dealloc(localdummyobject *self) { if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free((PyObject*)self); + Py_DECREF(tp); } -static PyTypeObject localdummytype = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_thread._localdummy", - /* tp_basicsize */ sizeof(localdummyobject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor)localdummy_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, - /* tp_doc */ "Thread-local dummy", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist) +static PyMemberDef local_dummy_type_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(localdummyobject, weakreflist), READONLY}, + {NULL}, +}; + +static PyType_Slot local_dummy_type_slots[] = { + {Py_tp_dealloc, (destructor)localdummy_dealloc}, + {Py_tp_doc, "Thread-local dummy"}, + {Py_tp_members, local_dummy_type_members}, + {0, 0} +}; + +static PyType_Spec local_dummy_type_spec = { + .name = "_thread._localdummy", + .basicsize = sizeof(localdummyobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = local_dummy_type_slots, }; @@ -682,19 +713,19 @@ typedef struct { } localobject; /* Forward declaration */ -static PyObject *_ldict(localobject *self); +static PyObject *_ldict(localobject *self, thread_module_state *state); static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref); /* Create and register the dummy for the current thread. Returns a borrowed reference of the corresponding local dict */ static PyObject * -_local_create_dummy(localobject *self) +_local_create_dummy(localobject *self, thread_module_state *state) { - PyObject *tdict, *ldict = NULL, *wr = NULL; + PyObject *ldict = NULL, *wr = NULL; localdummyobject *dummy = NULL; - int r; + PyTypeObject *type = state->local_dummy_type; - tdict = PyThreadState_GetDict(); + PyObject *tdict = PyThreadState_GetDict(); if (tdict == NULL) { PyErr_SetString(PyExc_SystemError, "Couldn't get thread-state dictionary"); @@ -702,25 +733,30 @@ _local_create_dummy(localobject *self) } ldict = PyDict_New(); - if (ldict == NULL) + if (ldict == NULL) { goto err; - dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0); - if (dummy == NULL) + } + dummy = (localdummyobject *) type->tp_alloc(type, 0); + if (dummy == NULL) { goto err; + } dummy->localdict = ldict; wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback); - if (wr == NULL) + if (wr == NULL) { goto err; + } /* As a side-effect, this will cache the weakref's hash before the dummy gets deleted */ - r = PyDict_SetItem(self->dummies, wr, ldict); - if (r < 0) + int r = PyDict_SetItem(self->dummies, wr, ldict); + if (r < 0) { goto err; + } Py_CLEAR(wr); r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy); - if (r < 0) + if (r < 0) { goto err; + } Py_CLEAR(dummy); Py_DECREF(ldict); @@ -736,8 +772,6 @@ err: static PyObject * local_new(PyTypeObject *type, PyObject *args, PyObject *kw) { - localobject *self; - PyObject *wr; static PyMethodDef wr_callback_def = { "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O }; @@ -749,42 +783,48 @@ local_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (rc == 0 && kw != NULL) rc = PyObject_IsTrue(kw); if (rc != 0) { - if (rc > 0) + if (rc > 0) { PyErr_SetString(PyExc_TypeError, "Initialization arguments are not supported"); + } return NULL; } } - self = (localobject *)type->tp_alloc(type, 0); - if (self == NULL) + PyObject *module = _PyType_GetModuleByDef(type, &thread_module); + thread_module_state *state = get_thread_state(module); + + localobject *self = (localobject *)type->tp_alloc(type, 0); + if (self == NULL) { return NULL; + } - Py_XINCREF(args); - self->args = args; - Py_XINCREF(kw); - self->kw = kw; + self->args = Py_XNewRef(args); + self->kw = Py_XNewRef(kw); self->key = PyUnicode_FromFormat("thread.local.%p", self); - if (self->key == NULL) + if (self->key == NULL) { goto err; + } self->dummies = PyDict_New(); - if (self->dummies == NULL) + if (self->dummies == NULL) { goto err; + } /* We use a weak reference to self in the callback closure in order to avoid spurious reference cycles */ - wr = PyWeakref_NewRef((PyObject *) self, NULL); - if (wr == NULL) + PyObject *wr = PyWeakref_NewRef((PyObject *) self, NULL); + if (wr == NULL) { goto err; + } self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL); Py_DECREF(wr); - if (self->wr_callback == NULL) + if (self->wr_callback == NULL) { goto err; - - if (_local_create_dummy(self) == NULL) + } + if (_local_create_dummy(self, state) == NULL) { goto err; - + } return (PyObject *)self; err: @@ -795,6 +835,7 @@ local_new(PyTypeObject *type, PyObject *args, PyObject *kw) static int local_traverse(localobject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->args); Py_VISIT(self->kw); Py_VISIT(self->dummies); @@ -804,23 +845,26 @@ local_traverse(localobject *self, visitproc visit, void *arg) static int local_clear(localobject *self) { - PyThreadState *tstate; Py_CLEAR(self->args); Py_CLEAR(self->kw); Py_CLEAR(self->dummies); Py_CLEAR(self->wr_callback); /* Remove all strong references to dummies from the thread states */ - if (self->key - && (tstate = PyThreadState_Get()) - && tstate->interp) { - for(tstate = PyInterpreterState_ThreadHead(tstate->interp); - tstate; - tstate = PyThreadState_Next(tstate)) - if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) { - if (PyDict_DelItem(tstate->dict, self->key)) { - PyErr_Clear(); - } + if (self->key) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + for(; tstate; tstate = PyThreadState_Next(tstate)) { + if (tstate->dict == NULL) { + continue; + } + PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None); + if (v != NULL) { + Py_DECREF(v); + } + else { + PyErr_Clear(); } + } } return 0; } @@ -830,35 +874,38 @@ local_dealloc(localobject *self) { /* Weakrefs must be invalidated right now, otherwise they can be used from code called below, which is very dangerous since Py_REFCNT(self) == 0 */ - if (self->weakreflist != NULL) + if (self->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); + } PyObject_GC_UnTrack(self); local_clear(self); Py_XDECREF(self->key); - Py_TYPE(self)->tp_free((PyObject*)self); + + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free((PyObject*)self); + Py_DECREF(tp); } /* Returns a borrowed reference to the local dict, creating it if necessary */ static PyObject * -_ldict(localobject *self) +_ldict(localobject *self, thread_module_state *state) { - PyObject *tdict, *ldict, *dummy; - - tdict = PyThreadState_GetDict(); + PyObject *tdict = PyThreadState_GetDict(); if (tdict == NULL) { PyErr_SetString(PyExc_SystemError, "Couldn't get thread-state dictionary"); return NULL; } - dummy = PyDict_GetItemWithError(tdict, self->key); + PyObject *ldict; + PyObject *dummy = PyDict_GetItemWithError(tdict, self->key); if (dummy == NULL) { if (PyErr_Occurred()) { return NULL; } - ldict = _local_create_dummy(self); + ldict = _local_create_dummy(self, state); if (ldict == NULL) return NULL; @@ -873,7 +920,7 @@ _ldict(localobject *self) } } else { - assert(Py_IS_TYPE(dummy, &localdummytype)); + assert(Py_IS_TYPE(dummy, state->local_dummy_type)); ldict = ((localdummyobject *) dummy)->localdict; } @@ -883,104 +930,98 @@ _ldict(localobject *self) static int local_setattro(localobject *self, PyObject *name, PyObject *v) { - PyObject *ldict; - int r; + PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + thread_module_state *state = get_thread_state(module); - ldict = _ldict(self); - if (ldict == NULL) + PyObject *ldict = _ldict(self, state); + if (ldict == NULL) { return -1; + } - r = PyObject_RichCompareBool(name, str_dict, Py_EQ); + PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref + if (str_dict == NULL) { + return -1; + } + + int r = PyObject_RichCompareBool(name, str_dict, Py_EQ); + if (r == -1) { + return -1; + } if (r == 1) { PyErr_Format(PyExc_AttributeError, "'%.50s' object attribute '%U' is read-only", Py_TYPE(self)->tp_name, name); return -1; } - if (r == -1) - return -1; return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict); } static PyObject *local_getattro(localobject *, PyObject *); -static PyTypeObject localtype = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_thread._local", - /* tp_basicsize */ sizeof(localobject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor)local_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 */ (getattrofunc)local_getattro, - /* tp_setattro */ (setattrofunc)local_setattro, - /* tp_as_buffer */ 0, - /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, - /* tp_doc */ "Thread-local data", - /* tp_traverse */ (traverseproc)local_traverse, - /* tp_clear */ (inquiry)local_clear, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ offsetof(localobject, weakreflist), - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ 0, - /* tp_members */ 0, - /* tp_getset */ 0, - /* tp_base */ 0, - /* tp_dict */ 0, /* internal use */ - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ local_new, - /* tp_free */ 0, /* Low-level free-mem routine */ - /* tp_is_gc */ 0, /* For PyObject_IS_GC */ +static PyMemberDef local_type_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(localobject, weakreflist), READONLY}, + {NULL}, +}; + +static PyType_Slot local_type_slots[] = { + {Py_tp_dealloc, (destructor)local_dealloc}, + {Py_tp_getattro, (getattrofunc)local_getattro}, + {Py_tp_setattro, (setattrofunc)local_setattro}, + {Py_tp_doc, "Thread-local data"}, + {Py_tp_traverse, (traverseproc)local_traverse}, + {Py_tp_clear, (inquiry)local_clear}, + {Py_tp_new, local_new}, + {Py_tp_members, local_type_members}, + {0, 0} +}; + +static PyType_Spec local_type_spec = { + .name = "_thread._local", + .basicsize = sizeof(localobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = local_type_slots, }; static PyObject * local_getattro(localobject *self, PyObject *name) { - PyObject *ldict, *value; - int r; + PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + thread_module_state *state = get_thread_state(module); - ldict = _ldict(self); + PyObject *ldict = _ldict(self, state); if (ldict == NULL) return NULL; - r = PyObject_RichCompareBool(name, str_dict, Py_EQ); + PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref + if (str_dict == NULL) { + return NULL; + } + + int r = PyObject_RichCompareBool(name, str_dict, Py_EQ); if (r == 1) { - Py_INCREF(ldict); - return ldict; + return Py_NewRef(ldict); } - if (r == -1) + if (r == -1) { return NULL; + } - if (!Py_IS_TYPE(self, &localtype)) + if (!Py_IS_TYPE(self, state->local_type)) { /* use generic lookup for subtypes */ - return _PyObject_GenericGetAttrWithDict( - (PyObject *)self, name, ldict, 0); + return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, + ldict, 0); + } /* Optimization: just look in dict ourselves */ - value = PyDict_GetItemWithError(ldict, name); + PyObject *value = PyDict_GetItemWithError(ldict, name); if (value != NULL) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } - else if (PyErr_Occurred()) { + if (PyErr_Occurred()) { return NULL; } + /* Fall back on generic to get __class__ and __dict__ */ return _PyObject_GenericGetAttrWithDict( (PyObject *)self, name, ldict, 0); @@ -990,17 +1031,15 @@ local_getattro(localobject *self, PyObject *name) static PyObject * _localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref) { - PyObject *obj; - localobject *self; assert(PyWeakref_CheckRef(localweakref)); - obj = PyWeakref_GET_OBJECT(localweakref); - if (obj == Py_None) + PyObject *obj = PyWeakref_GET_OBJECT(localweakref); + if (obj == Py_None) { Py_RETURN_NONE; - Py_INCREF(obj); - assert(PyObject_TypeCheck(obj, &localtype)); + } + /* If the thread-local object is still alive and not being cleared, remove the corresponding local dict */ - self = (localobject *) obj; + localobject *self = (localobject *)Py_NewRef(obj); if (self->dummies != NULL) { PyObject *ldict; ldict = PyDict_GetItemWithError(self->dummies, dummyweakref); @@ -1020,24 +1059,35 @@ struct bootstate { PyInterpreterState *interp; PyObject *func; PyObject *args; - PyObject *keyw; + PyObject *kwargs; PyThreadState *tstate; _PyRuntimeState *runtime; }; + +static void +thread_bootstate_free(struct bootstate *boot) +{ + Py_DECREF(boot->func); + Py_DECREF(boot->args); + Py_XDECREF(boot->kwargs); + PyMem_Free(boot); +} + + static void -t_bootstrap(void *boot_raw) +thread_run(void *boot_raw) { struct bootstate *boot = (struct bootstate *) boot_raw; PyThreadState *tstate; - PyObject *res; tstate = boot->tstate; tstate->thread_id = PyThread_get_thread_ident(); _PyThreadState_Init(tstate); PyEval_AcquireThread(tstate); tstate->interp->num_threads++; - res = PyObject_Call(boot->func, boot->args, boot->keyw); + + PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs); if (res == NULL) { if (PyErr_ExceptionMatches(PyExc_SystemExit)) /* SystemExit is ignored silently */ @@ -1049,10 +1099,8 @@ t_bootstrap(void *boot_raw) else { Py_DECREF(res); } - Py_DECREF(boot->func); - Py_DECREF(boot->args); - Py_XDECREF(boot->keyw); - PyMem_DEL(boot_raw); + + thread_bootstate_free(boot); tstate->interp->num_threads--; PyThreadState_Clear(tstate); _PyThreadState_DeleteCurrent(tstate); @@ -1066,12 +1114,10 @@ static PyObject * thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) { _PyRuntimeState *runtime = &_PyRuntime; - PyObject *func, *args, *keyw = NULL; - struct bootstate *boot; - unsigned long ident; + PyObject *func, *args, *kwargs = NULL; if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, - &func, &args, &keyw)) + &func, &args, &kwargs)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, @@ -1083,7 +1129,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) "2nd arg must be a tuple"); return NULL; } - if (keyw != NULL && !PyDict_Check(keyw)) { + if (kwargs != NULL && !PyDict_Check(kwargs)) { PyErr_SetString(PyExc_TypeError, "optional 3rd arg must be a dictionary"); return NULL; @@ -1096,31 +1142,26 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) return NULL; } - boot = PyMem_NEW(struct bootstate, 1); - if (boot == NULL) + struct bootstate *boot = PyMem_NEW(struct bootstate, 1); + if (boot == NULL) { return PyErr_NoMemory(); + } boot->interp = _PyInterpreterState_GET(); - boot->func = func; - boot->args = args; - boot->keyw = keyw; boot->tstate = _PyThreadState_Prealloc(boot->interp); - boot->runtime = runtime; if (boot->tstate == NULL) { - PyMem_DEL(boot); + PyMem_Free(boot); return PyErr_NoMemory(); } - Py_INCREF(func); - Py_INCREF(args); - Py_XINCREF(keyw); + boot->runtime = runtime; + boot->func = Py_NewRef(func); + boot->args = Py_NewRef(args); + boot->kwargs = Py_XNewRef(kwargs); - ident = PyThread_start_new_thread(t_bootstrap, (void*) boot); + unsigned long ident = PyThread_start_new_thread(thread_run, (void*) boot); if (ident == PYTHREAD_INVALID_THREAD_ID) { PyErr_SetString(ThreadError, "can't start new thread"); - Py_DECREF(func); - Py_DECREF(args); - Py_XDECREF(keyw); PyThreadState_Clear(boot->tstate); - PyMem_DEL(boot); + thread_bootstate_free(boot); return NULL; } return PyLong_FromUnsignedLong(ident); @@ -1152,25 +1193,37 @@ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); static PyObject * -thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored)) +thread_PyThread_interrupt_main(PyObject *self, PyObject *args) { - PyErr_SetInterrupt(); + int signum = SIGINT; + if (!PyArg_ParseTuple(args, "|i:signum", &signum)) { + return NULL; + } + + if (PyErr_SetInterruptEx(signum)) { + PyErr_SetString(PyExc_ValueError, "signal number out of range"); + return NULL; + } Py_RETURN_NONE; } PyDoc_STRVAR(interrupt_doc, -"interrupt_main()\n\ +"interrupt_main(signum=signal.SIGINT, /)\n\ \n\ -Raise a KeyboardInterrupt in the main thread.\n\ -A subthread can use this function to interrupt the main thread." +Simulate the arrival of the given signal in the main thread,\n\ +where the corresponding signal handler will be executed.\n\ +If *signum* is omitted, SIGINT is assumed.\n\ +A subthread can use this function to interrupt the main thread.\n\ +\n\ +Note: the default signal handler for SIGINT raises ``KeyboardInterrupt``." ); -static lockobject *newlockobject(void); +static lockobject *newlockobject(PyObject *module); static PyObject * -thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored)) +thread_PyThread_allocate_lock(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return (PyObject *) newlockobject(); + return (PyObject *) newlockobject(module); } PyDoc_STRVAR(allocate_doc, @@ -1247,7 +1300,6 @@ release_sentinel(void *wr_raw) PyObject *obj = PyWeakref_GET_OBJECT(wr); lockobject *lock; if (obj != Py_None) { - assert(Py_IS_TYPE(obj, &Locktype)); lock = (lockobject *) obj; if (lock->locked) { PyThread_release_lock(lock->lock_lock); @@ -1260,7 +1312,7 @@ release_sentinel(void *wr_raw) } static PyObject * -thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored)) +thread__set_sentinel(PyObject *module, PyObject *Py_UNUSED(ignored)) { PyObject *wr; PyThreadState *tstate = PyThreadState_Get(); @@ -1275,7 +1327,7 @@ thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored)) tstate->on_delete_data = NULL; Py_DECREF(wr); } - lock = newlockobject(); + lock = newlockobject(module); if (lock == NULL) return NULL; /* The lock is owned by whoever called _set_sentinel(), but the weakref @@ -1428,7 +1480,7 @@ static PyStructSequence_Field ExceptHookArgs_fields[] = { }; static PyStructSequence_Desc ExceptHookArgs_desc = { - .name = "_thread.ExceptHookArgs", + .name = "_thread._ExceptHookArgs", .doc = ExceptHookArgs__doc__, .fields = ExceptHookArgs_fields, .n_in_sequence = 4 @@ -1507,8 +1559,8 @@ static PyMethodDef thread_methods[] = { METH_NOARGS, exit_doc}, {"exit", thread_PyThread_exit_thread, METH_NOARGS, exit_doc}, - {"interrupt_main", thread_PyThread_interrupt_main, - METH_NOARGS, interrupt_doc}, + {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main, + METH_VARARGS, interrupt_doc}, {"get_ident", thread_get_ident, METH_NOARGS, get_ident_doc}, #ifdef PY_HAVE_THREAD_NATIVE_ID @@ -1529,106 +1581,132 @@ static PyMethodDef thread_methods[] = { /* Initialization function */ -PyDoc_STRVAR(thread_doc, -"This module provides primitive operations to write multi-threaded programs.\n\ -The 'threading' module provides a more convenient interface."); +static int +thread_module_exec(PyObject *module) +{ + thread_module_state *state = get_thread_state(module); + PyObject *d = PyModule_GetDict(module); -PyDoc_STRVAR(lock_doc, -"A lock object is a synchronization primitive. To create a lock,\n\ -call threading.Lock(). Methods are:\n\ -\n\ -acquire() -- lock the lock, possibly blocking until it can be obtained\n\ -release() -- unlock of the lock\n\ -locked() -- test whether the lock is currently locked\n\ -\n\ -A lock is not owned by the thread that locked it; another thread may\n\ -unlock it. A thread attempting to lock a lock that it has already locked\n\ -will block until another thread unlocks it. Deadlocks may ensue."); + // Initialize the C thread library + PyThread_init_thread(); -static struct PyModuleDef threadmodule = { - PyModuleDef_HEAD_INIT, - "_thread", - thread_doc, - -1, - thread_methods, - NULL, - NULL, - NULL, - NULL -}; + // Lock + state->lock_type = (PyTypeObject *)PyType_FromSpec(&lock_type_spec); + if (state->lock_type == NULL) { + return -1; + } + if (PyDict_SetItemString(d, "LockType", (PyObject *)state->lock_type) < 0) { + return -1; + } + // RLock + PyTypeObject *rlock_type = (PyTypeObject *)PyType_FromSpec(&rlock_type_spec); + if (rlock_type == NULL) { + return -1; + } + if (PyModule_AddType(module, rlock_type) < 0) { + Py_DECREF(rlock_type); + return -1; + } + Py_DECREF(rlock_type); -PyMODINIT_FUNC -PyInit__thread(void) -{ - PyObject *m, *d, *v; - double time_max; - double timeout_max; - PyInterpreterState *interp = _PyInterpreterState_GET(); + // Local dummy + state->local_dummy_type = (PyTypeObject *)PyType_FromSpec(&local_dummy_type_spec); + if (state->local_dummy_type == NULL) { + return -1; + } + + // Local + state->local_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &local_type_spec, NULL); + if (state->local_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->local_type) < 0) { + return -1; + } - /* Initialize types: */ - if (PyType_Ready(&localdummytype) < 0) - return NULL; - if (PyType_Ready(&localtype) < 0) - return NULL; - if (PyType_Ready(&Locktype) < 0) - return NULL; - if (PyType_Ready(&RLocktype) < 0) - return NULL; if (ExceptHookArgsType.tp_name == NULL) { if (PyStructSequence_InitType2(&ExceptHookArgsType, &ExceptHookArgs_desc) < 0) { - return NULL; + return -1; } } - /* Create the module and add the functions */ - m = PyModule_Create(&threadmodule); - if (m == NULL) - return NULL; + // Add module attributes + if (PyDict_SetItemString(d, "error", ThreadError) < 0) { + return -1; + } + if (PyModule_AddType(module, &ExceptHookArgsType) < 0) { + return -1; + } - timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6; - time_max = _PyTime_AsSecondsDouble(_PyTime_MAX); + // TIMEOUT_MAX + double timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6; + double time_max = _PyTime_AsSecondsDouble(_PyTime_MAX); timeout_max = Py_MIN(timeout_max, time_max); - /* Round towards minus infinity */ + // Round towards minus infinity timeout_max = floor(timeout_max); - v = PyFloat_FromDouble(timeout_max); - if (!v) - return NULL; - if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0) - return NULL; + if (PyModule_AddObject(module, "TIMEOUT_MAX", + PyFloat_FromDouble(timeout_max)) < 0) { + return -1; + } - /* Add a symbolic constant */ - d = PyModule_GetDict(m); - ThreadError = PyExc_RuntimeError; - Py_INCREF(ThreadError); + return 0; +} - PyDict_SetItemString(d, "error", ThreadError); - Locktype.tp_doc = lock_doc; - Py_INCREF(&Locktype); - PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype); - Py_INCREF(&RLocktype); - if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0) - return NULL; +static int +thread_module_traverse(PyObject *module, visitproc visit, void *arg) +{ + thread_module_state *state = get_thread_state(module); + Py_VISIT(state->lock_type); + Py_VISIT(state->local_type); + Py_VISIT(state->local_dummy_type); + return 0; +} - Py_INCREF(&localtype); - if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0) - return NULL; +static int +thread_module_clear(PyObject *module) +{ + thread_module_state *state = get_thread_state(module); + Py_CLEAR(state->lock_type); + Py_CLEAR(state->local_type); + Py_CLEAR(state->local_dummy_type); + return 0; +} - Py_INCREF(&ExceptHookArgsType); - if (PyModule_AddObject(m, "_ExceptHookArgs", - (PyObject *)&ExceptHookArgsType) < 0) - return NULL; +static void +thread_module_free(void *module) +{ + thread_module_clear((PyObject *)module); +} - interp->num_threads = 0; - str_dict = PyUnicode_InternFromString("__dict__"); - if (str_dict == NULL) - return NULL; - /* Initialize the C thread library */ - PyThread_init_thread(); - return m; +PyDoc_STRVAR(thread_doc, +"This module provides primitive operations to write multi-threaded programs.\n\ +The 'threading' module provides a more convenient interface."); + +static PyModuleDef_Slot thread_module_slots[] = { + {Py_mod_exec, thread_module_exec}, + {0, NULL} +}; + +static struct PyModuleDef thread_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_thread", + .m_doc = thread_doc, + .m_size = sizeof(thread_module_state), + .m_methods = thread_methods, + .m_traverse = thread_module_traverse, + .m_clear = thread_module_clear, + .m_free = thread_module_free, + .m_slots = thread_module_slots, +}; + +PyMODINIT_FUNC +PyInit__thread(void) +{ + return PyModuleDef_Init(&thread_module); } diff --git a/contrib/tools/python3/src/Modules/_winapi.c b/contrib/tools/python3/src/Modules/_winapi.c index 5b7f075722e..a44a300c0c8 100644 --- a/contrib/tools/python3/src/Modules/_winapi.c +++ b/contrib/tools/python3/src/Modules/_winapi.c @@ -35,8 +35,10 @@ /* See https://www.python.org/2.4/license for licensing details. */ #include "Python.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "structmember.h" // PyMemberDef + #define WINDOWS_LEAN_AND_MEAN #include "windows.h" #include @@ -79,6 +81,17 @@ check_CancelIoEx() return has_CancelIoEx; } +typedef struct { + PyTypeObject *overlapped_type; +} WinApiState; + +static inline WinApiState* +winapi_get_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (WinApiState *)state; +} /* * A Python object wrapping an OVERLAPPED structure and other useful data @@ -100,12 +113,27 @@ typedef struct { Py_buffer write_buffer; } OverlappedObject; +/* +Note: tp_clear (overlapped_clear) is not implemented because it +requires cancelling the IO operation if it's pending and the cancellation is +quite complex and can fail (see: overlapped_dealloc). +*/ +static int +overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->read_buffer); + Py_VISIT(self->write_buffer.obj); + Py_VISIT(Py_TYPE(self)); + return 0; +} + static void overlapped_dealloc(OverlappedObject *self) { DWORD bytes; int err = GetLastError(); + PyObject_GC_UnTrack(self); if (self->pending) { if (check_CancelIoEx() && Py_CancelIoEx(self->handle, &self->overlapped) && @@ -141,12 +169,14 @@ overlapped_dealloc(OverlappedObject *self) if (self->write_buffer.obj) PyBuffer_Release(&self->write_buffer); Py_CLEAR(self->read_buffer); - PyObject_Del(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + Py_DECREF(tp); } /*[clinic input] module _winapi -class _winapi.Overlapped "OverlappedObject *" "&WinApiOverlappedType" +class _winapi.Overlapped "OverlappedObject *" "&OverlappedType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c13d3f5fd1dabb84]*/ @@ -165,10 +195,11 @@ create_converter('LPCVOID', '" F_POINTER "') create_converter('BOOL', 'i') # F_BOOL used previously (always 'i') create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter) create_converter('LPCTSTR', 's') -create_converter('LPCWSTR', 'u') -create_converter('LPWSTR', 'u') create_converter('UINT', 'I') # F_UINT used previously (always 'I') +class LPCWSTR_converter(Py_UNICODE_converter): + type = 'LPCWSTR' + class HANDLE_return_converter(CReturnConverter): type = 'HANDLE' @@ -198,7 +229,7 @@ class LPVOID_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = HANDLE_TO_PYNUM(_return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=79464c61a31ae932]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=011ee0c3a2244bfe]*/ #include "clinic/_winapi.c.h" @@ -305,55 +336,31 @@ static PyMemberDef overlapped_members[] = { {NULL} }; -PyTypeObject WinApiOverlappedType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_winapi.Overlapped", - /* tp_basicsize */ sizeof(OverlappedObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor) overlapped_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, - /* tp_doc */ "OVERLAPPED structure wrapper", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ overlapped_methods, - /* tp_members */ overlapped_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 */ 0, +static PyType_Slot winapi_overlapped_type_slots[] = { + {Py_tp_traverse, overlapped_traverse}, + {Py_tp_dealloc, overlapped_dealloc}, + {Py_tp_doc, "OVERLAPPED structure wrapper"}, + {Py_tp_methods, overlapped_methods}, + {Py_tp_members, overlapped_members}, + {0,0} +}; + +static PyType_Spec winapi_overlapped_type_spec = { + .name = "_winapi.Overlapped", + .basicsize = sizeof(OverlappedObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = winapi_overlapped_type_slots, }; static OverlappedObject * -new_overlapped(HANDLE handle) +new_overlapped(PyObject *module, HANDLE handle) { - OverlappedObject *self; - - self = PyObject_New(OverlappedObject, &WinApiOverlappedType); + WinApiState *st = winapi_get_state(module); + OverlappedObject *self = PyObject_GC_New(OverlappedObject, st->overlapped_type); if (!self) return NULL; + self->handle = handle; self->read_buffer = NULL; self->pending = 0; @@ -362,6 +369,8 @@ new_overlapped(HANDLE handle) memset(&self->write_buffer, 0, sizeof(Py_buffer)); /* Manual reset, initially non-signalled */ self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + PyObject_GC_Track(self); return self; } @@ -409,7 +418,7 @@ _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, OverlappedObject *overlapped = NULL; if (use_overlapped) { - overlapped = new_overlapped(handle); + overlapped = new_overlapped(module, handle); if (!overlapped) return NULL; } @@ -521,15 +530,15 @@ _winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle, /*[clinic input] _winapi.CreateJunction - src_path: LPWSTR - dst_path: LPWSTR + src_path: LPCWSTR + dst_path: LPCWSTR / [clinic start generated code]*/ static PyObject * -_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, - LPWSTR dst_path) -/*[clinic end generated code: output=66b7eb746e1dfa25 input=8cd1f9964b6e3d36]*/ +_winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, + LPCWSTR dst_path) +/*[clinic end generated code: output=44b3f5e9bbcc4271 input=963d29b44b9384a7]*/ { /* Privilege adjustment */ HANDLE token = NULL; @@ -1527,7 +1536,7 @@ _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, if (!buf) return NULL; if (use_overlapped) { - overlapped = new_overlapped(handle); + overlapped = new_overlapped(module, handle); if (!overlapped) { Py_DECREF(buf); return NULL; @@ -1810,7 +1819,7 @@ _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, OverlappedObject *overlapped = NULL; if (use_overlapped) { - overlapped = new_overlapped(handle); + overlapped = new_overlapped(module, handle); if (!overlapped) return NULL; buf = &overlapped->write_buffer; @@ -1886,6 +1895,113 @@ _winapi_GetFileType_impl(PyObject *module, HANDLE handle) return result; } +/*[clinic input] +_winapi._mimetypes_read_windows_registry + + on_type_read: object + +Optimized function for reading all known MIME types from the registry. + +*on_type_read* is a callable taking *type* and *ext* arguments, as for +MimeTypes.add_type. +[clinic start generated code]*/ + +static PyObject * +_winapi__mimetypes_read_windows_registry_impl(PyObject *module, + PyObject *on_type_read) +/*[clinic end generated code: output=20829f00bebce55b input=cd357896d6501f68]*/ +{ +#define CCH_EXT 128 +#define CB_TYPE 510 + struct { + wchar_t ext[CCH_EXT]; + wchar_t type[CB_TYPE / sizeof(wchar_t) + 1]; + } entries[64]; + int entry = 0; + HKEY hkcr = NULL; + LRESULT err; + + Py_BEGIN_ALLOW_THREADS + err = RegOpenKeyExW(HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &hkcr); + for (DWORD i = 0; err == ERROR_SUCCESS || err == ERROR_MORE_DATA; ++i) { + LPWSTR ext = entries[entry].ext; + LPWSTR type = entries[entry].type; + DWORD cchExt = CCH_EXT; + DWORD cbType = CB_TYPE; + HKEY subkey; + DWORD regType; + + err = RegEnumKeyExW(hkcr, i, ext, &cchExt, NULL, NULL, NULL, NULL); + if (err != ERROR_SUCCESS || (cchExt && ext[0] != L'.')) { + continue; + } + + err = RegOpenKeyExW(hkcr, ext, 0, KEY_READ, &subkey); + if (err == ERROR_FILE_NOT_FOUND) { + err = ERROR_SUCCESS; + continue; + } else if (err != ERROR_SUCCESS) { + continue; + } + + err = RegQueryValueExW(subkey, L"Content Type", NULL, + ®Type, (LPBYTE)type, &cbType); + RegCloseKey(subkey); + if (err == ERROR_FILE_NOT_FOUND) { + err = ERROR_SUCCESS; + continue; + } else if (err != ERROR_SUCCESS) { + continue; + } else if (regType != REG_SZ || !cbType) { + continue; + } + type[cbType / sizeof(wchar_t)] = L'\0'; + + entry += 1; + + /* Flush our cached entries if we are full */ + if (entry == sizeof(entries) / sizeof(entries[0])) { + Py_BLOCK_THREADS + for (int j = 0; j < entry; ++j) { + PyObject *r = PyObject_CallFunction( + on_type_read, "uu", entries[j].type, entries[j].ext + ); + if (!r) { + /* We blocked threads, so safe to return from here */ + RegCloseKey(hkcr); + return NULL; + } + Py_DECREF(r); + } + Py_UNBLOCK_THREADS + entry = 0; + } + } + if (hkcr) { + RegCloseKey(hkcr); + } + Py_END_ALLOW_THREADS + + if (err != ERROR_SUCCESS && err != ERROR_NO_MORE_ITEMS) { + PyErr_SetFromWindowsErr((int)err); + return NULL; + } + + for (int j = 0; j < entry; ++j) { + PyObject *r = PyObject_CallFunction( + on_type_read, "uu", entries[j].type, entries[j].ext + ); + if (!r) { + return NULL; + } + Py_DECREF(r); + } + + Py_RETURN_NONE; +#undef CCH_EXT +#undef CB_TYPE +} + static PyMethodDef winapi_functions[] = { _WINAPI_CLOSEHANDLE_METHODDEF @@ -1918,39 +2034,37 @@ static PyMethodDef winapi_functions[] = { _WINAPI_WRITEFILE_METHODDEF _WINAPI_GETACP_METHODDEF _WINAPI_GETFILETYPE_METHODDEF + _WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF {NULL, NULL} }; -static struct PyModuleDef winapi_module = { - PyModuleDef_HEAD_INIT, - "_winapi", - NULL, - -1, - winapi_functions, - NULL, - NULL, - NULL, - NULL -}; - #define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) - -PyMODINIT_FUNC -PyInit__winapi(void) + do { \ + PyObject *value = Py_BuildValue(fmt, con); \ + if (value == NULL) { \ + return -1; \ + } \ + if (PyDict_SetItemString(d, #con, value) < 0) { \ + Py_DECREF(value); \ + return -1; \ + } \ + Py_DECREF(value); \ + } while (0) + +static int winapi_exec(PyObject *m) { - PyObject *d; - PyObject *m; + WinApiState *st = winapi_get_state(m); - if (PyType_Ready(&WinApiOverlappedType) < 0) - return NULL; + st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(m, &winapi_overlapped_type_spec, NULL); + if (st->overlapped_type == NULL) { + return -1; + } - m = PyModule_Create(&winapi_module); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); + if (PyModule_AddType(m, st->overlapped_type) < 0) { + return -1; + } - PyDict_SetItemString(d, "Overlapped", (PyObject *) &WinApiOverlappedType); + PyObject *d = PyModule_GetDict(m); /* constants */ WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE); @@ -2049,5 +2163,49 @@ PyInit__winapi(void) WINAPI_CONSTANT("i", NULL); - return m; + return 0; +} + +static PyModuleDef_Slot winapi_slots[] = { + {Py_mod_exec, winapi_exec}, + {0, NULL} +}; + +static int +winapi_traverse(PyObject *module, visitproc visit, void *arg) +{ + WinApiState *st = winapi_get_state(module); + Py_VISIT(st->overlapped_type); + return 0; +} + +static int +winapi_clear(PyObject *module) +{ + WinApiState *st = winapi_get_state(module); + Py_CLEAR(st->overlapped_type); + return 0; +} + +static void +winapi_free(void *module) +{ + winapi_clear((PyObject *)module); +} + +static struct PyModuleDef winapi_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_winapi", + .m_size = sizeof(WinApiState), + .m_methods = winapi_functions, + .m_slots = winapi_slots, + .m_traverse = winapi_traverse, + .m_clear = winapi_clear, + .m_free = winapi_free, +}; + +PyMODINIT_FUNC +PyInit__winapi(void) +{ + return PyModuleDef_Init(&winapi_module); } diff --git a/contrib/tools/python3/src/Modules/_xxsubinterpretersmodule.c b/contrib/tools/python3/src/Modules/_xxsubinterpretersmodule.c index 314059d1082..9290255c66c 100644 --- a/contrib/tools/python3/src/Modules/_xxsubinterpretersmodule.c +++ b/contrib/tools/python3/src/Modules/_xxsubinterpretersmodule.c @@ -1780,7 +1780,12 @@ static PyTypeObject ChannelIDtype = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + // 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 */ @@ -1791,19 +1796,6 @@ static PyTypeObject ChannelIDtype = { 0, /* tp_methods */ 0, /* tp_members */ channelid_getsets, /* 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 */ - // Note that we do not set tp_new to channelid_new. Instead we - // set it to NULL, meaning it 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. - NULL, /* tp_new */ }; @@ -1847,7 +1839,7 @@ _is_running(PyInterpreterState *interp) return 0; } - int executing = (int)(frame->f_executing); + int executing = _PyFrame_IsExecuting(frame); Py_DECREF(frame); return executing; @@ -1939,6 +1931,20 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, return -1; } +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + // Switch to interpreter. + PyThreadState *new_tstate = PyInterpreterState_ThreadHead(interp); + PyThreadState *save1 = PyEval_SaveThread(); + + (void)PyThreadState_Swap(new_tstate); + + // Run the script. + _sharedexception *exc = NULL; + int result = _run_script(interp, codestr, shared, &exc); + + // Switch back. + PyEval_RestoreThread(save1); +#else // Switch to interpreter. PyThreadState *save_tstate = NULL; if (interp != PyInterpreterState_Get()) { @@ -1956,6 +1962,7 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, if (save_tstate != NULL) { PyThreadState_Swap(save_tstate); } +#endif // Propagate any exception out to the caller. if (exc != NULL) { diff --git a/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c b/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c index 6bd2c3aedcc..acbf068637b 100644 --- a/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c +++ b/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c @@ -83,7 +83,7 @@ static int fuzz_builtin_unicode(const char* data, size_t size) { PyObject* struct_unpack_method = NULL; PyObject* struct_error = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ -static int init_struct_unpack() { +static int init_struct_unpack(void) { /* Import struct.unpack */ PyObject* struct_module = PyImport_ImportModule("struct"); if (struct_module == NULL) { @@ -146,7 +146,7 @@ static int fuzz_struct_unpack(const char* data, size_t size) { PyObject* json_loads_method = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ -static int init_json_loads() { +static int init_json_loads(void) { /* Import json.loads */ PyObject* json_module = PyImport_ImportModule("json"); if (json_module == NULL) { @@ -192,7 +192,7 @@ PyObject* sre_compile_method = NULL; PyObject* sre_error_exception = NULL; int SRE_FLAG_DEBUG = 0; /* Called by LLVMFuzzerTestOneInput for initialization */ -static int init_sre_compile() { +static int init_sre_compile(void) { /* Import sre_compile.compile and sre.error */ PyObject* sre_compile_module = PyImport_ImportModule("sre_compile"); if (sre_compile_module == NULL) { @@ -284,7 +284,7 @@ static const char* regex_patterns[] = { const size_t NUM_PATTERNS = sizeof(regex_patterns) / sizeof(regex_patterns[0]); PyObject** compiled_patterns = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ -static int init_sre_match() { +static int init_sre_match(void) { PyObject* re_module = PyImport_ImportModule("re"); if (re_module == NULL) { return 0; @@ -339,7 +339,7 @@ static int fuzz_sre_match(const char* data, size_t size) { PyObject* csv_module = NULL; PyObject* csv_error = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ -static int init_csv_reader() { +static int init_csv_reader(void) { /* Import csv and csv.Error */ csv_module = PyImport_ImportModule("csv"); if (csv_module == NULL) { @@ -354,7 +354,7 @@ static int fuzz_csv_reader(const char* data, size_t size) { return 0; } /* Ignore non null-terminated strings since _csv can't handle - embeded nulls */ + embedded nulls */ if (memchr(data, '\0', size) == NULL) { return 0; } @@ -383,7 +383,7 @@ static int fuzz_csv_reader(const char* data, size_t size) { } /* Ignore csv.Error because we're probably going to generate - some bad files (embeded new-lines, unterminated quotes etc) */ + some bad files (embedded new-lines, unterminated quotes etc) */ if (PyErr_ExceptionMatches(csv_error)) { PyErr_Clear(); } diff --git a/contrib/tools/python3/src/Modules/_zoneinfo.c b/contrib/tools/python3/src/Modules/_zoneinfo.c index cd147aedb4c..0388d27ce10 100644 --- a/contrib/tools/python3/src/Modules/_zoneinfo.c +++ b/contrib/tools/python3/src/Modules/_zoneinfo.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_long.h" // _PyLong_GetOne() #include "structmember.h" #include @@ -487,9 +488,7 @@ zoneinfo_tzname(PyObject *self, PyObject *dt) return tti->tzname; } -#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo) -#define GET_DT_TZINFO(p) \ - (HASTZINFO(p) ? ((PyDateTime_DateTime *)(p))->tzinfo : Py_None) +#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO static PyObject * zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) @@ -590,7 +589,7 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) } dt = NULL; - if (!PyDict_SetItemString(kwargs, "fold", _PyLong_One)) { + if (!PyDict_SetItemString(kwargs, "fold", _PyLong_GetOne())) { dt = PyObject_Call(replace, args, kwargs); } @@ -727,17 +726,16 @@ zoneinfo__unpickle(PyTypeObject *cls, PyObject *args) static PyObject * load_timedelta(long seconds) { - PyObject *rv = NULL; + PyObject *rv; PyObject *pyoffset = PyLong_FromLong(seconds); if (pyoffset == NULL) { return NULL; } - int contains = PyDict_Contains(TIMEDELTA_CACHE, pyoffset); - if (contains == -1) { - goto error; - } - - if (!contains) { + rv = PyDict_GetItemWithError(TIMEDELTA_CACHE, pyoffset); + if (rv == NULL) { + if (PyErr_Occurred()) { + goto error; + } PyObject *tmp = PyDateTimeAPI->Delta_FromDelta( 0, seconds, 0, 1, PyDateTimeAPI->DeltaType); @@ -748,12 +746,9 @@ load_timedelta(long seconds) rv = PyDict_SetDefault(TIMEDELTA_CACHE, pyoffset, tmp); Py_DECREF(tmp); } - else { - rv = PyDict_GetItem(TIMEDELTA_CACHE, pyoffset); - } + Py_XINCREF(rv); Py_DECREF(pyoffset); - Py_INCREF(rv); return rv; error: Py_DECREF(pyoffset); @@ -1473,11 +1468,11 @@ parse_tz_str(PyObject *tz_str_obj, _tzrule *out) long std_offset = 1 << 20; long dst_offset = 1 << 20; - char *tz_str = PyBytes_AsString(tz_str_obj); + const char *tz_str = PyBytes_AsString(tz_str_obj); if (tz_str == NULL) { return -1; } - char *p = tz_str; + const char *p = tz_str; // Read the `std` abbreviation, which must be at least 3 characters long. Py_ssize_t num_chars = parse_abbr(p, &std_abbr); diff --git a/contrib/tools/python3/src/Modules/arraymodule.c b/contrib/tools/python3/src/Modules/arraymodule.c index 7c7fc917454..72b90111a83 100644 --- a/contrib/tools/python3/src/Modules/arraymodule.c +++ b/contrib/tools/python3/src/Modules/arraymodule.c @@ -5,6 +5,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "structmember.h" // PyMemberDef #include // offsetof() #ifdef STDC_HEADERS @@ -21,6 +23,7 @@ module array /*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/ struct arrayobject; /* Forward */ +static struct PyModuleDef arraymodule; /* All possible arraydescr values are defined in the vector "descriptors" * below. That's defined later because the appropriate get and set @@ -46,8 +49,6 @@ typedef struct arrayobject { Py_ssize_t ob_exports; /* Number of exported buffers */ } arrayobject; -static PyTypeObject Arraytype; - typedef struct { PyObject_HEAD Py_ssize_t index; @@ -55,9 +56,21 @@ typedef struct { PyObject* (*getitem)(struct arrayobject *, Py_ssize_t); } arrayiterobject; -static PyTypeObject PyArrayIter_Type; +typedef struct { + PyTypeObject *ArrayType; + PyTypeObject *ArrayIterType; +} array_state; + +static array_state * +get_array_state(PyObject *module) +{ + return (array_state *)_PyModule_GetState(module); +} -#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) +#define find_array_state_by_type(tp) \ + (get_array_state(_PyType_GetModuleByDef(tp, &arraymodule))) +#define get_array_state_by_class(cls) \ + (get_array_state(PyType_GetModule(cls))) enum machine_format_code { UNKNOWN_FORMAT = -1, @@ -105,8 +118,7 @@ enum machine_format_code { */ #include "clinic/arraymodule.c.h" -#define array_Check(op) PyObject_TypeCheck(op, &Arraytype) -#define array_CheckExact(op) Py_IS_TYPE(op, &Arraytype) +#define array_Check(op, state) PyObject_TypeCheck(op, state->ArrayType) static int array_resize(arrayobject *self, Py_ssize_t newsize) @@ -133,7 +145,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize) } if (newsize == 0) { - PyMem_FREE(self->ob_item); + PyMem_Free(self->ob_item); self->ob_item = NULL; Py_SET_SIZE(self, 0); self->allocated = 0; @@ -337,17 +349,6 @@ II_getitem(arrayobject *ap, Py_ssize_t i) (unsigned long) ((unsigned int *)ap->ob_item)[i]); } -static PyObject * -get_int_unless_float(PyObject *v) -{ - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "array item must be integer"); - return NULL; - } - return _PyLong_FromNbIndexOrNbInt(v); -} - static int II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { @@ -355,7 +356,7 @@ II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) int do_decref = 0; /* if nb_int was called */ if (!PyLong_Check(v)) { - v = get_int_unless_float(v); + v = _PyNumber_Index(v); if (NULL == v) { return -1; } @@ -415,7 +416,7 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) int do_decref = 0; /* if nb_int was called */ if (!PyLong_Check(v)) { - v = get_int_unless_float(v); + v = _PyNumber_Index(v); if (NULL == v) { return -1; } @@ -468,7 +469,7 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) int do_decref = 0; /* if nb_int was called */ if (!PyLong_Check(v)) { - v = get_int_unless_float(v); + v = _PyNumber_Index(v); if (NULL == v) { return -1; } @@ -573,9 +574,9 @@ static const struct arraydescr descriptors[] = { Implementations of array object methods. ****************************************************************************/ /*[clinic input] -class array.array "arrayobject *" "&Arraytype" +class array.array "arrayobject *" "ArrayType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/ static PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr) @@ -618,8 +619,11 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des static PyObject * getarrayitem(PyObject *op, Py_ssize_t i) { +#ifndef NDEBUG + array_state *state = find_array_state_by_type(Py_TYPE(op)); + assert(array_Check(op, state)); +#endif arrayobject *ap; - assert(array_Check(op)); ap = (arrayobject *)op; assert(i>=0 && iob_descr->getitem)(ap, i); @@ -657,26 +661,38 @@ ins1(arrayobject *self, Py_ssize_t where, PyObject *v) /* Methods */ +static int +array_tp_traverse(arrayobject *op, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(op)); + return 0; +} + static void array_dealloc(arrayobject *op) { + PyTypeObject *tp = Py_TYPE(op); + PyObject_GC_UnTrack(op); + if (op->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) op); if (op->ob_item != NULL) - PyMem_DEL(op->ob_item); - Py_TYPE(op)->tp_free((PyObject *)op); + PyMem_Free(op->ob_item); + tp->tp_free(op); + Py_DECREF(tp); } static PyObject * array_richcompare(PyObject *v, PyObject *w, int op) { + array_state *state = find_array_state_by_type(Py_TYPE(v)); arrayobject *va, *wa; PyObject *vi = NULL; PyObject *wi = NULL; Py_ssize_t i, k; PyObject *res; - if (!array_Check(v) || !array_Check(w)) + if (!array_Check(v, state) || !array_Check(w, state)) Py_RETURN_NOTIMPLEMENTED; va = (arrayobject *)v; @@ -798,7 +814,9 @@ array_item(arrayobject *a, Py_ssize_t i) static PyObject * array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { + array_state *state = find_array_state_by_type(Py_TYPE(a)); arrayobject *np; + if (ilow < 0) ilow = 0; else if (ilow > Py_SIZE(a)) @@ -809,7 +827,7 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) ihigh = ilow; else if (ihigh > Py_SIZE(a)) ihigh = Py_SIZE(a); - np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr); + np = (arrayobject *) newarrayobject(state->ArrayType, ihigh - ilow, a->ob_descr); if (np == NULL) return NULL; if (ihigh > ilow) { @@ -852,9 +870,10 @@ array_array___deepcopy__(arrayobject *self, PyObject *unused) static PyObject * array_concat(arrayobject *a, PyObject *bb) { + array_state *state = find_array_state_by_type(Py_TYPE(a)); Py_ssize_t size; arrayobject *np; - if (!array_Check(bb)) { + if (!array_Check(bb, state)) { PyErr_Format(PyExc_TypeError, "can only append array (not \"%.200s\") to array", Py_TYPE(bb)->tp_name); @@ -869,7 +888,7 @@ array_concat(arrayobject *a, PyObject *bb) return PyErr_NoMemory(); } size = Py_SIZE(a) + Py_SIZE(b); - np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); + np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); if (np == NULL) { return NULL; } @@ -887,6 +906,7 @@ array_concat(arrayobject *a, PyObject *bb) static PyObject * array_repeat(arrayobject *a, Py_ssize_t n) { + array_state *state = find_array_state_by_type(Py_TYPE(a)); Py_ssize_t size; arrayobject *np; Py_ssize_t oldbytes, newbytes; @@ -896,7 +916,7 @@ array_repeat(arrayobject *a, Py_ssize_t n) return PyErr_NoMemory(); } size = Py_SIZE(a) * n; - np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); + np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); if (np == NULL) return NULL; if (size == 0) @@ -969,7 +989,10 @@ array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v) static int setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v) { - assert(array_Check(a)); +#ifndef NDEBUG + array_state *state = find_array_state_by_type(Py_TYPE(a)); + assert(array_Check(a, state)); +#endif return array_ass_item((arrayobject *)a, i, v); } @@ -997,11 +1020,11 @@ array_iter_extend(arrayobject *self, PyObject *bb) } static int -array_do_extend(arrayobject *self, PyObject *bb) +array_do_extend(array_state *state, arrayobject *self, PyObject *bb) { Py_ssize_t size, oldsize, bbsize; - if (!array_Check(bb)) + if (!array_Check(bb, state)) return array_iter_extend(self, bb); #define b ((arrayobject *)bb) if (self->ob_descr != b->ob_descr) { @@ -1032,13 +1055,15 @@ array_do_extend(arrayobject *self, PyObject *bb) static PyObject * array_inplace_concat(arrayobject *self, PyObject *bb) { - if (!array_Check(bb)) { + array_state *state = find_array_state_by_type(Py_TYPE(self)); + + if (!array_Check(bb, state)) { PyErr_Format(PyExc_TypeError, "can only extend array with array (not \"%.200s\")", Py_TYPE(bb)->tp_name); return NULL; } - if (array_do_extend(self, bb) == -1) + if (array_do_extend(state, self, bb) == -1) return NULL; Py_INCREF(self); return (PyObject *)self; @@ -1120,18 +1145,32 @@ array_array_count(arrayobject *self, PyObject *v) array.array.index v: object + start: slice_index(accept={int}) = 0 + stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize / Return index of first occurrence of v in the array. + +Raise ValueError if the value is not present. [clinic start generated code]*/ static PyObject * -array_array_index(arrayobject *self, PyObject *v) -/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/ -{ - Py_ssize_t i; - - for (i = 0; i < Py_SIZE(self); i++) { +array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start, + Py_ssize_t stop) +/*[clinic end generated code: output=c45e777880c99f52 input=089dff7baa7e5a7e]*/ +{ + if (start < 0) { + start += Py_SIZE(self); + if (start < 0) { + start = 0; + } + } + if (stop < 0) { + stop += Py_SIZE(self); + } + // Use Py_SIZE() for every iteration in case the array is mutated + // during PyObject_RichCompareBool() + for (Py_ssize_t i = start; i < stop && i < Py_SIZE(self); i++) { PyObject *selfi; int cmp; @@ -1243,6 +1282,7 @@ array_array_pop_impl(arrayobject *self, Py_ssize_t i) /*[clinic input] array.array.extend + cls: defining_class bb: object / @@ -1250,10 +1290,12 @@ Append items to the end of the array. [clinic start generated code]*/ static PyObject * -array_array_extend(arrayobject *self, PyObject *bb) -/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/ +array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb) +/*[clinic end generated code: output=e65eb7588f0bc266 input=8eb6817ec4d2cb62]*/ { - if (array_do_extend(self, bb) == -1) + array_state *state = get_array_state_by_class(cls); + + if (array_do_extend(state, self, bb) == -1) return NULL; Py_RETURN_NONE; } @@ -1939,6 +1981,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, PyObject *items) /*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/ { + array_state *state = get_array_state(module); PyObject *converted_items; PyObject *result; const struct arraydescr *descr; @@ -1949,10 +1992,10 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_TYPE(arraytype)->tp_name); return NULL; } - if (!PyType_IsSubtype(arraytype, &Arraytype)) { + if (!PyType_IsSubtype(arraytype, state->ArrayType)) { PyErr_Format(PyExc_TypeError, "%.200s is not a subtype of %.200s", - arraytype->tp_name, Arraytype.tp_name); + arraytype->tp_name, state->ArrayType->tp_name); return NULL; } for (descr = descriptors; descr->typecode != '\0'; descr++) { @@ -2298,6 +2341,8 @@ array_repr(arrayobject *a) static PyObject* array_subscr(arrayobject* self, PyObject* item) { + array_state *state = find_array_state_by_type(Py_TYPE(self)); + if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i==-1 && PyErr_Occurred()) { @@ -2321,10 +2366,10 @@ array_subscr(arrayobject* self, PyObject* item) step); if (slicelength <= 0) { - return newarrayobject(&Arraytype, 0, self->ob_descr); + return newarrayobject(state->ArrayType, 0, self->ob_descr); } else if (step == 1) { - PyObject *result = newarrayobject(&Arraytype, + PyObject *result = newarrayobject(state->ArrayType, slicelength, self->ob_descr); if (result == NULL) return NULL; @@ -2334,7 +2379,7 @@ array_subscr(arrayobject* self, PyObject* item) return result; } else { - result = newarrayobject(&Arraytype, slicelength, self->ob_descr); + result = newarrayobject(state->ArrayType, slicelength, self->ob_descr); if (!result) return NULL; ar = (arrayobject*)result; @@ -2360,6 +2405,7 @@ static int array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) { Py_ssize_t start, stop, step, slicelength, needed; + array_state* state = find_array_state_by_type(Py_TYPE(self)); arrayobject* other; int itemsize; @@ -2401,7 +2447,7 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) other = NULL; needed = 0; } - else if (array_Check(value)) { + else if (array_Check(value, state)) { other = (arrayobject *)value; needed = Py_SIZE(other); if (self == other) { @@ -2513,12 +2559,6 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) } } -static PyMappingMethods array_as_mapping = { - (lenfunc)array_length, - (binaryfunc)array_subscr, - (objobjargproc)array_ass_subscr -}; - static const void *emptybuf = ""; @@ -2536,14 +2576,14 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) Py_INCREF(self); if (view->buf == NULL) view->buf = (void *)emptybuf; - view->len = (Py_SIZE(self)) * self->ob_descr->itemsize; + view->len = Py_SIZE(self) * self->ob_descr->itemsize; view->readonly = 0; view->ndim = 1; view->itemsize = self->ob_descr->itemsize; view->suboffsets = NULL; view->shape = NULL; if ((flags & PyBUF_ND)==PyBUF_ND) { - view->shape = &((Py_SIZE(self))); + view->shape = &((PyVarObject*)self)->ob_size; } view->strides = NULL; if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES) @@ -2569,32 +2609,15 @@ array_buffer_relbuf(arrayobject *self, Py_buffer *view) self->ob_exports--; } -static PySequenceMethods array_as_sequence = { - (lenfunc)array_length, /*sq_length*/ - (binaryfunc)array_concat, /*sq_concat*/ - (ssizeargfunc)array_repeat, /*sq_repeat*/ - (ssizeargfunc)array_item, /*sq_item*/ - 0, /*sq_slice*/ - (ssizeobjargproc)array_ass_item, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - (objobjproc)array_contains, /*sq_contains*/ - (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/ - (ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/ -}; - -static PyBufferProcs array_as_buffer = { - (getbufferproc)array_buffer_getbuf, - (releasebufferproc)array_buffer_relbuf -}; - static PyObject * array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + array_state *state = find_array_state_by_type(type); int c; PyObject *initial = NULL, *it = NULL; const struct arraydescr *descr; - if (type == &Arraytype && !_PyArg_NoKeywords("array.array", kwds)) + if (type == state->ArrayType && !_PyArg_NoKeywords("array.array", kwds)) return NULL; if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial)) @@ -2611,7 +2634,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) "an array with typecode '%c'", c); return NULL; } - else if (array_Check(initial) && + else if (array_Check(initial, state) && ((arrayobject*)initial)->ob_descr->typecode == 'u') { PyErr_Format(PyExc_TypeError, "cannot use a unicode array to " "initialize an array with typecode '%c'", c); @@ -2624,7 +2647,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) || PyBytes_Check(initial) || PyTuple_Check(initial) || ((c=='u') && PyUnicode_Check(initial)) - || (array_Check(initial) + || (array_Check(initial, state) && c == ((arrayobject*)initial)->ob_descr->typecode))) { it = PyObject_GetIter(initial); if (it == NULL) @@ -2645,7 +2668,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) len = 0; else if (PyList_Check(initial)) len = PyList_GET_SIZE(initial); - else if (PyTuple_Check(initial) || array_Check(initial)) + else if (PyTuple_Check(initial) || array_Check(initial, state)) len = Py_SIZE(initial); else len = 0; @@ -2654,7 +2677,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (a == NULL) return NULL; - if (len > 0 && !array_Check(initial)) { + if (len > 0 && !array_Check(initial, state)) { Py_ssize_t i; for (i = 0; i < len; i++) { PyObject *v = @@ -2699,7 +2722,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->allocated = n; } } - else if (initial != NULL && array_Check(initial) && len > 0) { + else if (initial != NULL && array_Check(initial, state) && len > 0) { arrayobject *self = (arrayobject *)a; arrayobject *other = (arrayobject *)initial; memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize); @@ -2788,67 +2811,75 @@ itemsize -- the length in bytes of one array item\n\ static PyObject *array_iter(arrayobject *ao); -static PyTypeObject Arraytype = { - PyVarObject_HEAD_INIT(NULL, 0) - "array.array", - sizeof(arrayobject), - 0, - (destructor)array_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)array_repr, /* tp_repr */ - 0, /* tp_as_number*/ - &array_as_sequence, /* tp_as_sequence*/ - &array_as_mapping, /* tp_as_mapping*/ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - &array_as_buffer, /* tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - arraytype_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - array_richcompare, /* tp_richcompare */ - offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */ - (getiterfunc)array_iter, /* tp_iter */ - 0, /* tp_iternext */ - array_methods, /* tp_methods */ - 0, /* tp_members */ - array_getsets, /* 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 */ - array_new, /* tp_new */ - PyObject_Del, /* tp_free */ +static struct PyMemberDef array_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(arrayobject, weakreflist), READONLY}, + {NULL}, }; +static PyType_Slot array_slots[] = { + {Py_tp_dealloc, array_dealloc}, + {Py_tp_repr, array_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)arraytype_doc}, + {Py_tp_richcompare, array_richcompare}, + {Py_tp_iter, array_iter}, + {Py_tp_methods, array_methods}, + {Py_tp_members, array_members}, + {Py_tp_getset, array_getsets}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, array_new}, + {Py_tp_traverse, array_tp_traverse}, + + /* as sequence */ + {Py_sq_length, array_length}, + {Py_sq_concat, array_concat}, + {Py_sq_repeat, array_repeat}, + {Py_sq_item, array_item}, + {Py_sq_ass_item, array_ass_item}, + {Py_sq_contains, array_contains}, + {Py_sq_inplace_concat, array_inplace_concat}, + {Py_sq_inplace_repeat, array_inplace_repeat}, + + /* as mapping */ + {Py_mp_length, array_length}, + {Py_mp_subscript, array_subscr}, + {Py_mp_ass_subscript, array_ass_subscr}, + + /* as buffer */ + {Py_bf_getbuffer, array_buffer_getbuf}, + {Py_bf_releasebuffer, array_buffer_relbuf}, + + {0, NULL}, +}; + +static PyType_Spec array_spec = { + .name = "array.array", + .basicsize = sizeof(arrayobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_SEQUENCE), + .slots = array_slots, +}; /*********************** Array Iterator **************************/ /*[clinic input] -class array.arrayiterator "arrayiterobject *" "&PyArrayIter_Type" +class array.arrayiterator "arrayiterobject *" "find_array_state_by_type(type)->ArrayIterType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5aefd2d74d8c8e30]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fb46d5ef98dd95ff]*/ static PyObject * array_iter(arrayobject *ao) { + array_state *state = find_array_state_by_type(Py_TYPE(ao)); arrayiterobject *it; - if (!array_Check(ao)) { + if (!array_Check(ao, state)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type); + it = PyObject_GC_New(arrayiterobject, state->ArrayIterType); if (it == NULL) return NULL; @@ -2866,12 +2897,17 @@ arrayiter_next(arrayiterobject *it) arrayobject *ao; assert(it != NULL); - assert(PyArrayIter_Check(it)); +#ifndef NDEBUG + array_state *state = find_array_state_by_type(Py_TYPE(it)); + assert(PyObject_TypeCheck(it, state->ArrayIterType)); +#endif ao = it->ao; if (ao == NULL) { return NULL; } - assert(array_Check(ao)); +#ifndef NDEBUG + assert(array_Check(ao, state)); +#endif if (it->index < Py_SIZE(ao)) { return (*it->getitem)(ao, it->index++); } @@ -2883,14 +2919,18 @@ arrayiter_next(arrayiterobject *it) static void arrayiter_dealloc(arrayiterobject *it) { + PyTypeObject *tp = Py_TYPE(it); + PyObject_GC_UnTrack(it); Py_XDECREF(it->ao); PyObject_GC_Del(it); + Py_DECREF(tp); } static int arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(it)); Py_VISIT(it->ao); return 0; } @@ -2943,66 +2983,104 @@ static PyMethodDef arrayiter_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject PyArrayIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "arrayiterator", /* tp_name */ - sizeof(arrayiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)arrayiter_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)arrayiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)arrayiter_next, /* tp_iternext */ - arrayiter_methods, /* tp_methods */ +static PyType_Slot arrayiter_slots[] = { + {Py_tp_dealloc, arrayiter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, arrayiter_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, arrayiter_next}, + {Py_tp_methods, arrayiter_methods}, + {0, NULL}, +}; + +static PyType_Spec arrayiter_spec = { + .name = "array.arrayiterator", + .basicsize = sizeof(arrayiterobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = arrayiter_slots, }; /*********************** Install Module **************************/ +static int +array_traverse(PyObject *module, visitproc visit, void *arg) +{ + array_state *state = get_array_state(module); + Py_VISIT(state->ArrayType); + Py_VISIT(state->ArrayIterType); + return 0; +} + +static int +array_clear(PyObject *module) +{ + array_state *state = get_array_state(module); + Py_CLEAR(state->ArrayType); + Py_CLEAR(state->ArrayIterType); + return 0; +} + +static void +array_free(void *module) +{ + array_clear((PyObject *)module); +} + /* No functions in array module. */ static PyMethodDef a_methods[] = { ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF {NULL, NULL, 0, NULL} /* Sentinel */ }; +#define CREATE_TYPE(module, type, spec) \ +do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (type == NULL) { \ + return -1; \ + } \ +} while (0) + static int array_modexec(PyObject *m) { + array_state *state = get_array_state(m); char buffer[Py_ARRAY_LENGTH(descriptors)], *p; PyObject *typecodes; const struct arraydescr *descr; - if (PyType_Ready(&Arraytype) < 0) + CREATE_TYPE(m, state->ArrayType, &array_spec); + 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) { + Py_DECREF((PyObject *)state->ArrayType); return -1; - Py_SET_TYPE(&PyArrayIter_Type, &PyType_Type); + } - Py_INCREF((PyObject *)&Arraytype); - if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) { - Py_DECREF((PyObject *)&Arraytype); + 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); + if (!mutablesequence) { + Py_DECREF((PyObject *)state->ArrayType); + return -1; + } + PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O", + (PyObject *)state->ArrayType); + Py_DECREF(mutablesequence); + if (!res) { + Py_DECREF((PyObject *)state->ArrayType); return -1; } - Py_INCREF((PyObject *)&Arraytype); - if (PyModule_AddObject(m, "array", (PyObject *)&Arraytype) < 0) { - Py_DECREF((PyObject *)&Arraytype); + Py_DECREF(res); + + if (PyModule_AddType(m, state->ArrayType) < 0) { return -1; } @@ -3026,15 +3104,15 @@ static PyModuleDef_Slot arrayslots[] = { static struct PyModuleDef arraymodule = { - PyModuleDef_HEAD_INIT, - "array", - module_doc, - 0, - a_methods, - arrayslots, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "array", + .m_size = sizeof(array_state), + .m_doc = module_doc, + .m_methods = a_methods, + .m_slots = arrayslots, + .m_traverse = array_traverse, + .m_clear = array_clear, + .m_free = array_free, }; diff --git a/contrib/tools/python3/src/Modules/atexitmodule.c b/contrib/tools/python3/src/Modules/atexitmodule.c index 8cef64ceb9b..95c653cf478 100644 --- a/contrib/tools/python3/src/Modules/atexitmodule.c +++ b/contrib/tools/python3/src/Modules/atexitmodule.c @@ -7,117 +7,122 @@ */ #include "Python.h" - -/* Forward declaration (for atexit_cleanup) */ -static PyObject *atexit_clear(PyObject*, PyObject*); -/* Forward declaration of module object */ -static struct PyModuleDef atexitmodule; +#include "pycore_initconfig.h" // _PyStatus_NO_MEMORY +#include "pycore_interp.h" // PyInterpreterState.atexit +#include "pycore_pystate.h" // _PyInterpreterState_GET /* ===================================================================== */ /* Callback machinery. */ -typedef struct { - PyObject *func; - PyObject *args; - PyObject *kwargs; -} atexit_callback; - -typedef struct { - atexit_callback **atexit_callbacks; - int ncallbacks; - int callback_len; -} atexitmodule_state; - -static inline atexitmodule_state* -get_atexit_state(PyObject *module) +static inline struct atexit_state* +get_atexit_state(void) { - void *state = PyModule_GetState(module); - assert(state != NULL); - return (atexitmodule_state *)state; + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->atexit; } static void -atexit_delete_cb(atexitmodule_state *modstate, int i) +atexit_delete_cb(struct atexit_state *state, int i) { - atexit_callback *cb; + atexit_callback *cb = state->callbacks[i]; + state->callbacks[i] = NULL; - cb = modstate->atexit_callbacks[i]; - modstate->atexit_callbacks[i] = NULL; Py_DECREF(cb->func); Py_DECREF(cb->args); Py_XDECREF(cb->kwargs); PyMem_Free(cb); } + /* Clear all callbacks without calling them */ static void -atexit_cleanup(atexitmodule_state *modstate) +atexit_cleanup(struct atexit_state *state) { atexit_callback *cb; - int i; - for (i = 0; i < modstate->ncallbacks; i++) { - cb = modstate->atexit_callbacks[i]; + for (int i = 0; i < state->ncallbacks; i++) { + cb = state->callbacks[i]; if (cb == NULL) continue; - atexit_delete_cb(modstate, i); + atexit_delete_cb(state, i); } - modstate->ncallbacks = 0; + state->ncallbacks = 0; } -/* Installed into pylifecycle.c's atexit mechanism */ -static void -atexit_callfuncs(PyObject *module) +PyStatus +_PyAtExit_Init(PyInterpreterState *interp) { - PyObject *exc_type = NULL, *exc_value, *exc_tb, *r; - atexit_callback *cb; - atexitmodule_state *modstate; - int i; + struct atexit_state *state = &interp->atexit; + // _PyAtExit_Init() must only be called once + assert(state->callbacks == NULL); + + state->callback_len = 32; + state->ncallbacks = 0; + state->callbacks = PyMem_New(atexit_callback*, state->callback_len); + if (state->callbacks == NULL) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} - if (module == NULL) - return; - modstate = get_atexit_state(module); - if (modstate->ncallbacks == 0) - return; +void +_PyAtExit_Fini(PyInterpreterState *interp) +{ + struct atexit_state *state = &interp->atexit; + atexit_cleanup(state); + PyMem_Free(state->callbacks); + state->callbacks = NULL; +} - for (i = modstate->ncallbacks - 1; i >= 0; i--) - { - cb = modstate->atexit_callbacks[i]; - if (cb == NULL) +static void +atexit_callfuncs(struct atexit_state *state) +{ + assert(!PyErr_Occurred()); + + if (state->ncallbacks == 0) { + return; + } + + for (int i = state->ncallbacks - 1; i >= 0; i--) { + atexit_callback *cb = state->callbacks[i]; + if (cb == NULL) { continue; + } - r = PyObject_Call(cb->func, cb->args, cb->kwargs); - Py_XDECREF(r); - if (r == NULL) { - /* Maintain the last exception, but don't leak if there are - multiple exceptions. */ - if (exc_type) { - Py_DECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - } - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); - if (!PyErr_GivenExceptionMatches(exc_type, PyExc_SystemExit)) { - PySys_WriteStderr("Error in atexit._run_exitfuncs:\n"); - PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); - PyErr_Display(exc_type, exc_value, exc_tb); - } + // bpo-46025: Increment the refcount of cb->func as the call itself may unregister it + PyObject* the_func = Py_NewRef(cb->func); + PyObject *res = PyObject_Call(cb->func, cb->args, cb->kwargs); + if (res == NULL) { + _PyErr_WriteUnraisableMsg("in atexit callback", the_func); } + else { + Py_DECREF(res); + } + Py_DECREF(the_func); } - atexit_cleanup(modstate); + atexit_cleanup(state); + + assert(!PyErr_Occurred()); +} + - if (exc_type) - PyErr_Restore(exc_type, exc_value, exc_tb); +void +_PyAtExit_Call(PyInterpreterState *interp) +{ + struct atexit_state *state = &interp->atexit; + atexit_callfuncs(state); } + /* ===================================================================== */ /* Module methods. */ + PyDoc_STRVAR(atexit_register__doc__, "register(func, *args, **kwargs) -> func\n\ \n\ @@ -130,68 +135,63 @@ Register a function to be executed upon normal program termination\n\ func is returned to facilitate usage as a decorator."); static PyObject * -atexit_register(PyObject *self, PyObject *args, PyObject *kwargs) +atexit_register(PyObject *module, PyObject *args, PyObject *kwargs) { - atexitmodule_state *modstate; - atexit_callback *new_callback; - PyObject *func = NULL; - - modstate = get_atexit_state(self); - - if (modstate->ncallbacks >= modstate->callback_len) { - atexit_callback **r; - modstate->callback_len += 16; - r = (atexit_callback**)PyMem_Realloc(modstate->atexit_callbacks, - sizeof(atexit_callback*) * modstate->callback_len); - if (r == NULL) - return PyErr_NoMemory(); - modstate->atexit_callbacks = r; - } - if (PyTuple_GET_SIZE(args) == 0) { PyErr_SetString(PyExc_TypeError, "register() takes at least 1 argument (0 given)"); return NULL; } - func = PyTuple_GET_ITEM(args, 0); + PyObject *func = PyTuple_GET_ITEM(args, 0); if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "the first argument must be callable"); return NULL; } - new_callback = PyMem_Malloc(sizeof(atexit_callback)); - if (new_callback == NULL) + struct atexit_state *state = get_atexit_state(); + if (state->ncallbacks >= state->callback_len) { + atexit_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); + if (r == NULL) { + return PyErr_NoMemory(); + } + state->callbacks = r; + } + + atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback)); + if (callback == NULL) { return PyErr_NoMemory(); + } - new_callback->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); - if (new_callback->args == NULL) { - PyMem_Free(new_callback); + callback->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + if (callback->args == NULL) { + PyMem_Free(callback); return NULL; } - new_callback->func = func; - new_callback->kwargs = kwargs; - Py_INCREF(func); - Py_XINCREF(kwargs); + callback->func = Py_NewRef(func); + callback->kwargs = Py_XNewRef(kwargs); - modstate->atexit_callbacks[modstate->ncallbacks++] = new_callback; + state->callbacks[state->ncallbacks++] = callback; - Py_INCREF(func); - return func; + return Py_NewRef(func); } PyDoc_STRVAR(atexit_run_exitfuncs__doc__, "_run_exitfuncs() -> None\n\ \n\ -Run all registered exit functions."); +Run all registered exit functions.\n\ +\n\ +If a callaback raises an exception, it is logged with sys.unraisablehook."); static PyObject * -atexit_run_exitfuncs(PyObject *self, PyObject *unused) +atexit_run_exitfuncs(PyObject *module, PyObject *unused) { - atexit_callfuncs(self); - if (PyErr_Occurred()) - return NULL; + struct atexit_state *state = get_atexit_state(); + atexit_callfuncs(state); Py_RETURN_NONE; } @@ -201,9 +201,9 @@ PyDoc_STRVAR(atexit_clear__doc__, Clear the list of previously registered exit functions."); static PyObject * -atexit_clear(PyObject *self, PyObject *unused) +atexit_clear(PyObject *module, PyObject *unused) { - atexit_cleanup(get_atexit_state(self)); + atexit_cleanup(get_atexit_state()); Py_RETURN_NONE; } @@ -213,50 +213,10 @@ PyDoc_STRVAR(atexit_ncallbacks__doc__, Return the number of registered exit functions."); static PyObject * -atexit_ncallbacks(PyObject *self, PyObject *unused) -{ - atexitmodule_state *modstate; - - modstate = get_atexit_state(self); - - return PyLong_FromSsize_t(modstate->ncallbacks); -} - -static int -atexit_m_traverse(PyObject *self, visitproc visit, void *arg) -{ - int i; - atexitmodule_state *modstate; - - modstate = (atexitmodule_state *)PyModule_GetState(self); - - for (i = 0; i < modstate->ncallbacks; i++) { - atexit_callback *cb = modstate->atexit_callbacks[i]; - if (cb == NULL) - continue; - Py_VISIT(cb->func); - Py_VISIT(cb->args); - Py_VISIT(cb->kwargs); - } - return 0; -} - -static int -atexit_m_clear(PyObject *self) +atexit_ncallbacks(PyObject *module, PyObject *unused) { - atexitmodule_state *modstate; - modstate = (atexitmodule_state *)PyModule_GetState(self); - atexit_cleanup(modstate); - return 0; -} - -static void -atexit_free(PyObject *m) -{ - atexitmodule_state *modstate; - modstate = (atexitmodule_state *)PyModule_GetState(m); - atexit_cleanup(modstate); - PyMem_Free(modstate->atexit_callbacks); + struct atexit_state *state = get_atexit_state(); + return PyLong_FromSsize_t(state->ncallbacks); } PyDoc_STRVAR(atexit_unregister__doc__, @@ -268,29 +228,28 @@ atexit.register\n\ func - function to be unregistered"); static PyObject * -atexit_unregister(PyObject *self, PyObject *func) +atexit_unregister(PyObject *module, PyObject *func) { - atexitmodule_state *modstate; - atexit_callback *cb; - int i, eq; - - modstate = get_atexit_state(self); - - for (i = 0; i < modstate->ncallbacks; i++) + struct atexit_state *state = get_atexit_state(); + for (int i = 0; i < state->ncallbacks; i++) { - cb = modstate->atexit_callbacks[i]; - if (cb == NULL) + atexit_callback *cb = state->callbacks[i]; + if (cb == NULL) { continue; + } - eq = PyObject_RichCompareBool(cb->func, func, Py_EQ); - if (eq < 0) + int eq = PyObject_RichCompareBool(cb->func, func, Py_EQ); + if (eq < 0) { return NULL; - if (eq) - atexit_delete_cb(modstate, i); + } + if (eq) { + atexit_delete_cb(state, i); + } } Py_RETURN_NONE; } + static PyMethodDef atexit_methods[] = { {"register", (PyCFunction)(void(*)(void)) atexit_register, METH_VARARGS|METH_KEYWORDS, atexit_register__doc__}, @@ -305,47 +264,23 @@ static PyMethodDef atexit_methods[] = { {NULL, NULL} /* sentinel */ }; + /* ===================================================================== */ /* Initialization function. */ PyDoc_STRVAR(atexit__doc__, -"allow programmer to define multiple exit functions to be executed\ +"allow programmer to define multiple exit functions to be executed\n\ upon normal program termination.\n\ \n\ Two public functions, register and unregister, are defined.\n\ "); -static int -atexit_exec(PyObject *m) { - atexitmodule_state *modstate; - - modstate = get_atexit_state(m); - modstate->callback_len = 32; - modstate->ncallbacks = 0; - modstate->atexit_callbacks = PyMem_New(atexit_callback*, - modstate->callback_len); - if (modstate->atexit_callbacks == NULL) - return -1; - - _Py_PyAtExit(atexit_callfuncs, m); - return 0; -} - -static PyModuleDef_Slot atexit_slots[] = { - {Py_mod_exec, atexit_exec}, - {0, NULL} -}; - static struct PyModuleDef atexitmodule = { PyModuleDef_HEAD_INIT, - "atexit", - atexit__doc__, - sizeof(atexitmodule_state), - atexit_methods, - atexit_slots, - atexit_m_traverse, - atexit_m_clear, - (freefunc)atexit_free + .m_name = "atexit", + .m_doc = atexit__doc__, + .m_size = 0, + .m_methods = atexit_methods, }; PyMODINIT_FUNC diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h b/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h index e41755b197f..ba8fad26055 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h @@ -245,15 +245,13 @@ static const struct dbcs_map *mapping_list; static PyObject * getmultibytecodec(void) { - static PyObject *cofunc = NULL; - - if (cofunc == NULL) { - PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); - if (mod == NULL) - return NULL; - cofunc = PyObject_GetAttrString(mod, "__create_codec"); - Py_DECREF(mod); + PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); + if (mod == NULL) { + return NULL; } + + PyObject *cofunc = PyObject_GetAttrString(mod, "__create_codec"); + Py_DECREF(mod); return cofunc; } @@ -293,14 +291,11 @@ getcodec(PyObject *self, PyObject *encoding) r = PyObject_CallOneArg(cofunc, codecobj); Py_DECREF(codecobj); + Py_DECREF(cofunc); return r; } -static struct PyMethodDef __methods[] = { - {"getcodec", (PyCFunction)getcodec, METH_O, ""}, - {NULL, NULL}, -}; static int register_maps(PyObject *module) @@ -309,12 +304,17 @@ register_maps(PyObject *module) for (h = mapping_list; h->charset[0] != '\0'; h++) { char mhname[256] = "__map_"; - int r; strcpy(mhname + sizeof("__map_") - 1, h->charset); - r = PyModule_AddObject(module, mhname, - PyCapsule_New((void *)h, PyMultibyteCodec_CAPSULE_NAME, NULL)); - if (r == -1) + + PyObject *capsule = PyCapsule_New((void *)h, + PyMultibyteCodec_CAPSULE_NAME, NULL); + if (capsule == NULL) { + return -1; + } + if (PyModule_AddObject(module, mhname, capsule) < 0) { + Py_DECREF(capsule); return -1; + } } return 0; } @@ -395,25 +395,36 @@ errorexit: } #endif +static int +_cjk_exec(PyObject *module) +{ + return register_maps(module); +} + + +static struct PyMethodDef _cjk_methods[] = { + {"getcodec", (PyCFunction)getcodec, METH_O, ""}, + {NULL, NULL}, +}; + +static PyModuleDef_Slot _cjk_slots[] = { + {Py_mod_exec, _cjk_exec}, + {0, NULL} +}; + #define I_AM_A_MODULE_FOR(loc) \ - static struct PyModuleDef __module = { \ + static struct PyModuleDef _cjk_module = { \ PyModuleDef_HEAD_INIT, \ - "_codecs_"#loc, \ - NULL, \ - 0, \ - __methods, \ - NULL, \ - NULL, \ - NULL, \ - NULL \ + .m_name = "_codecs_"#loc, \ + .m_size = 0, \ + .m_methods = _cjk_methods, \ + .m_slots = _cjk_slots, \ }; \ + \ PyMODINIT_FUNC \ PyInit__codecs_##loc(void) \ { \ - PyObject *m = PyModule_Create(&__module); \ - if (m != NULL) \ - (void)register_maps(m); \ - return m; \ + return PyModuleDef_Init(&_cjk_module); \ } #endif diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h b/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h index 5ddbbe221b9..563888370d0 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -171,11 +171,6 @@ _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderOb if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[1]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -288,11 +283,6 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[1]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -525,4 +515,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=5ce6fd4ca1f95620 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c0f74129db07c87 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c index 86402768b6e..ba558d0dbf2 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c @@ -10,11 +10,44 @@ #include "multibytecodec.h" #include "clinic/multibytecodec.c.h" +#define MODULE_NAME "_multibytecodec" + +typedef struct { + PyTypeObject *encoder_type; + PyTypeObject *decoder_type; + PyTypeObject *reader_type; + PyTypeObject *writer_type; + PyTypeObject *multibytecodec_type; +} _multibytecodec_state; + +static _multibytecodec_state * +_multibytecodec_get_state(PyObject *module) +{ + _multibytecodec_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) +{ + PyObject *module = _PyType_GetModuleByDef(type, &_multibytecodecmodule); + assert(module != NULL); + return _multibytecodec_get_state(module); +} + +#define clinic_get_state() _multibyte_codec_find_state_by_type(type) /*[clinic input] module _multibytecodec -class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" +class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "clinic_get_state()->multibytecodec_type" +class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "clinic_get_state()->encoder_type" +class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "clinic_get_state()->decoder_type" +class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "clinic_get_state()->reader_type" +class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "clinic_get_state()->writer_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6ad689546cbb5450]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=305a76dfdd24b99c]*/ +#undef clinic_get_state typedef struct { PyObject *inobj; @@ -688,42 +721,36 @@ static struct PyMethodDef multibytecodec_methods[] = { {NULL, NULL}, }; +static int +multibytecodec_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static void multibytecodec_dealloc(MultibyteCodecObject *self) { - PyObject_Del(self); + PyObject_GC_UnTrack(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteCodec_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteCodec", /* tp_name */ - sizeof(MultibyteCodecObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)multibytecodec_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, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - multibytecodec_methods, /* tp_methods */ +static PyType_Slot multibytecodec_slots[] = { + {Py_tp_dealloc, multibytecodec_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_methods, multibytecodec_methods}, + {Py_tp_traverse, multibytecodec_traverse}, + {0, NULL}, +}; + +static PyType_Spec multibytecodec_spec = { + .name = MODULE_NAME ".MultibyteCodec", + .basicsize = sizeof(MultibyteCodecObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = multibytecodec_slots, }; @@ -868,11 +895,6 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, } -/*[clinic input] - class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ - /*[clinic input] _multibytecodec.MultibyteIncrementalEncoder.encode @@ -1024,7 +1046,9 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1065,60 +1089,33 @@ mbiencoder_traverse(MultibyteIncrementalEncoderObject *self, static void mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_CLEAR(self->pending); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteIncrementalEncoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteIncrementalEncoder", /* tp_name */ - sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbiencoder_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 */ - 0, /* tp_doc */ - (traverseproc)mbiencoder_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbiencoder_methods, /* tp_methods */ - 0, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbiencoder_init, /* tp_init */ - 0, /* tp_alloc */ - mbiencoder_new, /* tp_new */ +static PyType_Slot encoder_slots[] = { + {Py_tp_dealloc, mbiencoder_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbiencoder_traverse}, + {Py_tp_methods, mbiencoder_methods}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbiencoder_init}, + {Py_tp_new, mbiencoder_new}, + {0, NULL}, }; +static PyType_Spec encoder_spec = { + .name = MODULE_NAME ".MultibyteIncrementalEncoder", + .basicsize = sizeof(MultibyteIncrementalEncoderObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = encoder_slots, +}; -/*[clinic input] - class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/ /*[clinic input] _multibytecodec.MultibyteIncrementalDecoder.decode @@ -1191,13 +1188,13 @@ _multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDeco goto errorexit; if (wdata != data) - PyMem_Del(wdata); + PyMem_Free(wdata); Py_XDECREF(buf.excobj); return res; errorexit: if (wdata != NULL && wdata != data) - PyMem_Del(wdata); + PyMem_Free(wdata); Py_XDECREF(buf.excobj); _PyUnicodeWriter_Dealloc(&buf.writer); return NULL; @@ -1324,7 +1321,9 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1365,59 +1364,31 @@ mbidecoder_traverse(MultibyteIncrementalDecoderObject *self, static void mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteIncrementalDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteIncrementalDecoder", /* tp_name */ - sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbidecoder_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 */ - 0, /* tp_doc */ - (traverseproc)mbidecoder_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbidecoder_methods, /* tp_methods */ - 0, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbidecoder_init, /* tp_init */ - 0, /* tp_alloc */ - mbidecoder_new, /* tp_new */ +static PyType_Slot decoder_slots[] = { + {Py_tp_dealloc, mbidecoder_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbidecoder_traverse}, + {Py_tp_methods, mbidecoder_methods}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbidecoder_init}, + {Py_tp_new, mbidecoder_new}, + {0, NULL}, }; - -/*[clinic input] - class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/ +static PyType_Spec decoder_spec = { + .name = MODULE_NAME ".MultibyteIncrementalDecoder", + .basicsize = sizeof(MultibyteIncrementalDecoderObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = decoder_slots, +}; static PyObject * mbstreamreader_iread(MultibyteStreamReaderObject *self, @@ -1667,7 +1638,9 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1711,60 +1684,33 @@ mbstreamreader_traverse(MultibyteStreamReaderObject *self, static void mbstreamreader_dealloc(MultibyteStreamReaderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteStreamReader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteStreamReader", /* tp_name */ - sizeof(MultibyteStreamReaderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbstreamreader_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 */ - 0, /* tp_doc */ - (traverseproc)mbstreamreader_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbstreamreader_methods, /* tp_methods */ - mbstreamreader_members, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbstreamreader_init, /* tp_init */ - 0, /* tp_alloc */ - mbstreamreader_new, /* tp_new */ +static PyType_Slot reader_slots[] = { + {Py_tp_dealloc, mbstreamreader_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbstreamreader_traverse}, + {Py_tp_methods, mbstreamreader_methods}, + {Py_tp_members, mbstreamreader_members}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbstreamreader_init}, + {Py_tp_new, mbstreamreader_new}, + {0, NULL}, }; - -/*[clinic input] - class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/ +static PyType_Spec reader_spec = { + .name = MODULE_NAME ".MultibyteStreamReader", + .basicsize = sizeof(MultibyteStreamReaderObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = reader_slots, +}; static int mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, @@ -1899,7 +1845,9 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1943,10 +1891,12 @@ mbstreamwriter_traverse(MultibyteStreamWriterObject *self, static void mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } static struct PyMethodDef mbstreamwriter_methods[] = { @@ -1963,47 +1913,24 @@ static PyMemberDef mbstreamwriter_members[] = { {NULL,} }; -static PyTypeObject MultibyteStreamWriter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteStreamWriter", /* tp_name */ - sizeof(MultibyteStreamWriterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbstreamwriter_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 */ - 0, /* tp_doc */ - (traverseproc)mbstreamwriter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbstreamwriter_methods, /* tp_methods */ - mbstreamwriter_members, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbstreamwriter_init, /* tp_init */ - 0, /* tp_alloc */ - mbstreamwriter_new, /* tp_new */ +static PyType_Slot writer_slots[] = { + {Py_tp_dealloc, mbstreamwriter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbstreamwriter_traverse}, + {Py_tp_methods, mbstreamwriter_methods}, + {Py_tp_members, mbstreamwriter_members}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbstreamwriter_init}, + {Py_tp_new, mbstreamwriter_new}, + {0, NULL}, +}; + +static PyType_Spec writer_spec = { + .name = MODULE_NAME ".MultibyteStreamWriter", + .basicsize = sizeof(MultibyteStreamWriterObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = writer_slots, }; @@ -2030,59 +1957,104 @@ _multibytecodec___create_codec(PyObject *module, PyObject *arg) if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) return NULL; - self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type); + _multibytecodec_state *state = _multibytecodec_get_state(module); + self = PyObject_GC_New(MultibyteCodecObject, state->multibytecodec_type); if (self == NULL) return NULL; self->codec = codec; + PyObject_GC_Track(self); return (PyObject *)self; } -static struct PyMethodDef __methods[] = { +static int +_multibytecodec_traverse(PyObject *mod, visitproc visit, void *arg) +{ + _multibytecodec_state *state = _multibytecodec_get_state(mod); + Py_VISIT(state->multibytecodec_type); + Py_VISIT(state->encoder_type); + Py_VISIT(state->decoder_type); + Py_VISIT(state->reader_type); + Py_VISIT(state->writer_type); + return 0; +} + +static int +_multibytecodec_clear(PyObject *mod) +{ + _multibytecodec_state *state = _multibytecodec_get_state(mod); + Py_CLEAR(state->multibytecodec_type); + Py_CLEAR(state->encoder_type); + Py_CLEAR(state->decoder_type); + Py_CLEAR(state->reader_type); + Py_CLEAR(state->writer_type); + return 0; +} + +static void +_multibytecodec_free(void *mod) +{ + _multibytecodec_clear((PyObject *)mod); +} + +#define CREATE_TYPE(module, type, spec) \ + do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (!type) { \ + return -1; \ + } \ + } while (0) + +#define ADD_TYPE(module, type) \ + do { \ + if (PyModule_AddType(module, type) < 0) { \ + return -1; \ + } \ + } while (0) + +static int +_multibytecodec_exec(PyObject *mod) +{ + _multibytecodec_state *state = _multibytecodec_get_state(mod); + CREATE_TYPE(mod, state->multibytecodec_type, &multibytecodec_spec); + CREATE_TYPE(mod, state->encoder_type, &encoder_spec); + CREATE_TYPE(mod, state->decoder_type, &decoder_spec); + CREATE_TYPE(mod, state->reader_type, &reader_spec); + CREATE_TYPE(mod, state->writer_type, &writer_spec); + + ADD_TYPE(mod, state->encoder_type); + ADD_TYPE(mod, state->decoder_type); + ADD_TYPE(mod, state->reader_type); + ADD_TYPE(mod, state->writer_type); + return 0; +} + +#undef CREATE_TYPE +#undef ADD_TYPE + +static struct PyMethodDef _multibytecodec_methods[] = { _MULTIBYTECODEC___CREATE_CODEC_METHODDEF {NULL, NULL}, }; +static PyModuleDef_Slot _multibytecodec_slots[] = { + {Py_mod_exec, _multibytecodec_exec}, + {0, NULL} +}; static struct PyModuleDef _multibytecodecmodule = { - PyModuleDef_HEAD_INIT, - "_multibytecodec", - NULL, - -1, - __methods, - NULL, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_multibytecodec", + .m_size = sizeof(_multibytecodec_state), + .m_methods = _multibytecodec_methods, + .m_slots = _multibytecodec_slots, + .m_traverse = _multibytecodec_traverse, + .m_clear = _multibytecodec_clear, + .m_free = _multibytecodec_free, }; PyMODINIT_FUNC PyInit__multibytecodec(void) { - PyObject *m; - PyTypeObject *typelist[] = { - &MultibyteIncrementalEncoder_Type, - &MultibyteIncrementalDecoder_Type, - &MultibyteStreamReader_Type, - &MultibyteStreamWriter_Type - }; - - if (PyType_Ready(&MultibyteCodec_Type) < 0) - return NULL; - - m = PyModule_Create(&_multibytecodecmodule); - if (m == NULL) - return NULL; - - for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { - if (PyModule_AddType(m, typelist[i]) < 0) { - return NULL; - } - } - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; - } - return m; + return PyModuleDef_Init(&_multibytecodecmodule); } diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h index 59468210b97..69404ba96aa 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h @@ -65,7 +65,7 @@ typedef struct { MultibyteCodec *codec; } MultibyteCodecObject; -#define MultibyteCodec_Check(op) Py_IS_TYPE((op), &MultibyteCodec_Type) +#define MultibyteCodec_Check(state, op) Py_IS_TYPE((op), state->multibytecodec_type) #define _MultibyteStatefulCodec_HEAD \ PyObject_HEAD \ diff --git a/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h b/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h index a071efc1e2b..c472e652fb7 100644 --- a/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h @@ -669,6 +669,45 @@ _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)(void(*)(void))_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" @@ -832,4 +871,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=d0fc522bcbff9d61 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0d127162ac92e0c0 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_bisectmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_bisectmodule.c.h index 80ab7048f14..f118f4bbf86 100644 --- a/contrib/tools/python3/src/Modules/clinic/_bisectmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_bisectmodule.c.h @@ -3,14 +3,14 @@ preserve [clinic start generated code]*/ PyDoc_STRVAR(_bisect_bisect_right__doc__, -"bisect_right($module, /, a, x, lo=0, hi=None)\n" +"bisect_right($module, /, a, x, lo=0, hi=None, *, key=None)\n" "--\n" "\n" "Return the index where to insert item x in list a, assuming a is sorted.\n" "\n" "The return value i is such that all e in a[:i] have e <= x, and all e in\n" -"a[i:] have e > x. So if x already appears in the list, i points just\n" -"beyond the rightmost x already there\n" +"a[i:] have e > x. So if x already appears in the list, a.insert(i, x) will\n" +"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."); @@ -20,20 +20,21 @@ PyDoc_STRVAR(_bisect_bisect_right__doc__, static Py_ssize_t _bisect_bisect_right_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi); + Py_ssize_t lo, Py_ssize_t hi, PyObject *key); static PyObject * _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"a", "x", "lo", "hi", NULL}; + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "bisect_right", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; PyObject *x; Py_ssize_t lo = 0; Py_ssize_t hi = -1; + PyObject *key = Py_None; Py_ssize_t _return_value; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); @@ -46,14 +47,9 @@ _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -67,11 +63,21 @@ _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } } - if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { - goto exit; + if (args[3]) { + if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } skip_optional_pos: - _return_value = _bisect_bisect_right_impl(module, a, x, lo, hi); + if (!noptargs) { + goto skip_optional_kwonly; + } + key = args[4]; +skip_optional_kwonly: + _return_value = _bisect_bisect_right_impl(module, a, x, lo, hi, key); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } @@ -82,7 +88,7 @@ exit: } PyDoc_STRVAR(_bisect_insort_right__doc__, -"insort_right($module, /, a, x, lo=0, hi=None)\n" +"insort_right($module, /, a, x, lo=0, hi=None, *, key=None)\n" "--\n" "\n" "Insert item x in list a, and keep it sorted assuming a is sorted.\n" @@ -97,20 +103,21 @@ PyDoc_STRVAR(_bisect_insort_right__doc__, static PyObject * _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi); + Py_ssize_t lo, Py_ssize_t hi, PyObject *key); static PyObject * _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"a", "x", "lo", "hi", NULL}; + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "insort_right", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; PyObject *x; Py_ssize_t lo = 0; Py_ssize_t hi = -1; + PyObject *key = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); if (!args) { @@ -122,14 +129,9 @@ _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -143,25 +145,35 @@ _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } } - if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { - goto exit; + if (args[3]) { + if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } skip_optional_pos: - return_value = _bisect_insort_right_impl(module, a, x, lo, hi); + if (!noptargs) { + goto skip_optional_kwonly; + } + key = args[4]; +skip_optional_kwonly: + return_value = _bisect_insort_right_impl(module, a, x, lo, hi, key); exit: return return_value; } PyDoc_STRVAR(_bisect_bisect_left__doc__, -"bisect_left($module, /, a, x, lo=0, hi=None)\n" +"bisect_left($module, /, a, x, lo=0, hi=None, *, key=None)\n" "--\n" "\n" "Return the index where to insert item x in list a, assuming a is sorted.\n" "\n" "The return value i is such that all e in a[:i] have e < x, and all e in\n" -"a[i:] have e >= x. So if x already appears in the list, i points just\n" -"before the leftmost x already there.\n" +"a[i:] have e >= x. So if x already appears in the list, a.insert(i, x) will\n" +"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."); @@ -171,20 +183,21 @@ PyDoc_STRVAR(_bisect_bisect_left__doc__, static Py_ssize_t _bisect_bisect_left_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi); + Py_ssize_t lo, Py_ssize_t hi, PyObject *key); static PyObject * _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"a", "x", "lo", "hi", NULL}; + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "bisect_left", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; PyObject *x; Py_ssize_t lo = 0; Py_ssize_t hi = -1; + PyObject *key = Py_None; Py_ssize_t _return_value; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); @@ -197,14 +210,9 @@ _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P goto skip_optional_pos; } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -218,11 +226,21 @@ _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P goto skip_optional_pos; } } - if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { - goto exit; + if (args[3]) { + if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } skip_optional_pos: - _return_value = _bisect_bisect_left_impl(module, a, x, lo, hi); + if (!noptargs) { + goto skip_optional_kwonly; + } + key = args[4]; +skip_optional_kwonly: + _return_value = _bisect_bisect_left_impl(module, a, x, lo, hi, key); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } @@ -233,7 +251,7 @@ exit: } PyDoc_STRVAR(_bisect_insort_left__doc__, -"insort_left($module, /, a, x, lo=0, hi=None)\n" +"insort_left($module, /, a, x, lo=0, hi=None, *, key=None)\n" "--\n" "\n" "Insert item x in list a, and keep it sorted assuming a is sorted.\n" @@ -248,20 +266,21 @@ PyDoc_STRVAR(_bisect_insort_left__doc__, static PyObject * _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, - Py_ssize_t lo, Py_ssize_t hi); + Py_ssize_t lo, Py_ssize_t hi, PyObject *key); static PyObject * _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"a", "x", "lo", "hi", NULL}; + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "insort_left", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; PyObject *x; Py_ssize_t lo = 0; Py_ssize_t hi = -1; + PyObject *key = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); if (!args) { @@ -273,14 +292,9 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P goto skip_optional_pos; } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -294,13 +308,23 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P goto skip_optional_pos; } } - if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { - goto exit; + if (args[3]) { + if (!_Py_convert_optional_to_ssize_t(args[3], &hi)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } skip_optional_pos: - return_value = _bisect_insort_left_impl(module, a, x, lo, hi); + if (!noptargs) { + goto skip_optional_kwonly; + } + key = args[4]; +skip_optional_kwonly: + return_value = _bisect_insort_left_impl(module, a, x, lo, hi, key); exit: return return_value; } -/*[clinic end generated code: output=bcbd6c77331a08f0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aeb97db6db79bf96 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h b/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h index 0eb6280d6e0..71ad0b13571 100644 --- a/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h @@ -65,52 +65,6 @@ _bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored)) return _bz2_BZ2Compressor_flush_impl(self); } -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___impl(BZ2Compressor *self, int compresslevel); - -static int -_bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - int compresslevel = 9; - - if (Py_IS_TYPE(self, &BZ2Compressor_Type) && - !_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; - } - if (PyFloat_Check(PyTuple_GET_ITEM(args, 0))) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - 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; -} - PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__, "decompress($self, /, data, max_length=-1)\n" "--\n" @@ -162,14 +116,9 @@ _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -190,34 +139,4 @@ exit: return return_value; } - -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 int -_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self); - -static int -_bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - - if (Py_IS_TYPE(self, &BZ2Decompressor_Type) && - !_PyArg_NoPositional("BZ2Decompressor", args)) { - goto exit; - } - if (Py_IS_TYPE(self, &BZ2Decompressor_Type) && - !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { - goto exit; - } - return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self); - -exit: - return return_value; -} -/*[clinic end generated code: output=3f3f1e788fe28ee1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ed10705d7a9fd598 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h index 7ddc36de8a7..855ac77a7f7 100644 --- a/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h @@ -15,6 +15,17 @@ PyDoc_STRVAR(_codecs_register__doc__, #define _CODECS_REGISTER_METHODDEF \ {"register", (PyCFunction)_codecs_register, METH_O, _codecs_register__doc__}, +PyDoc_STRVAR(_codecs_unregister__doc__, +"unregister($module, search_function, /)\n" +"--\n" +"\n" +"Unregister a codec search function and clear the registry\'s cache.\n" +"\n" +"If the search function is not registered, do nothing."); + +#define _CODECS_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)_codecs_unregister, METH_O, _codecs_unregister__doc__}, + PyDoc_STRVAR(_codecs_lookup__doc__, "lookup($module, encoding, /)\n" "--\n" @@ -206,43 +217,6 @@ exit: return return_value; } -PyDoc_STRVAR(_codecs__forget_codec__doc__, -"_forget_codec($module, encoding, /)\n" -"--\n" -"\n" -"Purge the named codec from the internal codec lookup cache"); - -#define _CODECS__FORGET_CODEC_METHODDEF \ - {"_forget_codec", (PyCFunction)_codecs__forget_codec, METH_O, _codecs__forget_codec__doc__}, - -static PyObject * -_codecs__forget_codec_impl(PyObject *module, const char *encoding); - -static PyObject * -_codecs__forget_codec(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *encoding; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("_forget_codec", "argument", "str", arg); - goto exit; - } - Py_ssize_t encoding_length; - encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length); - if (encoding == NULL) { - goto exit; - } - if (strlen(encoding) != (size_t)encoding_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - return_value = _codecs__forget_codec_impl(module, encoding); - -exit: - return return_value; -} - PyDoc_STRVAR(_codecs_escape_decode__doc__, "escape_decode($module, data, errors=None, /)\n" "--\n" @@ -424,11 +398,6 @@ _codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -499,11 +468,6 @@ _codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -574,11 +538,6 @@ _codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -649,11 +608,6 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -724,11 +678,6 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -801,11 +750,6 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } byteorder = _PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; @@ -813,11 +757,6 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[3]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -888,11 +827,6 @@ _codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -963,11 +897,6 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1038,11 +967,6 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1115,11 +1039,6 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } byteorder = _PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; @@ -1127,11 +1046,6 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[3]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1212,11 +1126,6 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1297,11 +1206,6 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1565,11 +1469,6 @@ _codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1644,11 +1543,6 @@ _codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[2]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1693,11 +1587,6 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("code_page_decode", nargs, 2, 4)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } codepage = _PyLong_AsInt(args[0]); if (codepage == -1 && PyErr_Occurred()) { goto exit; @@ -1733,11 +1622,6 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[3]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -1999,11 +1883,6 @@ _codecs_utf_16_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } byteorder = _PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; @@ -2186,11 +2065,6 @@ _codecs_utf_32_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } byteorder = _PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; @@ -2791,11 +2665,6 @@ _codecs_code_page_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("code_page_encode", nargs, 2, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } code_page = _PyLong_AsInt(args[0]); if (code_page == -1 && PyErr_Occurred()) { goto exit; @@ -2948,4 +2817,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=eed7dc9312baf252 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=814dae36b6f885cb input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_collectionsmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_collectionsmodule.c.h index c3ba1a66985..7e18aeb312c 100644 --- a/contrib/tools/python3/src/Modules/clinic/_collectionsmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_collectionsmodule.c.h @@ -50,14 +50,9 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!_PyArg_CheckPositional("_tuplegetter", PyTuple_GET_SIZE(args), 2, 2)) { goto exit; } - if (PyFloat_Check(PyTuple_GET_ITEM(args, 0))) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(PyTuple_GET_ITEM(args, 0)); + PyObject *iobj = _PyNumber_Index(PyTuple_GET_ITEM(args, 0)); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -73,4 +68,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=9d2bfcc9df5faf35 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=947186d369f50f1e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_curses_panel.c.h b/contrib/tools/python3/src/Modules/clinic/_curses_panel.c.h index 9840ed86e79..45898070b1f 100644 --- a/contrib/tools/python3/src/Modules/clinic/_curses_panel.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_curses_panel.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "Push the panel to the bottom of the stack."); #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ - {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__}, + {"bottom", (PyCFunction)(void(*)(void))_curses_panel_panel_bottom, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, static PyObject * -_curses_panel_panel_bottom_impl(PyCursesPanelObject *self); +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_bottom(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_bottom_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":bottom", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_bottom_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_hide__doc__, @@ -29,15 +40,26 @@ PyDoc_STRVAR(_curses_panel_panel_hide__doc__, "This does not delete the object, it just makes the window on screen invisible."); #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ - {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__}, + {"hide", (PyCFunction)(void(*)(void))_curses_panel_panel_hide, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, static PyObject * -_curses_panel_panel_hide_impl(PyCursesPanelObject *self); +_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_hide(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_hide_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":hide", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_hide_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_show__doc__, @@ -47,15 +69,26 @@ PyDoc_STRVAR(_curses_panel_panel_show__doc__, "Display the panel (which might have been hidden)."); #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ - {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__}, + {"show", (PyCFunction)(void(*)(void))_curses_panel_panel_show, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, static PyObject * -_curses_panel_panel_show_impl(PyCursesPanelObject *self); +_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_show(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_show_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":show", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_show_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_top__doc__, @@ -65,15 +98,26 @@ PyDoc_STRVAR(_curses_panel_panel_top__doc__, "Push panel to the top of the stack."); #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ - {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__}, + {"top", (PyCFunction)(void(*)(void))_curses_panel_panel_top, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, static PyObject * -_curses_panel_panel_top_impl(PyCursesPanelObject *self); +_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_top(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_top_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":top", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_top_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_above__doc__, @@ -137,40 +181,26 @@ PyDoc_STRVAR(_curses_panel_panel_move__doc__, "Move the panel to the screen coordinates (y, x)."); #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ - {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_FASTCALL, _curses_panel_panel_move__doc__}, + {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, static PyObject * -_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x); +_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, + int y, int x); static PyObject * -_curses_panel_panel_move(PyCursesPanelObject *self, PyObject *const *args, Py_ssize_t nargs) +_curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"ii:move", _keywords, 0}; int y; int x; - if (!_PyArg_CheckPositional("move", nargs, 2, 2)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - y = _PyLong_AsInt(args[0]); - if (y == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - x = _PyLong_AsInt(args[1]); - if (x == -1 && PyErr_Occurred()) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &y, &x)) { goto exit; } - return_value = _curses_panel_panel_move_impl(self, y, x); + return_value = _curses_panel_panel_move_impl(self, cls, y, x); exit: return return_value; @@ -201,24 +231,26 @@ PyDoc_STRVAR(_curses_panel_panel_replace__doc__, "Change the window associated with the panel to the window win."); #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ - {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__}, + {"replace", (PyCFunction)(void(*)(void))_curses_panel_panel_replace, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, static PyObject * _curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyTypeObject *cls, PyCursesWindowObject *win); static PyObject * -_curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) +_curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O!:replace", _keywords, 0}; PyCursesWindowObject *win; - if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { - _PyArg_BadArgument("replace", "argument", (&PyCursesWindow_Type)->tp_name, arg); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &PyCursesWindow_Type, &win)) { goto exit; } - win = (PyCursesWindowObject *)arg; - return_value = _curses_panel_panel_replace_impl(self, win); + return_value = _curses_panel_panel_replace_impl(self, cls, win); exit: return return_value; @@ -231,7 +263,29 @@ PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, "Set the panel\'s user pointer to obj."); #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ - {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__}, + {"set_userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_set_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, + +static PyObject * +_curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, + PyTypeObject *cls, PyObject *obj); + +static PyObject * +_curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:set_userptr", _keywords, 0}; + PyObject *obj; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &obj)) { + goto exit; + } + return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); + +exit: + return return_value; +} PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, "userptr($self, /)\n" @@ -240,15 +294,27 @@ PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, "Return the user pointer for the panel."); #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ - {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__}, + {"userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, static PyObject * -_curses_panel_panel_userptr_impl(PyCursesPanelObject *self); +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self, + PyTypeObject *cls); static PyObject * -_curses_panel_panel_userptr(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_userptr_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":userptr", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_userptr_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, @@ -335,4 +401,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=d96dc1fd68e898d9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3081ef24e5560cb0 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h index 66ffcdfdb3f..9c9611685b7 100644 --- a/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h @@ -252,11 +252,6 @@ _curses_window_bkgd(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_ if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } attr = PyLong_AsLong(args[1]); if (attr == -1 && PyErr_Occurred()) { goto exit; @@ -286,11 +281,6 @@ _curses_window_attroff(PyCursesWindowObject *self, PyObject *arg) PyObject *return_value = NULL; long attr; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } attr = PyLong_AsLong(arg); if (attr == -1 && PyErr_Occurred()) { goto exit; @@ -319,11 +309,6 @@ _curses_window_attron(PyCursesWindowObject *self, PyObject *arg) PyObject *return_value = NULL; long attr; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } attr = PyLong_AsLong(arg); if (attr == -1 && PyErr_Occurred()) { goto exit; @@ -352,11 +337,6 @@ _curses_window_attrset(PyCursesWindowObject *self, PyObject *arg) PyObject *return_value = NULL; long attr; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } attr = PyLong_AsLong(arg); if (attr == -1 && PyErr_Occurred()) { goto exit; @@ -399,11 +379,6 @@ _curses_window_bkgdset(PyCursesWindowObject *self, PyObject *const *args, Py_ssi if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } attr = PyLong_AsLong(args[1]); if (attr == -1 && PyErr_Occurred()) { goto exit; @@ -534,8 +509,8 @@ _curses_window_box(PyCursesWindowObject *self, PyObject *args) { PyObject *return_value = NULL; int group_right_1 = 0; - PyObject *verch = _PyLong_Zero; - PyObject *horch = _PyLong_Zero; + PyObject *verch = _PyLong_GetZero(); + PyObject *horch = _PyLong_GetZero(); switch (PyTuple_GET_SIZE(args)) { case 0: @@ -687,11 +662,6 @@ _curses_window_echochar(PyCursesWindowObject *self, PyObject *const *args, Py_ss if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } attr = PyLong_AsLong(args[1]); if (attr == -1 && PyErr_Occurred()) { goto exit; @@ -719,7 +689,7 @@ PyDoc_STRVAR(_curses_window_enclose__doc__, #define _CURSES_WINDOW_ENCLOSE_METHODDEF \ {"enclose", (PyCFunction)(void(*)(void))_curses_window_enclose, METH_FASTCALL, _curses_window_enclose__doc__}, -static long +static PyObject * _curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x); static PyObject * @@ -728,34 +698,19 @@ _curses_window_enclose(PyCursesWindowObject *self, PyObject *const *args, Py_ssi PyObject *return_value = NULL; int y; int x; - long _return_value; if (!_PyArg_CheckPositional("enclose", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } y = _PyLong_AsInt(args[0]); if (y == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } x = _PyLong_AsInt(args[1]); if (x == -1 && PyErr_Occurred()) { goto exit; } - _return_value = _curses_window_enclose_impl(self, y, x); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong(_return_value); + return_value = _curses_window_enclose_impl(self, y, x); exit: return return_value; @@ -1303,11 +1258,6 @@ _curses_window_is_linetouched(PyCursesWindowObject *self, PyObject *arg) PyObject *return_value = NULL; int line; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } line = _PyLong_AsInt(arg); if (line == -1 && PyErr_Occurred()) { goto exit; @@ -1552,20 +1502,10 @@ _curses_window_redrawln(PyCursesWindowObject *self, PyObject *const *args, Py_ss if (!_PyArg_CheckPositional("redrawln", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } beg = _PyLong_AsInt(args[0]); if (beg == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } num = _PyLong_AsInt(args[1]); if (num == -1 && PyErr_Occurred()) { goto exit; @@ -1661,20 +1601,10 @@ _curses_window_setscrreg(PyCursesWindowObject *self, PyObject *const *args, Py_s if (!_PyArg_CheckPositional("setscrreg", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } top = _PyLong_AsInt(args[0]); if (top == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } bottom = _PyLong_AsInt(args[1]); if (bottom == -1 && PyErr_Occurred()) { goto exit; @@ -2005,11 +1935,6 @@ _curses_cbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(args[0]); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -2037,38 +1962,17 @@ PyDoc_STRVAR(_curses_color_content__doc__, {"color_content", (PyCFunction)_curses_color_content, METH_O, _curses_color_content__doc__}, static PyObject * -_curses_color_content_impl(PyObject *module, short color_number); +_curses_color_content_impl(PyObject *module, int color_number); static PyObject * _curses_color_content(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - short color_number; + int color_number; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!color_converter(arg, &color_number)) { goto exit; } - { - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - color_number = (short) ival; - } - } return_value = _curses_color_content_impl(module, color_number); exit: @@ -2091,38 +1995,18 @@ PyDoc_STRVAR(_curses_color_pair__doc__, {"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__}, static PyObject * -_curses_color_pair_impl(PyObject *module, short pair_number); +_curses_color_pair_impl(PyObject *module, int pair_number); static PyObject * _curses_color_pair(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - short pair_number; + int pair_number; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + pair_number = _PyLong_AsInt(arg); + if (pair_number == -1 && PyErr_Occurred()) { goto exit; } - { - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - pair_number = (short) ival; - } - } return_value = _curses_color_pair_impl(module, pair_number); exit: @@ -2155,11 +2039,6 @@ _curses_curs_set(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int visibility; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } visibility = _PyLong_AsInt(arg); if (visibility == -1 && PyErr_Occurred()) { goto exit; @@ -2235,11 +2114,6 @@ _curses_delay_output(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int ms; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } ms = _PyLong_AsInt(arg); if (ms == -1 && PyErr_Occurred()) { goto exit; @@ -2297,11 +2171,6 @@ _curses_echo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(args[0]); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -2469,11 +2338,6 @@ _curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ungetmouse", nargs, 5, 5)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { long ival = PyLong_AsLong(args[0]); if (ival == -1 && PyErr_Occurred()) { @@ -2493,29 +2357,14 @@ _curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) id = (short) ival; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } x = _PyLong_AsInt(args[1]); if (x == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } y = _PyLong_AsInt(args[2]); if (y == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } z = _PyLong_AsInt(args[3]); if (z == -1 && PyErr_Occurred()) { goto exit; @@ -2568,11 +2417,6 @@ _curses_halfdelay(PyObject *module, PyObject *arg) PyObject *return_value = NULL; unsigned char tenths; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { long ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) { @@ -2675,11 +2519,6 @@ _curses_has_key(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int key; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } key = _PyLong_AsInt(arg); if (key == -1 && PyErr_Occurred()) { goto exit; @@ -2715,14 +2554,14 @@ PyDoc_STRVAR(_curses_init_color__doc__, {"init_color", (PyCFunction)(void(*)(void))_curses_init_color, METH_FASTCALL, _curses_init_color__doc__}, static PyObject * -_curses_init_color_impl(PyObject *module, short color_number, short r, - short g, short b); +_curses_init_color_impl(PyObject *module, int color_number, short r, short g, + short b); static PyObject * _curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - short color_number; + int color_number; short r; short g; short b; @@ -2730,102 +2569,18 @@ _curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("init_color", nargs, 4, 4)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!color_converter(args[0], &color_number)) { goto exit; } - { - long ival = PyLong_AsLong(args[0]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - color_number = (short) ival; - } - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!component_converter(args[1], &r)) { goto exit; } - { - long ival = PyLong_AsLong(args[1]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - r = (short) ival; - } - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!component_converter(args[2], &g)) { goto exit; } - { - long ival = PyLong_AsLong(args[2]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - g = (short) ival; - } - } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!component_converter(args[3], &b)) { goto exit; } - { - long ival = PyLong_AsLong(args[3]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - b = (short) ival; - } - } return_value = _curses_init_color_impl(module, color_number, r, g, b); exit: @@ -2852,92 +2607,28 @@ PyDoc_STRVAR(_curses_init_pair__doc__, {"init_pair", (PyCFunction)(void(*)(void))_curses_init_pair, METH_FASTCALL, _curses_init_pair__doc__}, static PyObject * -_curses_init_pair_impl(PyObject *module, short pair_number, short fg, - short bg); +_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg); static PyObject * _curses_init_pair(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - short pair_number; - short fg; - short bg; + int pair_number; + int fg; + int bg; if (!_PyArg_CheckPositional("init_pair", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!pair_converter(args[0], &pair_number)) { goto exit; } - { - long ival = PyLong_AsLong(args[0]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - pair_number = (short) ival; - } - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!color_allow_default_converter(args[1], &fg)) { goto exit; } - { - long ival = PyLong_AsLong(args[1]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - fg = (short) ival; - } - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!color_allow_default_converter(args[2], &bg)) { goto exit; } - { - long ival = PyLong_AsLong(args[2]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - bg = (short) ival; - } - } return_value = _curses_init_pair_impl(module, pair_number, fg, bg); exit: @@ -3024,11 +2715,6 @@ _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[1]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -3093,11 +2779,6 @@ _curses_set_escdelay(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int ms; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } ms = _PyLong_AsInt(arg); if (ms == -1 && PyErr_Occurred()) { goto exit; @@ -3161,11 +2842,6 @@ _curses_set_tabsize(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int size; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } size = _PyLong_AsInt(arg); if (size == -1 && PyErr_Occurred()) { goto exit; @@ -3195,11 +2871,6 @@ _curses_intrflush(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(arg); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -3257,20 +2928,10 @@ _curses_is_term_resized(PyObject *module, PyObject *const *args, Py_ssize_t narg if (!_PyArg_CheckPositional("is_term_resized", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nlines = _PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } ncols = _PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; @@ -3304,11 +2965,6 @@ _curses_keyname(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int key; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } key = _PyLong_AsInt(arg); if (key == -1 && PyErr_Occurred()) { goto exit; @@ -3379,11 +3035,6 @@ _curses_meta(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int yes; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } yes = _PyLong_AsInt(arg); if (yes == -1 && PyErr_Occurred()) { goto exit; @@ -3421,11 +3072,6 @@ _curses_mouseinterval(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int interval; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } interval = _PyLong_AsInt(arg); if (interval == -1 && PyErr_Occurred()) { goto exit; @@ -3497,11 +3143,6 @@ _curses_napms(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int ms; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } ms = _PyLong_AsInt(arg); if (ms == -1 && PyErr_Occurred()) { goto exit; @@ -3539,20 +3180,10 @@ _curses_newpad(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("newpad", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nlines = _PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } ncols = _PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; @@ -3648,11 +3279,6 @@ _curses_nl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(args[0]); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -3773,44 +3399,23 @@ PyDoc_STRVAR(_curses_pair_content__doc__, "Return a tuple (fg, bg) containing the colors for the requested color pair.\n" "\n" " pair_number\n" -" The number of the color pair (1 - (COLOR_PAIRS-1))."); +" The number of the color pair (0 - (COLOR_PAIRS-1))."); #define _CURSES_PAIR_CONTENT_METHODDEF \ {"pair_content", (PyCFunction)_curses_pair_content, METH_O, _curses_pair_content__doc__}, static PyObject * -_curses_pair_content_impl(PyObject *module, short pair_number); +_curses_pair_content_impl(PyObject *module, int pair_number); static PyObject * _curses_pair_content(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - short pair_number; + int pair_number; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!pair_converter(arg, &pair_number)) { goto exit; } - { - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - pair_number = (short) ival; - } - } return_value = _curses_pair_content_impl(module, pair_number); exit: @@ -3837,11 +3442,6 @@ _curses_pair_number(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int attr; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } attr = _PyLong_AsInt(arg); if (attr == -1 && PyErr_Occurred()) { goto exit; @@ -3911,11 +3511,6 @@ _curses_qiflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(args[0]); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -3979,11 +3574,6 @@ _curses_raw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(args[0]); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -4081,20 +3671,10 @@ _curses_resizeterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("resizeterm", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nlines = _PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } ncols = _PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; @@ -4142,20 +3722,10 @@ _curses_resize_term(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("resize_term", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nlines = _PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } ncols = _PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; @@ -4217,20 +3787,10 @@ _curses_setsyx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setsyx", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } y = _PyLong_AsInt(args[0]); if (y == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } x = _PyLong_AsInt(args[1]); if (x == -1 && PyErr_Occurred()) { goto exit; @@ -4500,11 +4060,6 @@ _curses_typeahead(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -4580,11 +4135,6 @@ _curses_use_env(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(arg); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -4622,6 +4172,27 @@ _curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* !defined(STRICT_SYSV_CURSES) */ +PyDoc_STRVAR(_curses_has_extended_color_support__doc__, +"has_extended_color_support($module, /)\n" +"--\n" +"\n" +"Return True if the module supports extended colors; otherwise, return False.\n" +"\n" +"Extended color support allows more than 256 color-pairs for terminals\n" +"that support more than 16 colors (e.g. xterm-256color)."); + +#define _CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF \ + {"has_extended_color_support", (PyCFunction)_curses_has_extended_color_support, METH_NOARGS, _curses_has_extended_color_support__doc__}, + +static PyObject * +_curses_has_extended_color_support_impl(PyObject *module); + +static PyObject * +_curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_extended_color_support_impl(module); +} + #ifndef _CURSES_WINDOW_ENCLOSE_METHODDEF #define _CURSES_WINDOW_ENCLOSE_METHODDEF #endif /* !defined(_CURSES_WINDOW_ENCLOSE_METHODDEF) */ @@ -4713,4 +4284,4 @@ _curses_use_default_colors(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=5e739120041df368 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9efc9943a3ac3741 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h b/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h index 973a4ea0253..7bd7c1986dc 100644 --- a/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h @@ -35,29 +35,14 @@ iso_calendar_date_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!fastargs) { goto exit; } - if (PyFloat_Check(fastargs[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } year = _PyLong_AsInt(fastargs[0]); if (year == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } week = _PyLong_AsInt(fastargs[1]); if (week == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(fastargs[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } weekday = _PyLong_AsInt(fastargs[2]); if (weekday == -1 && PyErr_Occurred()) { goto exit; @@ -109,4 +94,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=5e17549f29a439a5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f61310936e3d8091 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h index a7d73508506..af288c2586a 100644 --- a/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h @@ -27,15 +27,26 @@ PyDoc_STRVAR(_dbm_dbm_keys__doc__, "Return a list of all keys in the database."); #define _DBM_DBM_KEYS_METHODDEF \ - {"keys", (PyCFunction)_dbm_dbm_keys, METH_NOARGS, _dbm_dbm_keys__doc__}, + {"keys", (PyCFunction)(void(*)(void))_dbm_dbm_keys, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_keys__doc__}, static PyObject * -_dbm_dbm_keys_impl(dbmobject *self); +_dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls); static PyObject * -_dbm_dbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored)) +_dbm_dbm_keys(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _dbm_dbm_keys_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":keys", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _dbm_dbm_keys_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_dbm_dbm_get__doc__, @@ -45,25 +56,27 @@ PyDoc_STRVAR(_dbm_dbm_get__doc__, "Return the value for key if present, otherwise default."); #define _DBM_DBM_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_dbm_dbm_get, METH_FASTCALL, _dbm_dbm_get__doc__}, + {"get", (PyCFunction)(void(*)(void))_dbm_dbm_get, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_get__doc__}, static PyObject * -_dbm_dbm_get_impl(dbmobject *self, const char *key, +_dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key, Py_ssize_clean_t key_length, PyObject *default_value); static PyObject * -_dbm_dbm_get(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +_dbm_dbm_get(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"s#|O:get", _keywords, 0}; const char *key; Py_ssize_clean_t key_length; PyObject *default_value = Py_None; - if (!_PyArg_ParseStack(args, nargs, "s#|O:get", + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &key, &key_length, &default_value)) { goto exit; } - return_value = _dbm_dbm_get_impl(self, key, key_length, default_value); + return_value = _dbm_dbm_get_impl(self, cls, key, key_length, default_value); exit: return return_value; @@ -78,26 +91,28 @@ PyDoc_STRVAR(_dbm_dbm_setdefault__doc__, "If key is not in the database, it is inserted with default as the value."); #define _DBM_DBM_SETDEFAULT_METHODDEF \ - {"setdefault", (PyCFunction)(void(*)(void))_dbm_dbm_setdefault, METH_FASTCALL, _dbm_dbm_setdefault__doc__}, + {"setdefault", (PyCFunction)(void(*)(void))_dbm_dbm_setdefault, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_setdefault__doc__}, static PyObject * -_dbm_dbm_setdefault_impl(dbmobject *self, const char *key, +_dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key, Py_ssize_clean_t key_length, PyObject *default_value); static PyObject * -_dbm_dbm_setdefault(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +_dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"s#|O:setdefault", _keywords, 0}; const char *key; Py_ssize_clean_t key_length; PyObject *default_value = NULL; - if (!_PyArg_ParseStack(args, nargs, "s#|O:setdefault", + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &key, &key_length, &default_value)) { goto exit; } - return_value = _dbm_dbm_setdefault_impl(self, key, key_length, default_value); + return_value = _dbm_dbm_setdefault_impl(self, cls, key, key_length, default_value); exit: return return_value; @@ -162,11 +177,6 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -177,4 +187,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=7ced103488cbca7a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6947b1115df66f7c input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h b/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h index 034c1081dcc..5ed5a6cadd9 100644 --- a/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h @@ -430,14 +430,9 @@ _elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -920,4 +915,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=18ddc3c84139443d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=992733cfc7390590 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h index 552bf6ed88e..ea4ee7df001 100644 --- a/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h @@ -12,10 +12,10 @@ PyDoc_STRVAR(_gdbm_gdbm_get__doc__, {"get", (PyCFunction)(void(*)(void))_gdbm_gdbm_get, METH_FASTCALL, _gdbm_gdbm_get__doc__}, static PyObject * -_gdbm_gdbm_get_impl(dbmobject *self, PyObject *key, PyObject *default_value); +_gdbm_gdbm_get_impl(gdbmobject *self, PyObject *key, PyObject *default_value); static PyObject * -_gdbm_gdbm_get(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +_gdbm_gdbm_get(gdbmobject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *key; @@ -46,11 +46,11 @@ PyDoc_STRVAR(_gdbm_gdbm_setdefault__doc__, {"setdefault", (PyCFunction)(void(*)(void))_gdbm_gdbm_setdefault, METH_FASTCALL, _gdbm_gdbm_setdefault__doc__}, static PyObject * -_gdbm_gdbm_setdefault_impl(dbmobject *self, PyObject *key, +_gdbm_gdbm_setdefault_impl(gdbmobject *self, PyObject *key, PyObject *default_value); static PyObject * -_gdbm_gdbm_setdefault(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +_gdbm_gdbm_setdefault(gdbmobject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *key; @@ -81,10 +81,10 @@ PyDoc_STRVAR(_gdbm_gdbm_close__doc__, {"close", (PyCFunction)_gdbm_gdbm_close, METH_NOARGS, _gdbm_gdbm_close__doc__}, static PyObject * -_gdbm_gdbm_close_impl(dbmobject *self); +_gdbm_gdbm_close_impl(gdbmobject *self); static PyObject * -_gdbm_gdbm_close(dbmobject *self, PyObject *Py_UNUSED(ignored)) +_gdbm_gdbm_close(gdbmobject *self, PyObject *Py_UNUSED(ignored)) { return _gdbm_gdbm_close_impl(self); } @@ -96,15 +96,26 @@ PyDoc_STRVAR(_gdbm_gdbm_keys__doc__, "Get a list of all keys in the database."); #define _GDBM_GDBM_KEYS_METHODDEF \ - {"keys", (PyCFunction)_gdbm_gdbm_keys, METH_NOARGS, _gdbm_gdbm_keys__doc__}, + {"keys", (PyCFunction)(void(*)(void))_gdbm_gdbm_keys, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_keys__doc__}, static PyObject * -_gdbm_gdbm_keys_impl(dbmobject *self); +_gdbm_gdbm_keys_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * -_gdbm_gdbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored)) +_gdbm_gdbm_keys(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _gdbm_gdbm_keys_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":keys", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _gdbm_gdbm_keys_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__, @@ -118,15 +129,26 @@ PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__, "hash values, and won\'t be sorted by the key values."); #define _GDBM_GDBM_FIRSTKEY_METHODDEF \ - {"firstkey", (PyCFunction)_gdbm_gdbm_firstkey, METH_NOARGS, _gdbm_gdbm_firstkey__doc__}, + {"firstkey", (PyCFunction)(void(*)(void))_gdbm_gdbm_firstkey, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_firstkey__doc__}, static PyObject * -_gdbm_gdbm_firstkey_impl(dbmobject *self); +_gdbm_gdbm_firstkey_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * -_gdbm_gdbm_firstkey(dbmobject *self, PyObject *Py_UNUSED(ignored)) +_gdbm_gdbm_firstkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _gdbm_gdbm_firstkey_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":firstkey", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _gdbm_gdbm_firstkey_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__, @@ -144,23 +166,26 @@ PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__, " k = db.nextkey(k)"); #define _GDBM_GDBM_NEXTKEY_METHODDEF \ - {"nextkey", (PyCFunction)_gdbm_gdbm_nextkey, METH_O, _gdbm_gdbm_nextkey__doc__}, + {"nextkey", (PyCFunction)(void(*)(void))_gdbm_gdbm_nextkey, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_nextkey__doc__}, static PyObject * -_gdbm_gdbm_nextkey_impl(dbmobject *self, const char *key, +_gdbm_gdbm_nextkey_impl(gdbmobject *self, PyTypeObject *cls, const char *key, Py_ssize_clean_t key_length); static PyObject * -_gdbm_gdbm_nextkey(dbmobject *self, PyObject *arg) +_gdbm_gdbm_nextkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"s#:nextkey", _keywords, 0}; const char *key; Py_ssize_clean_t key_length; - if (!PyArg_Parse(arg, "s#:nextkey", &key, &key_length)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &key, &key_length)) { goto exit; } - return_value = _gdbm_gdbm_nextkey_impl(self, key, key_length); + return_value = _gdbm_gdbm_nextkey_impl(self, cls, key, key_length); exit: return return_value; @@ -179,15 +204,26 @@ PyDoc_STRVAR(_gdbm_gdbm_reorganize__doc__, "kept and reused as new (key,value) pairs are added."); #define _GDBM_GDBM_REORGANIZE_METHODDEF \ - {"reorganize", (PyCFunction)_gdbm_gdbm_reorganize, METH_NOARGS, _gdbm_gdbm_reorganize__doc__}, + {"reorganize", (PyCFunction)(void(*)(void))_gdbm_gdbm_reorganize, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_reorganize__doc__}, static PyObject * -_gdbm_gdbm_reorganize_impl(dbmobject *self); +_gdbm_gdbm_reorganize_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * -_gdbm_gdbm_reorganize(dbmobject *self, PyObject *Py_UNUSED(ignored)) +_gdbm_gdbm_reorganize(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _gdbm_gdbm_reorganize_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":reorganize", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _gdbm_gdbm_reorganize_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_gdbm_gdbm_sync__doc__, @@ -200,15 +236,26 @@ PyDoc_STRVAR(_gdbm_gdbm_sync__doc__, "any unwritten data to be written to the disk."); #define _GDBM_GDBM_SYNC_METHODDEF \ - {"sync", (PyCFunction)_gdbm_gdbm_sync, METH_NOARGS, _gdbm_gdbm_sync__doc__}, + {"sync", (PyCFunction)(void(*)(void))_gdbm_gdbm_sync, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_sync__doc__}, static PyObject * -_gdbm_gdbm_sync_impl(dbmobject *self); +_gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * -_gdbm_gdbm_sync(dbmobject *self, PyObject *Py_UNUSED(ignored)) +_gdbm_gdbm_sync(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _gdbm_gdbm_sync_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":sync", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _gdbm_gdbm_sync_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(dbmopen__doc__, @@ -283,11 +330,6 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -298,4 +340,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=f48d6e8d4c8a3465 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3b88446433e43d96 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h b/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h index 68aa765e529..de01489e6a3 100644 --- a/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h @@ -92,14 +92,9 @@ EVPXOF_digest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -144,14 +139,9 @@ EVPXOF_hexdigest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObj if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -936,11 +926,6 @@ pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject _PyArg_BadArgument("pbkdf2_hmac", "argument 'salt'", "contiguous buffer", args[2]); goto exit; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } iterations = PyLong_AsLong(args[3]); if (iterations == -1 && PyErr_Occurred()) { goto exit; @@ -965,7 +950,7 @@ exit: return return_value; } -#if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) +#if defined(PY_OPENSSL_HAS_SCRYPT) PyDoc_STRVAR(_hashlib_scrypt__doc__, "scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n" @@ -1055,11 +1040,6 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[5]) { - if (PyFloat_Check(args[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } maxmem = PyLong_AsLong(args[5]); if (maxmem == -1 && PyErr_Occurred()) { goto exit; @@ -1068,11 +1048,6 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_kwonly; } } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } dklen = PyLong_AsLong(args[6]); if (dklen == -1 && PyErr_Occurred()) { goto exit; @@ -1093,7 +1068,7 @@ exit: return return_value; } -#endif /* (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) */ +#endif /* defined(PY_OPENSSL_HAS_SCRYPT) */ PyDoc_STRVAR(_hashlib_hmac_singleshot__doc__, "hmac_digest($module, /, key, msg, digest)\n" @@ -1106,7 +1081,7 @@ PyDoc_STRVAR(_hashlib_hmac_singleshot__doc__, static PyObject * _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, - Py_buffer *msg, const char *digest); + Py_buffer *msg, PyObject *digest); static PyObject * _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -1117,7 +1092,7 @@ _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nar PyObject *argsbuf[3]; Py_buffer key = {NULL, NULL}; Py_buffer msg = {NULL, NULL}; - const char *digest; + PyObject *digest; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); if (!args) { @@ -1137,19 +1112,7 @@ _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nar _PyArg_BadArgument("hmac_digest", "argument 'msg'", "contiguous buffer", args[1]); goto exit; } - if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("hmac_digest", "argument 'digest'", "str", args[2]); - goto exit; - } - Py_ssize_t digest_length; - digest = PyUnicode_AsUTF8AndSize(args[2], &digest_length); - if (digest == NULL) { - goto exit; - } - if (strlen(digest) != (size_t)digest_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } + digest = args[2]; return_value = _hashlib_hmac_singleshot_impl(module, &key, &msg, digest); exit: @@ -1176,7 +1139,7 @@ PyDoc_STRVAR(_hashlib_hmac_new__doc__, static PyObject * _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, - const char *digestmod); + PyObject *digestmod); static PyObject * _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -1188,7 +1151,7 @@ _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer key = {NULL, NULL}; PyObject *msg_obj = NULL; - const char *digestmod = NULL; + PyObject *digestmod = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { @@ -1210,19 +1173,7 @@ _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO goto skip_optional_pos; } } - if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("hmac_new", "argument 'digestmod'", "str", args[2]); - goto exit; - } - Py_ssize_t digestmod_length; - digestmod = PyUnicode_AsUTF8AndSize(args[2], &digestmod_length); - if (digestmod == NULL) { - goto exit; - } - if (strlen(digestmod) != (size_t)digestmod_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } + digestmod = args[2]; skip_optional_pos: return_value = _hashlib_hmac_new_impl(module, &key, msg_obj, digestmod); @@ -1324,8 +1275,6 @@ _hashlib_HMAC_hexdigest(HMACobject *self, PyObject *Py_UNUSED(ignored)) return _hashlib_HMAC_hexdigest_impl(self); } -#if !defined(LIBRESSL_VERSION_NUMBER) - PyDoc_STRVAR(_hashlib_get_fips_mode__doc__, "get_fips_mode($module, /)\n" "--\n" @@ -1361,8 +1310,6 @@ exit: return return_value; } -#endif /* !defined(LIBRESSL_VERSION_NUMBER) */ - PyDoc_STRVAR(_hashlib_compare_digest__doc__, "compare_digest($module, a, b, /)\n" "--\n" @@ -1438,8 +1385,4 @@ exit: #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ - -#ifndef _HASHLIB_GET_FIPS_MODE_METHODDEF - #define _HASHLIB_GET_FIPS_MODE_METHODDEF -#endif /* !defined(_HASHLIB_GET_FIPS_MODE_METHODDEF) */ -/*[clinic end generated code: output=b6b280e46bf0b139 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=162369cb9d43f1cc input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_heapqmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_heapqmodule.c.h index 55403706ba0..a894315a766 100644 --- a/contrib/tools/python3/src/Modules/clinic/_heapqmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_heapqmodule.c.h @@ -24,6 +24,10 @@ _heapq_heappush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("heappush", nargs, 2, 2)) { goto exit; } + if (!PyList_Check(args[0])) { + _PyArg_BadArgument("heappush", "argument 1", "list", args[0]); + goto exit; + } heap = args[0]; item = args[1]; return_value = _heapq_heappush_impl(module, heap, item); @@ -41,6 +45,26 @@ PyDoc_STRVAR(_heapq_heappop__doc__, #define _HEAPQ_HEAPPOP_METHODDEF \ {"heappop", (PyCFunction)_heapq_heappop, METH_O, _heapq_heappop__doc__}, +static PyObject * +_heapq_heappop_impl(PyObject *module, PyObject *heap); + +static PyObject * +_heapq_heappop(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *heap; + + if (!PyList_Check(arg)) { + _PyArg_BadArgument("heappop", "argument", "list", arg); + goto exit; + } + heap = arg; + return_value = _heapq_heappop_impl(module, heap); + +exit: + return return_value; +} + PyDoc_STRVAR(_heapq_heapreplace__doc__, "heapreplace($module, heap, item, /)\n" "--\n" @@ -71,6 +95,10 @@ _heapq_heapreplace(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("heapreplace", nargs, 2, 2)) { goto exit; } + if (!PyList_Check(args[0])) { + _PyArg_BadArgument("heapreplace", "argument 1", "list", args[0]); + goto exit; + } heap = args[0]; item = args[1]; return_value = _heapq_heapreplace_impl(module, heap, item); @@ -104,6 +132,10 @@ _heapq_heappushpop(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("heappushpop", nargs, 2, 2)) { goto exit; } + if (!PyList_Check(args[0])) { + _PyArg_BadArgument("heappushpop", "argument 1", "list", args[0]); + goto exit; + } heap = args[0]; item = args[1]; return_value = _heapq_heappushpop_impl(module, heap, item); @@ -121,6 +153,26 @@ PyDoc_STRVAR(_heapq_heapify__doc__, #define _HEAPQ_HEAPIFY_METHODDEF \ {"heapify", (PyCFunction)_heapq_heapify, METH_O, _heapq_heapify__doc__}, +static PyObject * +_heapq_heapify_impl(PyObject *module, PyObject *heap); + +static PyObject * +_heapq_heapify(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *heap; + + if (!PyList_Check(arg)) { + _PyArg_BadArgument("heapify", "argument", "list", arg); + goto exit; + } + heap = arg; + return_value = _heapq_heapify_impl(module, heap); + +exit: + return return_value; +} + PyDoc_STRVAR(_heapq__heappop_max__doc__, "_heappop_max($module, heap, /)\n" "--\n" @@ -130,6 +182,26 @@ PyDoc_STRVAR(_heapq__heappop_max__doc__, #define _HEAPQ__HEAPPOP_MAX_METHODDEF \ {"_heappop_max", (PyCFunction)_heapq__heappop_max, METH_O, _heapq__heappop_max__doc__}, +static PyObject * +_heapq__heappop_max_impl(PyObject *module, PyObject *heap); + +static PyObject * +_heapq__heappop_max(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *heap; + + if (!PyList_Check(arg)) { + _PyArg_BadArgument("_heappop_max", "argument", "list", arg); + goto exit; + } + heap = arg; + return_value = _heapq__heappop_max_impl(module, heap); + +exit: + return return_value; +} + PyDoc_STRVAR(_heapq__heapreplace_max__doc__, "_heapreplace_max($module, heap, item, /)\n" "--\n" @@ -153,6 +225,10 @@ _heapq__heapreplace_max(PyObject *module, PyObject *const *args, Py_ssize_t narg if (!_PyArg_CheckPositional("_heapreplace_max", nargs, 2, 2)) { goto exit; } + if (!PyList_Check(args[0])) { + _PyArg_BadArgument("_heapreplace_max", "argument 1", "list", args[0]); + goto exit; + } heap = args[0]; item = args[1]; return_value = _heapq__heapreplace_max_impl(module, heap, item); @@ -169,4 +245,24 @@ PyDoc_STRVAR(_heapq__heapify_max__doc__, #define _HEAPQ__HEAPIFY_MAX_METHODDEF \ {"_heapify_max", (PyCFunction)_heapq__heapify_max, METH_O, _heapq__heapify_max__doc__}, -/*[clinic end generated code: output=37ef2a3319971c8d input=a9049054013a1b77]*/ + +static PyObject * +_heapq__heapify_max_impl(PyObject *module, PyObject *heap); + +static PyObject * +_heapq__heapify_max(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *heap; + + if (!PyList_Check(arg)) { + _PyArg_BadArgument("_heapify_max", "argument", "list", arg); + goto exit; + } + heap = arg; + return_value = _heapq__heapify_max_impl(module, heap); + +exit: + return return_value; +} +/*[clinic end generated code: output=9975cf51762878d5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_localemodule.c.h b/contrib/tools/python3/src/Modules/clinic/_localemodule.c.h new file mode 100644 index 00000000000..703d034c32e --- /dev/null +++ b/contrib/tools/python3/src/Modules/clinic/_localemodule.c.h @@ -0,0 +1,605 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_locale_setlocale__doc__, +"setlocale($module, category, locale=, /)\n" +"--\n" +"\n" +"Activates/queries locale processing."); + +#define _LOCALE_SETLOCALE_METHODDEF \ + {"setlocale", (PyCFunction)(void(*)(void))_locale_setlocale, METH_FASTCALL, _locale_setlocale__doc__}, + +static PyObject * +_locale_setlocale_impl(PyObject *module, int category, const char *locale); + +static PyObject * +_locale_setlocale(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int category; + const char *locale = NULL; + + if (!_PyArg_CheckPositional("setlocale", nargs, 1, 2)) { + goto exit; + } + category = _PyLong_AsInt(args[0]); + if (category == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + locale = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t locale_length; + locale = PyUnicode_AsUTF8AndSize(args[1], &locale_length); + if (locale == NULL) { + goto exit; + } + if (strlen(locale) != (size_t)locale_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("setlocale", "argument 2", "str or None", args[1]); + goto exit; + } +skip_optional: + return_value = _locale_setlocale_impl(module, category, locale); + +exit: + return return_value; +} + +PyDoc_STRVAR(_locale_localeconv__doc__, +"localeconv($module, /)\n" +"--\n" +"\n" +"Returns numeric and monetary locale-specific parameters."); + +#define _LOCALE_LOCALECONV_METHODDEF \ + {"localeconv", (PyCFunction)_locale_localeconv, METH_NOARGS, _locale_localeconv__doc__}, + +static PyObject * +_locale_localeconv_impl(PyObject *module); + +static PyObject * +_locale_localeconv(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _locale_localeconv_impl(module); +} + +#if defined(HAVE_WCSCOLL) + +PyDoc_STRVAR(_locale_strcoll__doc__, +"strcoll($module, os1, os2, /)\n" +"--\n" +"\n" +"Compares two strings according to the locale."); + +#define _LOCALE_STRCOLL_METHODDEF \ + {"strcoll", (PyCFunction)(void(*)(void))_locale_strcoll, METH_FASTCALL, _locale_strcoll__doc__}, + +static PyObject * +_locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2); + +static PyObject * +_locale_strcoll(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *os1; + PyObject *os2; + + if (!_PyArg_CheckPositional("strcoll", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("strcoll", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + os1 = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("strcoll", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + os2 = args[1]; + return_value = _locale_strcoll_impl(module, os1, os2); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WCSCOLL) */ + +#if defined(HAVE_WCSXFRM) + +PyDoc_STRVAR(_locale_strxfrm__doc__, +"strxfrm($module, string, /)\n" +"--\n" +"\n" +"Return a string that can be used as a key for locale-aware comparisons."); + +#define _LOCALE_STRXFRM_METHODDEF \ + {"strxfrm", (PyCFunction)_locale_strxfrm, METH_O, _locale_strxfrm__doc__}, + +static PyObject * +_locale_strxfrm_impl(PyObject *module, PyObject *str); + +static PyObject * +_locale_strxfrm(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *str; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("strxfrm", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + str = arg; + return_value = _locale_strxfrm_impl(module, str); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WCSXFRM) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_locale__getdefaultlocale__doc__, +"_getdefaultlocale($module, /)\n" +"--\n" +"\n"); + +#define _LOCALE__GETDEFAULTLOCALE_METHODDEF \ + {"_getdefaultlocale", (PyCFunction)_locale__getdefaultlocale, METH_NOARGS, _locale__getdefaultlocale__doc__}, + +static PyObject * +_locale__getdefaultlocale_impl(PyObject *module); + +static PyObject * +_locale__getdefaultlocale(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _locale__getdefaultlocale_impl(module); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(HAVE_LANGINFO_H) + +PyDoc_STRVAR(_locale_nl_langinfo__doc__, +"nl_langinfo($module, key, /)\n" +"--\n" +"\n" +"Return the value for the locale information associated with key."); + +#define _LOCALE_NL_LANGINFO_METHODDEF \ + {"nl_langinfo", (PyCFunction)_locale_nl_langinfo, METH_O, _locale_nl_langinfo__doc__}, + +static PyObject * +_locale_nl_langinfo_impl(PyObject *module, int item); + +static PyObject * +_locale_nl_langinfo(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int item; + + item = _PyLong_AsInt(arg); + if (item == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _locale_nl_langinfo_impl(module, item); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LANGINFO_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_gettext__doc__, +"gettext($module, msg, /)\n" +"--\n" +"\n" +"gettext(msg) -> string\n" +"\n" +"Return translation of msg."); + +#define _LOCALE_GETTEXT_METHODDEF \ + {"gettext", (PyCFunction)_locale_gettext, METH_O, _locale_gettext__doc__}, + +static PyObject * +_locale_gettext_impl(PyObject *module, const char *in); + +static PyObject * +_locale_gettext(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *in; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("gettext", "argument", "str", arg); + goto exit; + } + Py_ssize_t in_length; + in = PyUnicode_AsUTF8AndSize(arg, &in_length); + if (in == NULL) { + goto exit; + } + if (strlen(in) != (size_t)in_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _locale_gettext_impl(module, in); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_dgettext__doc__, +"dgettext($module, domain, msg, /)\n" +"--\n" +"\n" +"dgettext(domain, msg) -> string\n" +"\n" +"Return translation of msg in domain."); + +#define _LOCALE_DGETTEXT_METHODDEF \ + {"dgettext", (PyCFunction)(void(*)(void))_locale_dgettext, METH_FASTCALL, _locale_dgettext__doc__}, + +static PyObject * +_locale_dgettext_impl(PyObject *module, const char *domain, const char *in); + +static PyObject * +_locale_dgettext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + const char *in; + + if (!_PyArg_CheckPositional("dgettext", nargs, 2, 2)) { + goto exit; + } + if (args[0] == Py_None) { + domain = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("dgettext", "argument 1", "str or None", args[0]); + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("dgettext", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t in_length; + in = PyUnicode_AsUTF8AndSize(args[1], &in_length); + if (in == NULL) { + goto exit; + } + if (strlen(in) != (size_t)in_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _locale_dgettext_impl(module, domain, in); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_dcgettext__doc__, +"dcgettext($module, domain, msg, category, /)\n" +"--\n" +"\n" +"Return translation of msg in domain and category."); + +#define _LOCALE_DCGETTEXT_METHODDEF \ + {"dcgettext", (PyCFunction)(void(*)(void))_locale_dcgettext, METH_FASTCALL, _locale_dcgettext__doc__}, + +static PyObject * +_locale_dcgettext_impl(PyObject *module, const char *domain, + const char *msgid, int category); + +static PyObject * +_locale_dcgettext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + const char *msgid; + int category; + + if (!_PyArg_CheckPositional("dcgettext", nargs, 3, 3)) { + goto exit; + } + if (args[0] == Py_None) { + domain = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("dcgettext", "argument 1", "str or None", args[0]); + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("dcgettext", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t msgid_length; + msgid = PyUnicode_AsUTF8AndSize(args[1], &msgid_length); + if (msgid == NULL) { + goto exit; + } + if (strlen(msgid) != (size_t)msgid_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + category = _PyLong_AsInt(args[2]); + if (category == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _locale_dcgettext_impl(module, domain, msgid, category); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_textdomain__doc__, +"textdomain($module, domain, /)\n" +"--\n" +"\n" +"Set the C library\'s textdmain to domain, returning the new domain."); + +#define _LOCALE_TEXTDOMAIN_METHODDEF \ + {"textdomain", (PyCFunction)_locale_textdomain, METH_O, _locale_textdomain__doc__}, + +static PyObject * +_locale_textdomain_impl(PyObject *module, const char *domain); + +static PyObject * +_locale_textdomain(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *domain; + + if (arg == Py_None) { + domain = NULL; + } + else if (PyUnicode_Check(arg)) { + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(arg, &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("textdomain", "argument", "str or None", arg); + goto exit; + } + return_value = _locale_textdomain_impl(module, domain); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_bindtextdomain__doc__, +"bindtextdomain($module, domain, dir, /)\n" +"--\n" +"\n" +"Bind the C library\'s domain to dir."); + +#define _LOCALE_BINDTEXTDOMAIN_METHODDEF \ + {"bindtextdomain", (PyCFunction)(void(*)(void))_locale_bindtextdomain, METH_FASTCALL, _locale_bindtextdomain__doc__}, + +static PyObject * +_locale_bindtextdomain_impl(PyObject *module, const char *domain, + PyObject *dirname_obj); + +static PyObject * +_locale_bindtextdomain(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + PyObject *dirname_obj; + + if (!_PyArg_CheckPositional("bindtextdomain", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("bindtextdomain", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + dirname_obj = args[1]; + return_value = _locale_bindtextdomain_impl(module, domain, dirname_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) && defined(HAVE_BIND_TEXTDOMAIN_CODESET) + +PyDoc_STRVAR(_locale_bind_textdomain_codeset__doc__, +"bind_textdomain_codeset($module, domain, codeset, /)\n" +"--\n" +"\n" +"Bind the C library\'s domain to codeset."); + +#define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF \ + {"bind_textdomain_codeset", (PyCFunction)(void(*)(void))_locale_bind_textdomain_codeset, METH_FASTCALL, _locale_bind_textdomain_codeset__doc__}, + +static PyObject * +_locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain, + const char *codeset); + +static PyObject * +_locale_bind_textdomain_codeset(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + const char *codeset; + + if (!_PyArg_CheckPositional("bind_textdomain_codeset", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("bind_textdomain_codeset", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (args[1] == Py_None) { + codeset = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t codeset_length; + codeset = PyUnicode_AsUTF8AndSize(args[1], &codeset_length); + if (codeset == NULL) { + goto exit; + } + if (strlen(codeset) != (size_t)codeset_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("bind_textdomain_codeset", "argument 2", "str or None", args[1]); + goto exit; + } + return_value = _locale_bind_textdomain_codeset_impl(module, domain, codeset); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) && defined(HAVE_BIND_TEXTDOMAIN_CODESET) */ + +PyDoc_STRVAR(_locale__get_locale_encoding__doc__, +"_get_locale_encoding($module, /)\n" +"--\n" +"\n" +"Get the current locale encoding."); + +#define _LOCALE__GET_LOCALE_ENCODING_METHODDEF \ + {"_get_locale_encoding", (PyCFunction)_locale__get_locale_encoding, METH_NOARGS, _locale__get_locale_encoding__doc__}, + +static PyObject * +_locale__get_locale_encoding_impl(PyObject *module); + +static PyObject * +_locale__get_locale_encoding(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _locale__get_locale_encoding_impl(module); +} + +#ifndef _LOCALE_STRCOLL_METHODDEF + #define _LOCALE_STRCOLL_METHODDEF +#endif /* !defined(_LOCALE_STRCOLL_METHODDEF) */ + +#ifndef _LOCALE_STRXFRM_METHODDEF + #define _LOCALE_STRXFRM_METHODDEF +#endif /* !defined(_LOCALE_STRXFRM_METHODDEF) */ + +#ifndef _LOCALE__GETDEFAULTLOCALE_METHODDEF + #define _LOCALE__GETDEFAULTLOCALE_METHODDEF +#endif /* !defined(_LOCALE__GETDEFAULTLOCALE_METHODDEF) */ + +#ifndef _LOCALE_NL_LANGINFO_METHODDEF + #define _LOCALE_NL_LANGINFO_METHODDEF +#endif /* !defined(_LOCALE_NL_LANGINFO_METHODDEF) */ + +#ifndef _LOCALE_GETTEXT_METHODDEF + #define _LOCALE_GETTEXT_METHODDEF +#endif /* !defined(_LOCALE_GETTEXT_METHODDEF) */ + +#ifndef _LOCALE_DGETTEXT_METHODDEF + #define _LOCALE_DGETTEXT_METHODDEF +#endif /* !defined(_LOCALE_DGETTEXT_METHODDEF) */ + +#ifndef _LOCALE_DCGETTEXT_METHODDEF + #define _LOCALE_DCGETTEXT_METHODDEF +#endif /* !defined(_LOCALE_DCGETTEXT_METHODDEF) */ + +#ifndef _LOCALE_TEXTDOMAIN_METHODDEF + #define _LOCALE_TEXTDOMAIN_METHODDEF +#endif /* !defined(_LOCALE_TEXTDOMAIN_METHODDEF) */ + +#ifndef _LOCALE_BINDTEXTDOMAIN_METHODDEF + #define _LOCALE_BINDTEXTDOMAIN_METHODDEF +#endif /* !defined(_LOCALE_BINDTEXTDOMAIN_METHODDEF) */ + +#ifndef _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF + #define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF +#endif /* !defined(_LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF) */ +/*[clinic end generated code: output=cd703c8a3a75fcf4 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_lsprof.c.h b/contrib/tools/python3/src/Modules/clinic/_lsprof.c.h new file mode 100644 index 00000000000..5d9c209eab8 --- /dev/null +++ b/contrib/tools/python3/src/Modules/clinic/_lsprof.c.h @@ -0,0 +1,55 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, +"getstats($self, /)\n" +"--\n" +"\n" +"list of profiler_entry objects.\n" +"\n" +"getstats() -> list of profiler_entry objects\n" +"\n" +"Return all information collected by the profiler.\n" +"Each profiler_entry is a tuple-like object with the\n" +"following attributes:\n" +"\n" +" code code object\n" +" callcount how many times this was called\n" +" reccallcount how many times called recursively\n" +" totaltime total time in this entry\n" +" inlinetime inline time in this entry (not in subcalls)\n" +" calls details of the calls\n" +"\n" +"The calls attribute is either None or a list of\n" +"profiler_subentry objects:\n" +"\n" +" code called code object\n" +" callcount how many times this is called\n" +" reccallcount how many times this is called recursively\n" +" totaltime total time spent in this call\n" +" inlinetime inline time (not in further subcalls)"); + +#define _LSPROF_PROFILER_GETSTATS_METHODDEF \ + {"getstats", (PyCFunction)(void(*)(void))_lsprof_Profiler_getstats, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _lsprof_Profiler_getstats__doc__}, + +static PyObject * +_lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls); + +static PyObject * +_lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":getstats", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _lsprof_Profiler_getstats_impl(self, cls); + +exit: + return return_value; +} +/*[clinic end generated code: output=b4727cfebecdd22d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h b/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h index 82ef4d517d8..526031ade3b 100644 --- a/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h @@ -116,14 +116,9 @@ _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -194,11 +189,6 @@ _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs goto skip_optional_pos; } if (fastargs[0]) { - if (PyFloat_Check(fastargs[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } format = _PyLong_AsInt(fastargs[0]); if (format == -1 && PyErr_Occurred()) { goto exit; @@ -241,11 +231,6 @@ _lzma_is_check_supported(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int check_id; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } check_id = _PyLong_AsInt(arg); if (check_id == -1 && PyErr_Occurred()) { goto exit; @@ -256,39 +241,6 @@ exit: return return_value; } -PyDoc_STRVAR(_lzma__encode_filter_properties__doc__, -"_encode_filter_properties($module, filter, /)\n" -"--\n" -"\n" -"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" -"\n" -"The result does not include the filter ID itself, only the options."); - -#define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF \ - {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_O, _lzma__encode_filter_properties__doc__}, - -static PyObject * -_lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter); - -static PyObject * -_lzma__encode_filter_properties(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL}; - - if (!lzma_filter_converter(arg, &filter)) { - goto exit; - } - return_value = _lzma__encode_filter_properties_impl(module, filter); - -exit: - /* Cleanup for filter */ - if (filter.id != LZMA_VLI_UNKNOWN) - PyMem_Free(filter.options); - - return return_value; -} - PyDoc_STRVAR(_lzma__decode_filter_properties__doc__, "_decode_filter_properties($module, filter_id, encoded_props, /)\n" "--\n" @@ -334,4 +286,4 @@ exit: return return_value; } -/*[clinic end generated code: output=f7477a10e86a717d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=867b9e334053b679 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_opcode.c.h b/contrib/tools/python3/src/Modules/clinic/_opcode.c.h index 777701ff140..6915f21d644 100644 --- a/contrib/tools/python3/src/Modules/clinic/_opcode.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_opcode.c.h @@ -32,11 +32,6 @@ _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } opcode = _PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; @@ -61,4 +56,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=7bc08f2835b2cf89 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bcf66d25c2624197 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_operator.c.h b/contrib/tools/python3/src/Modules/clinic/_operator.c.h index 0e39f3b77ad..bda2eba6d12 100644 --- a/contrib/tools/python3/src/Modules/clinic/_operator.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_operator.c.h @@ -1424,14 +1424,9 @@ _operator_length_hint(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -1491,4 +1486,4 @@ _operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=ed2bc172e42320d8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=16749e11fda51785 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h b/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h index c25eacf08bc..8741f7d9aff 100644 --- a/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h @@ -16,11 +16,11 @@ simplequeue_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - if ((type == &PySimpleQueueType) && + if ((type == simplequeue_get_state_by_type(type)->SimpleQueueType) && !_PyArg_NoPositional("SimpleQueue", args)) { goto exit; } - if ((type == &PySimpleQueueType) && + if ((type == simplequeue_get_state_by_type(type)->SimpleQueueType) && !_PyArg_NoKeywords("SimpleQueue", kwargs)) { goto exit; } @@ -133,42 +133,26 @@ PyDoc_STRVAR(_queue_SimpleQueue_get__doc__, "in that case)."); #define _QUEUE_SIMPLEQUEUE_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_queue_SimpleQueue_get, METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get__doc__}, + {"get", (PyCFunction)(void(*)(void))_queue_SimpleQueue_get, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get__doc__}, static PyObject * -_queue_SimpleQueue_get_impl(simplequeueobject *self, int block, - PyObject *timeout); +_queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls, + int block, PyObject *timeout); static PyObject * -_queue_SimpleQueue_get(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_queue_SimpleQueue_get(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + static _PyArg_Parser _parser = {"|pO:get", _keywords, 0}; int block = 1; PyObject *timeout = Py_None; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &block, &timeout)) { goto exit; } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[0]) { - block = PyObject_IsTrue(args[0]); - if (block < 0) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - timeout = args[1]; -skip_optional_pos: - return_value = _queue_SimpleQueue_get_impl(self, block, timeout); + return_value = _queue_SimpleQueue_get_impl(self, cls, block, timeout); exit: return return_value; @@ -184,15 +168,27 @@ PyDoc_STRVAR(_queue_SimpleQueue_get_nowait__doc__, "raise the Empty exception."); #define _QUEUE_SIMPLEQUEUE_GET_NOWAIT_METHODDEF \ - {"get_nowait", (PyCFunction)_queue_SimpleQueue_get_nowait, METH_NOARGS, _queue_SimpleQueue_get_nowait__doc__}, + {"get_nowait", (PyCFunction)(void(*)(void))_queue_SimpleQueue_get_nowait, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get_nowait__doc__}, static PyObject * -_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self); +_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self, + PyTypeObject *cls); static PyObject * -_queue_SimpleQueue_get_nowait(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) +_queue_SimpleQueue_get_nowait(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _queue_SimpleQueue_get_nowait_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":get_nowait", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _queue_SimpleQueue_get_nowait_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_queue_SimpleQueue_empty__doc__, @@ -250,4 +246,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=b4717e2974cbc909 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ce56b46fac150909 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_randommodule.c.h b/contrib/tools/python3/src/Modules/clinic/_randommodule.c.h index a467811d93b..b3cd435b6f2 100644 --- a/contrib/tools/python3/src/Modules/clinic/_randommodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_randommodule.c.h @@ -100,11 +100,6 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) PyObject *return_value = NULL; int k; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } k = _PyLong_AsInt(arg); if (k == -1 && PyErr_Occurred()) { goto exit; @@ -114,4 +109,4 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a7feb0c9c8d1b627 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=cc8a23b2757dc6ba input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_sre.c.h b/contrib/tools/python3/src/Modules/clinic/_sre.c.h index d398a8504ba..72d772c289a 100644 --- a/contrib/tools/python3/src/Modules/clinic/_sre.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_sre.c.h @@ -47,11 +47,6 @@ _sre_ascii_iscased(PyObject *module, PyObject *arg) int character; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; @@ -84,11 +79,6 @@ _sre_unicode_iscased(PyObject *module, PyObject *arg) int character; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; @@ -121,11 +111,6 @@ _sre_ascii_tolower(PyObject *module, PyObject *arg) int character; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; @@ -158,11 +143,6 @@ _sre_unicode_tolower(PyObject *module, PyObject *arg) int character; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; @@ -184,73 +164,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_match__doc__, "Matches zero or more characters at the beginning of the string."); #define _SRE_SRE_PATTERN_MATCH_METHODDEF \ - {"match", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_match, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, + {"match", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_match, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_match(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "match", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:match", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { - goto exit; - } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - 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; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_match_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_match_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -263,73 +198,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_fullmatch__doc__, "Matches against all of the string."); #define _SRE_SRE_PATTERN_FULLMATCH_METHODDEF \ - {"fullmatch", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_fullmatch, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_fullmatch__doc__}, + {"fullmatch", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_fullmatch, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_fullmatch__doc__}, static PyObject * -_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_fullmatch(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fullmatch", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:fullmatch", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - 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; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_fullmatch_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_fullmatch_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -344,73 +234,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_search__doc__, "Return None if no position in the string matches."); #define _SRE_SRE_PATTERN_SEARCH_METHODDEF \ - {"search", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_search, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_search__doc__}, + {"search", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_search, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_search__doc__}, static PyObject * -_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_search(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "search", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:search", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - 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; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_search_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_search_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -450,14 +295,9 @@ _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t goto skip_optional_pos; } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -471,14 +311,9 @@ _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t goto skip_optional_pos; } } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -504,73 +339,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_finditer__doc__, "For each match, the iterator returns a match object."); #define _SRE_SRE_PATTERN_FINDITER_METHODDEF \ - {"finditer", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_finditer, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_finditer__doc__}, + {"finditer", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_finditer, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_finditer__doc__}, static PyObject * -_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_finditer(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "finditer", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:finditer", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { - goto exit; - } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - 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; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_finditer_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_finditer_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -582,73 +372,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_scanner__doc__, "\n"); #define _SRE_SRE_PATTERN_SCANNER_METHODDEF \ - {"scanner", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_scanner, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_scanner__doc__}, + {"scanner", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_scanner, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_scanner__doc__}, static PyObject * -_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_scanner(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scanner", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:scanner", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - 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; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_scanner_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_scanner_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -686,14 +431,9 @@ _sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t na if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -717,52 +457,27 @@ PyDoc_STRVAR(_sre_SRE_Pattern_sub__doc__, "Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl."); #define _SRE_SRE_PATTERN_SUB_METHODDEF \ - {"sub", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_sub, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_sub__doc__}, + {"sub", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_sub, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_sub__doc__}, static PyObject * -_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count); +_sre_SRE_Pattern_sub_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, Py_ssize_t count); static PyObject * -_sre_SRE_Pattern_sub(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sub", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + static _PyArg_Parser _parser = {"OO|n:sub", _keywords, 0}; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { - goto exit; - } - repl = args[0]; - string = args[1]; - if (!noptargs) { - goto skip_optional_pos; - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &repl, &string, &count)) { goto exit; } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - count = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_sub_impl(self, repl, string, count); + return_value = _sre_SRE_Pattern_sub_impl(self, cls, repl, string, count); exit: return return_value; @@ -775,52 +490,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_subn__doc__, "Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl."); #define _SRE_SRE_PATTERN_SUBN_METHODDEF \ - {"subn", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_subn, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_subn__doc__}, + {"subn", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_subn, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_subn__doc__}, static PyObject * -_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count); +_sre_SRE_Pattern_subn_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, + Py_ssize_t count); static PyObject * -_sre_SRE_Pattern_subn(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "subn", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + static _PyArg_Parser _parser = {"OO|n:subn", _keywords, 0}; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &repl, &string, &count)) { goto exit; } - repl = args[0]; - string = args[1]; - if (!noptargs) { - goto skip_optional_pos; - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - count = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_subn_impl(self, repl, string, count); + return_value = _sre_SRE_Pattern_subn_impl(self, cls, repl, string, count); exit: return return_value; @@ -884,11 +575,6 @@ _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } pattern = args[0]; - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -898,14 +584,9 @@ _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } code = args[2]; - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[3]); + PyObject *iobj = _PyNumber_Index(args[3]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -1180,15 +861,26 @@ PyDoc_STRVAR(_sre_SRE_Scanner_match__doc__, "\n"); #define _SRE_SRE_SCANNER_MATCH_METHODDEF \ - {"match", (PyCFunction)_sre_SRE_Scanner_match, METH_NOARGS, _sre_SRE_Scanner_match__doc__}, + {"match", (PyCFunction)(void(*)(void))_sre_SRE_Scanner_match, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_match__doc__}, static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self); +_sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * -_sre_SRE_Scanner_match(ScannerObject *self, PyObject *Py_UNUSED(ignored)) +_sre_SRE_Scanner_match(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _sre_SRE_Scanner_match_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":match", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _sre_SRE_Scanner_match_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, @@ -1197,14 +889,25 @@ PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, "\n"); #define _SRE_SRE_SCANNER_SEARCH_METHODDEF \ - {"search", (PyCFunction)_sre_SRE_Scanner_search, METH_NOARGS, _sre_SRE_Scanner_search__doc__}, + {"search", (PyCFunction)(void(*)(void))_sre_SRE_Scanner_search, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_search__doc__}, static PyObject * -_sre_SRE_Scanner_search_impl(ScannerObject *self); +_sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * -_sre_SRE_Scanner_search(ScannerObject *self, PyObject *Py_UNUSED(ignored)) +_sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _sre_SRE_Scanner_search_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":search", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _sre_SRE_Scanner_search_impl(self, cls); + +exit: + return return_value; } -/*[clinic end generated code: output=1adeddce58ae284c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=518f7bb775c1184f input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_ssl.c.h b/contrib/tools/python3/src/Modules/clinic/_ssl.c.h index ce8669ae212..b59b129af8a 100644 --- a/contrib/tools/python3/src/Modules/clinic/_ssl.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_ssl.c.h @@ -88,6 +88,40 @@ exit: return return_value; } +PyDoc_STRVAR(_ssl__SSLSocket_get_verified_chain__doc__, +"get_verified_chain($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_GET_VERIFIED_CHAIN_METHODDEF \ + {"get_verified_chain", (PyCFunction)_ssl__SSLSocket_get_verified_chain, METH_NOARGS, _ssl__SSLSocket_get_verified_chain__doc__}, + +static PyObject * +_ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_get_verified_chain(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_get_verified_chain_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_get_unverified_chain__doc__, +"get_unverified_chain($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_GET_UNVERIFIED_CHAIN_METHODDEF \ + {"get_unverified_chain", (PyCFunction)_ssl__SSLSocket_get_unverified_chain, METH_NOARGS, _ssl__SSLSocket_get_unverified_chain__doc__}, + +static PyObject * +_ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_get_unverified_chain(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_get_unverified_chain_impl(self); +} + PyDoc_STRVAR(_ssl__SSLSocket_shared_ciphers__doc__, "shared_ciphers($self, /)\n" "--\n" @@ -139,29 +173,6 @@ _ssl__SSLSocket_version(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) return _ssl__SSLSocket_version_impl(self); } -#if (HAVE_NPN) - -PyDoc_STRVAR(_ssl__SSLSocket_selected_npn_protocol__doc__, -"selected_npn_protocol($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF \ - {"selected_npn_protocol", (PyCFunction)_ssl__SSLSocket_selected_npn_protocol, METH_NOARGS, _ssl__SSLSocket_selected_npn_protocol__doc__}, - -static PyObject * -_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_selected_npn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_selected_npn_protocol_impl(self); -} - -#endif /* (HAVE_NPN) */ - -#if (HAVE_ALPN) - PyDoc_STRVAR(_ssl__SSLSocket_selected_alpn_protocol__doc__, "selected_alpn_protocol($self, /)\n" "--\n" @@ -179,8 +190,6 @@ _ssl__SSLSocket_selected_alpn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ig return _ssl__SSLSocket_selected_alpn_protocol_impl(self); } -#endif /* (HAVE_ALPN) */ - PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__, "compression($self, /)\n" "--\n" @@ -262,25 +271,25 @@ PyDoc_STRVAR(_ssl__SSLSocket_read__doc__, {"read", (PyCFunction)_ssl__SSLSocket_read, METH_VARARGS, _ssl__SSLSocket_read__doc__}, static PyObject * -_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, - Py_buffer *buffer); +_ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, + int group_right_1, Py_buffer *buffer); static PyObject * _ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) { PyObject *return_value = NULL; - int len; + Py_ssize_t len; int group_right_1 = 0; Py_buffer buffer = {NULL, NULL}; switch (PyTuple_GET_SIZE(args)) { case 1: - if (!PyArg_ParseTuple(args, "i:read", &len)) { + if (!PyArg_ParseTuple(args, "n:read", &len)) { goto exit; } break; case 2: - if (!PyArg_ParseTuple(args, "iw*:read", &len, &buffer)) { + if (!PyArg_ParseTuple(args, "nw*:read", &len, &buffer)) { goto exit; } group_right_1 = 1; @@ -399,18 +408,13 @@ _ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject *return_value = NULL; int proto_version; - if ((type == &PySSLContext_Type) && + if ((type == get_state_type(type)->PySSLContext_Type) && !_PyArg_NoKeywords("_SSLContext", kwargs)) { goto exit; } if (!_PyArg_CheckPositional("_SSLContext", PyTuple_GET_SIZE(args), 1, 1)) { goto exit; } - if (PyFloat_Check(PyTuple_GET_ITEM(args, 0))) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } proto_version = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); if (proto_version == -1 && PyErr_Occurred()) { goto exit; @@ -457,8 +461,6 @@ exit: return return_value; } -#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL) - PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, "get_ciphers($self, /)\n" "--\n" @@ -476,44 +478,6 @@ _ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored)) return _ssl__SSLContext_get_ciphers_impl(self); } -#endif /* (OPENSSL_VERSION_NUMBER >= 0x10002000UL) */ - -PyDoc_STRVAR(_ssl__SSLContext__set_npn_protocols__doc__, -"_set_npn_protocols($self, protos, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF \ - {"_set_npn_protocols", (PyCFunction)_ssl__SSLContext__set_npn_protocols, METH_O, _ssl__SSLContext__set_npn_protocols__doc__}, - -static PyObject * -_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, - Py_buffer *protos); - -static PyObject * -_ssl__SSLContext__set_npn_protocols(PySSLContext *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer protos = {NULL, NULL}; - - if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { - goto exit; - } - if (!PyBuffer_IsContiguous(&protos, 'C')) { - _PyArg_BadArgument("_set_npn_protocols", "argument", "contiguous buffer", arg); - goto exit; - } - return_value = _ssl__SSLContext__set_npn_protocols_impl(self, &protos); - -exit: - /* Cleanup for protos */ - if (protos.obj) { - PyBuffer_Release(&protos); - } - - return return_value; -} - PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, "_set_alpn_protocols($self, protos, /)\n" "--\n" @@ -689,16 +653,11 @@ _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssiz if (!args) { goto exit; } - if (!PyObject_TypeCheck(args[0], PySocketModule.Sock_Type)) { - _PyArg_BadArgument("_wrap_socket", "argument 'sock'", (PySocketModule.Sock_Type)->tp_name, args[0]); + if (!PyObject_TypeCheck(args[0], get_state_ctx(self)->Sock_Type)) { + _PyArg_BadArgument("_wrap_socket", "argument 'sock'", (get_state_ctx(self)->Sock_Type)->tp_name, args[0]); goto exit; } sock = args[0]; - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } server_side = _PyLong_AsInt(args[1]); if (server_side == -1 && PyErr_Occurred()) { goto exit; @@ -764,21 +723,16 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t if (!args) { goto exit; } - if (!PyObject_TypeCheck(args[0], &PySSLMemoryBIO_Type)) { - _PyArg_BadArgument("_wrap_bio", "argument 'incoming'", (&PySSLMemoryBIO_Type)->tp_name, args[0]); + if (!PyObject_TypeCheck(args[0], get_state_ctx(self)->PySSLMemoryBIO_Type)) { + _PyArg_BadArgument("_wrap_bio", "argument 'incoming'", (get_state_ctx(self)->PySSLMemoryBIO_Type)->tp_name, args[0]); goto exit; } incoming = (PySSLMemoryBIO *)args[0]; - if (!PyObject_TypeCheck(args[1], &PySSLMemoryBIO_Type)) { - _PyArg_BadArgument("_wrap_bio", "argument 'outgoing'", (&PySSLMemoryBIO_Type)->tp_name, args[1]); + if (!PyObject_TypeCheck(args[1], get_state_ctx(self)->PySSLMemoryBIO_Type)) { + _PyArg_BadArgument("_wrap_bio", "argument 'outgoing'", (get_state_ctx(self)->PySSLMemoryBIO_Type)->tp_name, args[1]); goto exit; } outgoing = (PySSLMemoryBIO *)args[1]; - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } server_side = _PyLong_AsInt(args[2]); if (server_side == -1 && PyErr_Occurred()) { goto exit; @@ -844,8 +798,6 @@ _ssl__SSLContext_set_default_verify_paths(PySSLContext *self, PyObject *Py_UNUSE return _ssl__SSLContext_set_default_verify_paths_impl(self); } -#if !defined(OPENSSL_NO_ECDH) - PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, "set_ecdh_curve($self, name, /)\n" "--\n" @@ -854,8 +806,6 @@ PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF \ {"set_ecdh_curve", (PyCFunction)_ssl__SSLContext_set_ecdh_curve, METH_O, _ssl__SSLContext_set_ecdh_curve__doc__}, -#endif /* !defined(OPENSSL_NO_ECDH) */ - PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, "cert_store_stats($self, /)\n" "--\n" @@ -934,11 +884,11 @@ _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - if ((type == &PySSLMemoryBIO_Type) && + if ((type == get_state_type(type)->PySSLMemoryBIO_Type) && !_PyArg_NoPositional("MemoryBIO", args)) { goto exit; } - if ((type == &PySSLMemoryBIO_Type) && + if ((type == get_state_type(type)->PySSLMemoryBIO_Type) && !_PyArg_NoKeywords("MemoryBIO", kwargs)) { goto exit; } @@ -977,11 +927,6 @@ _ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *const *args, Py_ssize_t narg if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } len = _PyLong_AsInt(args[0]); if (len == -1 && PyErr_Occurred()) { goto exit; @@ -1132,11 +1077,6 @@ _ssl_RAND_bytes(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int n; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } n = _PyLong_AsInt(arg); if (n == -1 && PyErr_Occurred()) { goto exit; @@ -1168,11 +1108,6 @@ _ssl_RAND_pseudo_bytes(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int n; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } n = _PyLong_AsInt(arg); if (n == -1 && PyErr_Occurred()) { goto exit; @@ -1187,7 +1122,7 @@ PyDoc_STRVAR(_ssl_RAND_status__doc__, "RAND_status($module, /)\n" "--\n" "\n" -"Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n" +"Returns True if the OpenSSL PRNG has been seeded with enough data and False if not.\n" "\n" "It is necessary to seed the PRNG with RAND_add() on some platforms before\n" "using the ssl() function."); @@ -1204,40 +1139,6 @@ _ssl_RAND_status(PyObject *module, PyObject *Py_UNUSED(ignored)) return _ssl_RAND_status_impl(module); } -#if !defined(OPENSSL_NO_EGD) - -PyDoc_STRVAR(_ssl_RAND_egd__doc__, -"RAND_egd($module, path, /)\n" -"--\n" -"\n" -"Queries the entropy gather daemon (EGD) on the socket named by \'path\'.\n" -"\n" -"Returns number of bytes read. Raises SSLError if connection to EGD\n" -"fails or if it does not provide enough data to seed PRNG."); - -#define _SSL_RAND_EGD_METHODDEF \ - {"RAND_egd", (PyCFunction)_ssl_RAND_egd, METH_O, _ssl_RAND_egd__doc__}, - -static PyObject * -_ssl_RAND_egd_impl(PyObject *module, PyObject *path); - -static PyObject * -_ssl_RAND_egd(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *path; - - if (!PyUnicode_FSConverter(arg, &path)) { - goto exit; - } - return_value = _ssl_RAND_egd_impl(module, path); - -exit: - return return_value; -} - -#endif /* !defined(OPENSSL_NO_EGD) */ - PyDoc_STRVAR(_ssl_get_default_verify_paths__doc__, "get_default_verify_paths($module, /)\n" "--\n" @@ -1333,11 +1234,6 @@ _ssl_nid2obj(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int nid; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nid = _PyLong_AsInt(arg); if (nid == -1 && PyErr_Occurred()) { goto exit; @@ -1455,26 +1351,6 @@ exit: #endif /* defined(_MSC_VER) */ -#ifndef _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF - #define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF -#endif /* !defined(_SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF) */ - -#ifndef _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF - #define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF -#endif /* !defined(_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF) */ - -#ifndef _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF - #define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF -#endif /* !defined(_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF) */ - -#ifndef _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF - #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF -#endif /* !defined(_SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF) */ - -#ifndef _SSL_RAND_EGD_METHODDEF - #define _SSL_RAND_EGD_METHODDEF -#endif /* !defined(_SSL_RAND_EGD_METHODDEF) */ - #ifndef _SSL_ENUM_CERTIFICATES_METHODDEF #define _SSL_ENUM_CERTIFICATES_METHODDEF #endif /* !defined(_SSL_ENUM_CERTIFICATES_METHODDEF) */ @@ -1482,4 +1358,4 @@ exit: #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=a4aeb3f92a091c64 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a7d7bf5cf8ee092 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_struct.c.h b/contrib/tools/python3/src/Modules/clinic/_struct.c.h index 36c4b4046cd..b0c1eb4587a 100644 --- a/contrib/tools/python3/src/Modules/clinic/_struct.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_struct.c.h @@ -124,14 +124,9 @@ Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -204,7 +199,7 @@ calcsize(PyObject *module, PyObject *arg) PyStructObject *s_object = NULL; Py_ssize_t _return_value; - if (!cache_struct_converter(arg, &s_object)) { + if (!cache_struct_converter(module, arg, &s_object)) { goto exit; } _return_value = calcsize_impl(module, s_object); @@ -246,7 +241,7 @@ unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("unpack", nargs, 2, 2)) { goto exit; } - if (!cache_struct_converter(args[0], &s_object)) { + if (!cache_struct_converter(module, args[0], &s_object)) { goto exit; } if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { @@ -302,7 +297,7 @@ unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (!cache_struct_converter(args[0], &s_object)) { + if (!cache_struct_converter(module, args[0], &s_object)) { goto exit; } if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { @@ -315,14 +310,9 @@ unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -374,7 +364,7 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("iter_unpack", nargs, 2, 2)) { goto exit; } - if (!cache_struct_converter(args[0], &s_object)) { + if (!cache_struct_converter(module, args[0], &s_object)) { goto exit; } buffer = args[1]; @@ -386,4 +376,4 @@ exit: return return_value; } -/*[clinic end generated code: output=6a6228cfc4b7099c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a3d3cd900091cb1c input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h b/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h index 73c3faeaf96..9718986838f 100644 --- a/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h @@ -434,11 +434,6 @@ _tkinter_tkapp_createfilehandler(TkappObject *self, PyObject *const *args, Py_ss goto exit; } file = args[0]; - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mask = _PyLong_AsInt(args[1]); if (mask == -1 && PyErr_Occurred()) { goto exit; @@ -503,11 +498,6 @@ _tkinter_tkapp_createtimerhandler(TkappObject *self, PyObject *const *args, Py_s if (!_PyArg_CheckPositional("createtimerhandler", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } milliseconds = _PyLong_AsInt(args[0]); if (milliseconds == -1 && PyErr_Occurred()) { goto exit; @@ -542,11 +532,6 @@ _tkinter_tkapp_mainloop(TkappObject *self, PyObject *const *args, Py_ssize_t nar if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } threshold = _PyLong_AsInt(args[0]); if (threshold == -1 && PyErr_Occurred()) { goto exit; @@ -581,11 +566,6 @@ _tkinter_tkapp_dooneevent(TkappObject *self, PyObject *const *args, Py_ssize_t n if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[0]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -769,11 +749,6 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } interactive = _PyLong_AsInt(args[3]); if (interactive == -1 && PyErr_Occurred()) { goto exit; @@ -781,11 +756,6 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 5) { goto skip_optional; } - if (PyFloat_Check(args[4])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } wantobjects = _PyLong_AsInt(args[4]); if (wantobjects == -1 && PyErr_Occurred()) { goto exit; @@ -793,11 +763,6 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 6) { goto skip_optional; } - if (PyFloat_Check(args[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } wantTk = _PyLong_AsInt(args[5]); if (wantTk == -1 && PyErr_Occurred()) { goto exit; @@ -805,11 +770,6 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 7) { goto skip_optional; } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } sync = _PyLong_AsInt(args[6]); if (sync == -1 && PyErr_Occurred()) { goto exit; @@ -862,11 +822,6 @@ _tkinter_setbusywaitinterval(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int new_val; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } new_val = _PyLong_AsInt(arg); if (new_val == -1 && PyErr_Occurred()) { goto exit; @@ -912,4 +867,4 @@ exit: #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=492b8b833fe54bc9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ab311480dd044fe4 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h b/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h index 049cacd8326..20afd76f06f 100644 --- a/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h @@ -101,11 +101,6 @@ _tracemalloc_start(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nframe = _PyLong_AsInt(args[0]); if (nframe == -1 && PyErr_Occurred()) { goto exit; @@ -217,4 +212,4 @@ _tracemalloc_reset_peak(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _tracemalloc_reset_peak_impl(module); } -/*[clinic end generated code: output=a130117b1af821da input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bafca0a19b0b0823 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_winapi.c.h b/contrib/tools/python3/src/Modules/clinic/_winapi.c.h index e21f2bc2b6f..5bda156d7aa 100644 --- a/contrib/tools/python3/src/Modules/clinic/_winapi.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_winapi.c.h @@ -195,8 +195,8 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na LPCWSTR name; HANDLE _return_value; - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkku:CreateFileMapping", - &file_handle, &security_attributes, &protect, &max_size_high, &max_size_low, &name)) { + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkkO&:CreateFileMapping", + &file_handle, &security_attributes, &protect, &max_size_high, &max_size_low, _PyUnicode_WideCharString_Converter, &name)) { goto exit; } _return_value = _winapi_CreateFileMapping_impl(module, file_handle, security_attributes, protect, max_size_high, max_size_low, name); @@ -209,6 +209,11 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na return_value = HANDLE_TO_PYNUM(_return_value); exit: + /* Cleanup for name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -221,23 +226,55 @@ PyDoc_STRVAR(_winapi_CreateJunction__doc__, {"CreateJunction", (PyCFunction)(void(*)(void))_winapi_CreateJunction, METH_FASTCALL, _winapi_CreateJunction__doc__}, static PyObject * -_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, - LPWSTR dst_path); +_winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, + LPCWSTR dst_path); static PyObject * _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - LPWSTR src_path; - LPWSTR dst_path; + LPCWSTR src_path; + LPCWSTR dst_path; - if (!_PyArg_ParseStack(args, nargs, "uu:CreateJunction", - &src_path, &dst_path)) { + if (!_PyArg_CheckPositional("CreateJunction", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _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; + } + if (!PyUnicode_Check(args[1])) { + _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; } return_value = _winapi_CreateJunction_impl(module, src_path, dst_path); 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; } @@ -367,13 +404,22 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const Py_UNICODE *current_directory; PyObject *startup_info; - if (!_PyArg_ParseStack(args, nargs, "ZOOOikOZO:CreateProcess", - &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, ¤t_directory, &startup_info)) { + if (!_PyArg_ParseStack(args, nargs, "O&OOOikOO&O:CreateProcess", + _PyUnicode_WideCharString_Opt_Converter, &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, _PyUnicode_WideCharString_Opt_Converter, ¤t_directory, &startup_info)) { goto exit; } return_value = _winapi_CreateProcess_impl(module, application_name, command_line, proc_attrs, thread_attrs, inherit_handles, creation_flags, env_mapping, current_directory, startup_info); 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; } @@ -706,8 +752,8 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg LPCWSTR name; HANDLE _return_value; - if (!_PyArg_ParseStack(args, nargs, "kiu:OpenFileMapping", - &desired_access, &inherit_handle, &name)) { + if (!_PyArg_ParseStack(args, nargs, "kiO&:OpenFileMapping", + &desired_access, &inherit_handle, _PyUnicode_WideCharString_Converter, &name)) { goto exit; } _return_value = _winapi_OpenFileMapping_impl(module, desired_access, inherit_handle, name); @@ -720,6 +766,11 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg return_value = HANDLE_TO_PYNUM(_return_value); exit: + /* Cleanup for name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -1097,4 +1148,40 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=f3897898ea1da99d input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_winapi__mimetypes_read_windows_registry__doc__, +"_mimetypes_read_windows_registry($module, /, on_type_read)\n" +"--\n" +"\n" +"Optimized function for reading all known MIME types from the registry.\n" +"\n" +"*on_type_read* is a callable taking *type* and *ext* arguments, as for\n" +"MimeTypes.add_type."); + +#define _WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF \ + {"_mimetypes_read_windows_registry", (PyCFunction)(void(*)(void))_winapi__mimetypes_read_windows_registry, METH_FASTCALL|METH_KEYWORDS, _winapi__mimetypes_read_windows_registry__doc__}, + +static PyObject * +_winapi__mimetypes_read_windows_registry_impl(PyObject *module, + PyObject *on_type_read); + +static PyObject * +_winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"on_type_read", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_mimetypes_read_windows_registry", 0}; + PyObject *argsbuf[1]; + PyObject *on_type_read; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + on_type_read = args[0]; + return_value = _winapi__mimetypes_read_windows_registry_impl(module, on_type_read); + +exit: + return return_value; +} +/*[clinic end generated code: output=ac3623be6e42017c input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h b/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h index 005c7ffce4d..c46cc738de9 100644 --- a/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h @@ -39,13 +39,50 @@ PyDoc_STRVAR(array_array_count__doc__, {"count", (PyCFunction)array_array_count, METH_O, array_array_count__doc__}, PyDoc_STRVAR(array_array_index__doc__, -"index($self, v, /)\n" +"index($self, v, start=0, stop=sys.maxsize, /)\n" "--\n" "\n" -"Return index of first occurrence of v in the array."); +"Return index of first occurrence of v in the array.\n" +"\n" +"Raise ValueError if the value is not present."); #define ARRAY_ARRAY_INDEX_METHODDEF \ - {"index", (PyCFunction)array_array_index, METH_O, array_array_index__doc__}, + {"index", (PyCFunction)(void(*)(void))array_array_index, METH_FASTCALL, array_array_index__doc__}, + +static PyObject * +array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start, + Py_ssize_t stop); + +static PyObject * +array_array_index(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *v; + Py_ssize_t start = 0; + Py_ssize_t stop = PY_SSIZE_T_MAX; + + if (!_PyArg_CheckPositional("index", nargs, 1, 3)) { + goto exit; + } + v = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (!_PyEval_SliceIndexNotNone(args[1], &start)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyEval_SliceIndexNotNone(args[2], &stop)) { + goto exit; + } +skip_optional: + return_value = array_array_index_impl(self, v, start, stop); + +exit: + return return_value; +} PyDoc_STRVAR(array_array_remove__doc__, "remove($self, v, /)\n" @@ -82,14 +119,9 @@ array_array_pop(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -113,7 +145,28 @@ PyDoc_STRVAR(array_array_extend__doc__, "Append items to the end of the array."); #define ARRAY_ARRAY_EXTEND_METHODDEF \ - {"extend", (PyCFunction)array_array_extend, METH_O, array_array_extend__doc__}, + {"extend", (PyCFunction)(void(*)(void))array_array_extend, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_extend__doc__}, + +static PyObject * +array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb); + +static PyObject * +array_array_extend(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:extend", _keywords, 0}; + PyObject *bb; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &bb)) { + goto exit; + } + return_value = array_array_extend_impl(self, cls, bb); + +exit: + return return_value; +} PyDoc_STRVAR(array_array_insert__doc__, "insert($self, i, v, /)\n" @@ -137,14 +190,9 @@ array_array_insert(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -253,14 +301,9 @@ array_array_fromfile(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } f = args[0]; - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -483,11 +526,6 @@ array__array_reconstructor(PyObject *module, PyObject *const *args, Py_ssize_t n goto exit; } typecode = PyUnicode_READ_CHAR(args[1], 0); - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mformat_code = _PyLong_AsInt(args[2]); if (mformat_code == -1 && PyErr_Occurred()) { goto exit; @@ -534,4 +572,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=485e848d1f3d05e7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f130a994f98f1227 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/audioop.c.h b/contrib/tools/python3/src/Modules/clinic/audioop.c.h index 8745533eeb6..da12bd17b5a 100644 --- a/contrib/tools/python3/src/Modules/clinic/audioop.c.h +++ b/contrib/tools/python3/src/Modules/clinic/audioop.c.h @@ -33,23 +33,13 @@ audioop_getsample(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("getsample", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -99,11 +89,6 @@ audioop_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("max", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -148,11 +133,6 @@ audioop_minmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("minmax", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -197,11 +177,6 @@ audioop_avg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("avg", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -246,11 +221,6 @@ audioop_rms(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("rms", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -400,14 +370,9 @@ audioop_findmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("findmax", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -457,11 +422,6 @@ audioop_avgpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("avgpp", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -506,11 +466,6 @@ audioop_maxpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("maxpp", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -555,11 +510,6 @@ audioop_cross(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("cross", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -606,11 +556,6 @@ audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("mul", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -668,11 +613,6 @@ audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("tomono", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -740,11 +680,6 @@ audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("tostereo", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -818,11 +753,6 @@ audioop_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("add", "argument 2", "contiguous buffer", args[1]); goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[2]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -872,20 +802,10 @@ audioop_bias(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("bias", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } bias = _PyLong_AsInt(args[2]); if (bias == -1 && PyErr_Occurred()) { goto exit; @@ -930,11 +850,6 @@ audioop_reverse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("reverse", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -979,11 +894,6 @@ audioop_byteswap(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("byteswap", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -1030,20 +940,10 @@ audioop_lin2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("lin2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } newwidth = _PyLong_AsInt(args[2]); if (newwidth == -1 && PyErr_Occurred()) { goto exit; @@ -1097,38 +997,18 @@ audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("ratecv", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nchannels = _PyLong_AsInt(args[2]); if (nchannels == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } inrate = _PyLong_AsInt(args[3]); if (inrate == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[4])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } outrate = _PyLong_AsInt(args[4]); if (outrate == -1 && PyErr_Occurred()) { goto exit; @@ -1137,11 +1017,6 @@ audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 7) { goto skip_optional; } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } weightA = _PyLong_AsInt(args[6]); if (weightA == -1 && PyErr_Occurred()) { goto exit; @@ -1149,11 +1024,6 @@ audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 8) { goto skip_optional; } - if (PyFloat_Check(args[7])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } weightB = _PyLong_AsInt(args[7]); if (weightB == -1 && PyErr_Occurred()) { goto exit; @@ -1199,11 +1069,6 @@ audioop_lin2ulaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("lin2ulaw", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -1248,11 +1113,6 @@ audioop_ulaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("ulaw2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -1297,11 +1157,6 @@ audioop_lin2alaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("lin2alaw", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -1346,11 +1201,6 @@ audioop_alaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("alaw2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -1397,11 +1247,6 @@ audioop_lin2adpcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("lin2adpcm", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -1449,11 +1294,6 @@ audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("adpcm2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } width = _PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; @@ -1469,4 +1309,4 @@ exit: return return_value; } -/*[clinic end generated code: output=6b4f2c597f295abc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=840f8c315ebd4946 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/binascii.c.h b/contrib/tools/python3/src/Modules/clinic/binascii.c.h index 4d02c72c472..ae1c4574325 100644 --- a/contrib/tools/python3/src/Modules/clinic/binascii.c.h +++ b/contrib/tools/python3/src/Modules/clinic/binascii.c.h @@ -70,11 +70,6 @@ binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_kwonly; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } backtick = _PyLong_AsInt(args[1]); if (backtick == -1 && PyErr_Occurred()) { goto exit; @@ -159,11 +154,6 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_kwonly; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } newline = _PyLong_AsInt(args[1]); if (newline == -1 && PyErr_Occurred()) { goto exit; @@ -348,11 +338,6 @@ binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("crc_hqx", "argument 1", "contiguous buffer", args[0]); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); if (crc == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -401,11 +386,6 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); if (crc == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -488,11 +468,6 @@ binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } bytes_per_sep = _PyLong_AsInt(args[2]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; @@ -563,11 +538,6 @@ binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } bytes_per_sep = _PyLong_AsInt(args[2]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; @@ -684,11 +654,6 @@ binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } header = _PyLong_AsInt(args[1]); if (header == -1 && PyErr_Occurred()) { goto exit; @@ -749,11 +714,6 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } quotetabs = _PyLong_AsInt(args[1]); if (quotetabs == -1 && PyErr_Occurred()) { goto exit; @@ -763,11 +723,6 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } istext = _PyLong_AsInt(args[2]); if (istext == -1 && PyErr_Occurred()) { goto exit; @@ -776,11 +731,6 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } header = _PyLong_AsInt(args[3]); if (header == -1 && PyErr_Occurred()) { goto exit; @@ -796,4 +746,4 @@ exit: return return_value; } -/*[clinic end generated code: output=a1e878d3963b615e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=95a0178f30801b89 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h b/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h index 024a44cfbf8..adf527fd443 100644 --- a/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h @@ -35,12 +35,7 @@ fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("fcntl", nargs, 2, 3)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = _PyLong_AsInt(args[1]); @@ -110,12 +105,7 @@ fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ioctl", nargs, 2, 4)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); @@ -165,12 +155,7 @@ fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("flock", nargs, 2, 2)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = _PyLong_AsInt(args[1]); @@ -230,12 +215,7 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("lockf", nargs, 2, 5)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = _PyLong_AsInt(args[1]); @@ -253,11 +233,6 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 5) { goto skip_optional; } - if (PyFloat_Check(args[4])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } whence = _PyLong_AsInt(args[4]); if (whence == -1 && PyErr_Occurred()) { goto exit; @@ -268,4 +243,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=e912d25e28362c52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8ea34bd0f7cf25ec input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h b/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h index 72795c66bf7..30efc7e0c2c 100644 --- a/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h @@ -102,11 +102,6 @@ gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } generation = _PyLong_AsInt(args[0]); if (generation == -1 && PyErr_Occurred()) { goto exit; @@ -151,11 +146,6 @@ gc_set_debug(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flags; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(arg); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -382,4 +372,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=bd6a8056989e2e69 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=61e15f3a549f3ab5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/itertoolsmodule.c.h b/contrib/tools/python3/src/Modules/clinic/itertoolsmodule.c.h index 251b67b17ea..d3f54221dd4 100644 --- a/contrib/tools/python3/src/Modules/clinic/itertoolsmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/itertoolsmodule.c.h @@ -2,6 +2,37 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(pairwise_new__doc__, +"pairwise(iterable, /)\n" +"--\n" +"\n" +"Return an iterator of overlapping pairs taken from the input iterator.\n" +"\n" +" s -> (s0,s1), (s1,s2), (s2, s3), ..."); + +static PyObject * +pairwise_new_impl(PyTypeObject *type, PyObject *iterable); + +static PyObject * +pairwise_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *iterable; + + if ((type == &pairwise_type) && + !_PyArg_NoKeywords("pairwise", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("pairwise", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + iterable = PyTuple_GET_ITEM(args, 0); + return_value = pairwise_new_impl(type, iterable); + +exit: + return return_value; +} + PyDoc_STRVAR(itertools_groupby__doc__, "groupby(iterable, key=None)\n" "--\n" @@ -170,14 +201,9 @@ itertools_tee(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -356,14 +382,9 @@ itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } iterable = fastargs[0]; - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(fastargs[1]); + PyObject *iobj = _PyNumber_Index(fastargs[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -409,14 +430,9 @@ itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyOb goto exit; } iterable = fastargs[0]; - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(fastargs[1]); + PyObject *iobj = _PyNumber_Index(fastargs[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -642,4 +658,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=0c2799c88400b63f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c91f57481a2461d3 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/md5module.c.h b/contrib/tools/python3/src/Modules/clinic/md5module.c.h index c109f9efec6..4762f2800d4 100644 --- a/contrib/tools/python3/src/Modules/clinic/md5module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/md5module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(MD5Type_copy__doc__, "Return a copy of the hash object."); #define MD5TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)MD5Type_copy, METH_NOARGS, MD5Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))MD5Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, MD5Type_copy__doc__}, static PyObject * -MD5Type_copy_impl(MD5object *self); +MD5Type_copy_impl(MD5object *self, PyTypeObject *cls); static PyObject * -MD5Type_copy(MD5object *self, PyObject *Py_UNUSED(ignored)) +MD5Type_copy(MD5object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return MD5Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = MD5Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(MD5Type_digest__doc__, @@ -115,4 +126,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=dbe3abc60086f3ef input=a9049054013a1b77]*/ +/*[clinic end generated code: output=53ff7f22dbaaea36 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/overlapped.c.h b/contrib/tools/python3/src/Modules/clinic/overlapped.c.h new file mode 100644 index 00000000000..efecd9028b7 --- /dev/null +++ b/contrib/tools/python3/src/Modules/clinic/overlapped.c.h @@ -0,0 +1,908 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, +"CreateIoCompletionPort($module, handle, port, key, concurrency, /)\n" +"--\n" +"\n" +"Create a completion port or register a handle with a port."); + +#define _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF \ + {"CreateIoCompletionPort", (PyCFunction)(void(*)(void))_overlapped_CreateIoCompletionPort, METH_FASTCALL, _overlapped_CreateIoCompletionPort__doc__}, + +static PyObject * +_overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle, + HANDLE ExistingCompletionPort, + ULONG_PTR CompletionKey, + DWORD NumberOfConcurrentThreads); + +static PyObject * +_overlapped_CreateIoCompletionPort(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE FileHandle; + HANDLE ExistingCompletionPort; + ULONG_PTR CompletionKey; + DWORD NumberOfConcurrentThreads; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_ULONG_PTR"k:CreateIoCompletionPort", + &FileHandle, &ExistingCompletionPort, &CompletionKey, &NumberOfConcurrentThreads)) { + goto exit; + } + return_value = _overlapped_CreateIoCompletionPort_impl(module, FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_GetQueuedCompletionStatus__doc__, +"GetQueuedCompletionStatus($module, port, msecs, /)\n" +"--\n" +"\n" +"Get a message from completion port.\n" +"\n" +"Wait for up to msecs milliseconds."); + +#define _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF \ + {"GetQueuedCompletionStatus", (PyCFunction)(void(*)(void))_overlapped_GetQueuedCompletionStatus, METH_FASTCALL, _overlapped_GetQueuedCompletionStatus__doc__}, + +static PyObject * +_overlapped_GetQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD Milliseconds); + +static PyObject * +_overlapped_GetQueuedCompletionStatus(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE CompletionPort; + DWORD Milliseconds; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:GetQueuedCompletionStatus", + &CompletionPort, &Milliseconds)) { + goto exit; + } + return_value = _overlapped_GetQueuedCompletionStatus_impl(module, CompletionPort, Milliseconds); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_PostQueuedCompletionStatus__doc__, +"PostQueuedCompletionStatus($module, port, bytes, key, address, /)\n" +"--\n" +"\n" +"Post a message to completion port."); + +#define _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF \ + {"PostQueuedCompletionStatus", (PyCFunction)(void(*)(void))_overlapped_PostQueuedCompletionStatus, METH_FASTCALL, _overlapped_PostQueuedCompletionStatus__doc__}, + +static PyObject * +_overlapped_PostQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD NumberOfBytes, + ULONG_PTR CompletionKey, + OVERLAPPED *Overlapped); + +static PyObject * +_overlapped_PostQueuedCompletionStatus(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE CompletionPort; + DWORD NumberOfBytes; + ULONG_PTR CompletionKey; + OVERLAPPED *Overlapped; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k"F_ULONG_PTR""F_POINTER":PostQueuedCompletionStatus", + &CompletionPort, &NumberOfBytes, &CompletionKey, &Overlapped)) { + goto exit; + } + return_value = _overlapped_PostQueuedCompletionStatus_impl(module, CompletionPort, NumberOfBytes, CompletionKey, Overlapped); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_RegisterWaitWithQueue__doc__, +"RegisterWaitWithQueue($module, Object, CompletionPort, Overlapped,\n" +" Timeout, /)\n" +"--\n" +"\n" +"Register wait for Object; when complete CompletionPort is notified."); + +#define _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF \ + {"RegisterWaitWithQueue", (PyCFunction)(void(*)(void))_overlapped_RegisterWaitWithQueue, METH_FASTCALL, _overlapped_RegisterWaitWithQueue__doc__}, + +static PyObject * +_overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, + HANDLE CompletionPort, + OVERLAPPED *Overlapped, + DWORD Milliseconds); + +static PyObject * +_overlapped_RegisterWaitWithQueue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Object; + HANDLE CompletionPort; + OVERLAPPED *Overlapped; + DWORD Milliseconds; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_POINTER"k:RegisterWaitWithQueue", + &Object, &CompletionPort, &Overlapped, &Milliseconds)) { + goto exit; + } + return_value = _overlapped_RegisterWaitWithQueue_impl(module, Object, CompletionPort, Overlapped, Milliseconds); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_UnregisterWait__doc__, +"UnregisterWait($module, WaitHandle, /)\n" +"--\n" +"\n" +"Unregister wait handle."); + +#define _OVERLAPPED_UNREGISTERWAIT_METHODDEF \ + {"UnregisterWait", (PyCFunction)_overlapped_UnregisterWait, METH_O, _overlapped_UnregisterWait__doc__}, + +static PyObject * +_overlapped_UnregisterWait_impl(PyObject *module, HANDLE WaitHandle); + +static PyObject * +_overlapped_UnregisterWait(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE WaitHandle; + + if (!PyArg_Parse(arg, ""F_HANDLE":UnregisterWait", &WaitHandle)) { + goto exit; + } + return_value = _overlapped_UnregisterWait_impl(module, WaitHandle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_UnregisterWaitEx__doc__, +"UnregisterWaitEx($module, WaitHandle, Event, /)\n" +"--\n" +"\n" +"Unregister wait handle."); + +#define _OVERLAPPED_UNREGISTERWAITEX_METHODDEF \ + {"UnregisterWaitEx", (PyCFunction)(void(*)(void))_overlapped_UnregisterWaitEx, METH_FASTCALL, _overlapped_UnregisterWaitEx__doc__}, + +static PyObject * +_overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle, + HANDLE Event); + +static PyObject * +_overlapped_UnregisterWaitEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE WaitHandle; + HANDLE Event; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":UnregisterWaitEx", + &WaitHandle, &Event)) { + goto exit; + } + return_value = _overlapped_UnregisterWaitEx_impl(module, WaitHandle, Event); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_CreateEvent__doc__, +"CreateEvent($module, EventAttributes, ManualReset, InitialState, Name,\n" +" /)\n" +"--\n" +"\n" +"Create an event.\n" +"\n" +"EventAttributes must be None."); + +#define _OVERLAPPED_CREATEEVENT_METHODDEF \ + {"CreateEvent", (PyCFunction)(void(*)(void))_overlapped_CreateEvent, METH_FASTCALL, _overlapped_CreateEvent__doc__}, + +static PyObject * +_overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes, + BOOL ManualReset, BOOL InitialState, + const Py_UNICODE *Name); + +static PyObject * +_overlapped_CreateEvent(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *EventAttributes; + BOOL ManualReset; + BOOL InitialState; + const Py_UNICODE *Name; + + if (!_PyArg_ParseStack(args, nargs, "OiiO&:CreateEvent", + &EventAttributes, &ManualReset, &InitialState, _PyUnicode_WideCharString_Opt_Converter, &Name)) { + 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; +} + +PyDoc_STRVAR(_overlapped_SetEvent__doc__, +"SetEvent($module, Handle, /)\n" +"--\n" +"\n" +"Set event."); + +#define _OVERLAPPED_SETEVENT_METHODDEF \ + {"SetEvent", (PyCFunction)_overlapped_SetEvent, METH_O, _overlapped_SetEvent__doc__}, + +static PyObject * +_overlapped_SetEvent_impl(PyObject *module, HANDLE Handle); + +static PyObject * +_overlapped_SetEvent(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE Handle; + + if (!PyArg_Parse(arg, ""F_HANDLE":SetEvent", &Handle)) { + goto exit; + } + return_value = _overlapped_SetEvent_impl(module, Handle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_ResetEvent__doc__, +"ResetEvent($module, Handle, /)\n" +"--\n" +"\n" +"Reset event."); + +#define _OVERLAPPED_RESETEVENT_METHODDEF \ + {"ResetEvent", (PyCFunction)_overlapped_ResetEvent, METH_O, _overlapped_ResetEvent__doc__}, + +static PyObject * +_overlapped_ResetEvent_impl(PyObject *module, HANDLE Handle); + +static PyObject * +_overlapped_ResetEvent(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE Handle; + + if (!PyArg_Parse(arg, ""F_HANDLE":ResetEvent", &Handle)) { + goto exit; + } + return_value = _overlapped_ResetEvent_impl(module, Handle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_BindLocal__doc__, +"BindLocal($module, handle, family, /)\n" +"--\n" +"\n" +"Bind a socket handle to an arbitrary local port.\n" +"\n" +"family should be AF_INET or AF_INET6."); + +#define _OVERLAPPED_BINDLOCAL_METHODDEF \ + {"BindLocal", (PyCFunction)(void(*)(void))_overlapped_BindLocal, METH_FASTCALL, _overlapped_BindLocal__doc__}, + +static PyObject * +_overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family); + +static PyObject * +_overlapped_BindLocal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Socket; + int Family; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:BindLocal", + &Socket, &Family)) { + goto exit; + } + return_value = _overlapped_BindLocal_impl(module, Socket, Family); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_FormatMessage__doc__, +"FormatMessage($module, error_code, /)\n" +"--\n" +"\n" +"Return error message for an error code."); + +#define _OVERLAPPED_FORMATMESSAGE_METHODDEF \ + {"FormatMessage", (PyCFunction)_overlapped_FormatMessage, METH_O, _overlapped_FormatMessage__doc__}, + +static PyObject * +_overlapped_FormatMessage_impl(PyObject *module, DWORD code); + +static PyObject * +_overlapped_FormatMessage(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + DWORD code; + + if (!PyArg_Parse(arg, "k:FormatMessage", &code)) { + goto exit; + } + return_value = _overlapped_FormatMessage_impl(module, code); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped__doc__, +"Overlapped(event=_overlapped.INVALID_HANDLE_VALUE)\n" +"--\n" +"\n" +"OVERLAPPED structure wrapper."); + +static PyObject * +_overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event); + +static PyObject * +_overlapped_Overlapped(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"event", NULL}; + static _PyArg_Parser _parser = {"|"F_HANDLE":Overlapped", _keywords, 0}; + HANDLE event = INVALID_HANDLE_VALUE; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &event)) { + goto exit; + } + return_value = _overlapped_Overlapped_impl(type, event); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_cancel__doc__, +"cancel($self, /)\n" +"--\n" +"\n" +"Cancel overlapped operation."); + +#define _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF \ + {"cancel", (PyCFunction)_overlapped_Overlapped_cancel, METH_NOARGS, _overlapped_Overlapped_cancel__doc__}, + +static PyObject * +_overlapped_Overlapped_cancel_impl(OverlappedObject *self); + +static PyObject * +_overlapped_Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _overlapped_Overlapped_cancel_impl(self); +} + +PyDoc_STRVAR(_overlapped_Overlapped_getresult__doc__, +"getresult($self, wait=False, /)\n" +"--\n" +"\n" +"Retrieve result of operation.\n" +"\n" +"If wait is true then it blocks until the operation is finished. If wait\n" +"is false and the operation is still pending then an error is raised."); + +#define _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF \ + {"getresult", (PyCFunction)(void(*)(void))_overlapped_Overlapped_getresult, METH_FASTCALL, _overlapped_Overlapped_getresult__doc__}, + +static PyObject * +_overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait); + +static PyObject * +_overlapped_Overlapped_getresult(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + BOOL wait = FALSE; + + if (!_PyArg_ParseStack(args, nargs, "|i:getresult", + &wait)) { + goto exit; + } + return_value = _overlapped_Overlapped_getresult_impl(self, wait); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ReadFile__doc__, +"ReadFile($self, handle, size, /)\n" +"--\n" +"\n" +"Start overlapped read."); + +#define _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF \ + {"ReadFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ReadFile, METH_FASTCALL, _overlapped_Overlapped_ReadFile__doc__}, + +static PyObject * +_overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, + DWORD size); + +static PyObject * +_overlapped_Overlapped_ReadFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD size; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:ReadFile", + &handle, &size)) { + goto exit; + } + return_value = _overlapped_Overlapped_ReadFile_impl(self, handle, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ReadFileInto__doc__, +"ReadFileInto($self, handle, buf, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF \ + {"ReadFileInto", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ReadFileInto, METH_FASTCALL, _overlapped_Overlapped_ReadFileInto__doc__}, + +static PyObject * +_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj); + +static PyObject * +_overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:ReadFileInto", + &handle, &bufobj)) { + goto exit; + } + return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, bufobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecv__doc__, +"WSARecv($self, handle, size, flags=0, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF \ + {"WSARecv", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecv, METH_FASTCALL, _overlapped_Overlapped_WSARecv__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, + DWORD size, DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecv(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD size; + DWORD flags = 0; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecv", + &handle, &size, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecv_impl(self, handle, size, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecvInto__doc__, +"WSARecvInto($self, handle, buf, flags, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF \ + {"WSARecvInto", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecvInto, METH_FASTCALL, _overlapped_Overlapped_WSARecvInto__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj, + DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + DWORD flags; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSARecvInto", + &handle, &bufobj, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, bufobj, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WriteFile__doc__, +"WriteFile($self, handle, buf, /)\n" +"--\n" +"\n" +"Start overlapped write."); + +#define _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF \ + {"WriteFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WriteFile, METH_FASTCALL, _overlapped_Overlapped_WriteFile__doc__}, + +static PyObject * +_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj); + +static PyObject * +_overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WriteFile", + &handle, &bufobj)) { + goto exit; + } + return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, bufobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSASend__doc__, +"WSASend($self, handle, buf, flags, /)\n" +"--\n" +"\n" +"Start overlapped send."); + +#define _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF \ + {"WSASend", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSASend, METH_FASTCALL, _overlapped_Overlapped_WSASend__doc__}, + +static PyObject * +_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + DWORD flags; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSASend", + &handle, &bufobj, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSASend_impl(self, handle, bufobj, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_AcceptEx__doc__, +"AcceptEx($self, listen_handle, accept_handle, /)\n" +"--\n" +"\n" +"Start overlapped wait for client to connect."); + +#define _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF \ + {"AcceptEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_AcceptEx, METH_FASTCALL, _overlapped_Overlapped_AcceptEx__doc__}, + +static PyObject * +_overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self, + HANDLE ListenSocket, + HANDLE AcceptSocket); + +static PyObject * +_overlapped_Overlapped_AcceptEx(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE ListenSocket; + HANDLE AcceptSocket; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":AcceptEx", + &ListenSocket, &AcceptSocket)) { + goto exit; + } + return_value = _overlapped_Overlapped_AcceptEx_impl(self, ListenSocket, AcceptSocket); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ConnectEx__doc__, +"ConnectEx($self, client_handle, address_as_bytes, /)\n" +"--\n" +"\n" +"Start overlapped connect.\n" +"\n" +"client_handle should be unbound."); + +#define _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF \ + {"ConnectEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ConnectEx, METH_FASTCALL, _overlapped_Overlapped_ConnectEx__doc__}, + +static PyObject * +_overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self, + HANDLE ConnectSocket, + PyObject *AddressObj); + +static PyObject * +_overlapped_Overlapped_ConnectEx(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE ConnectSocket; + PyObject *AddressObj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O!:ConnectEx", + &ConnectSocket, &PyTuple_Type, &AddressObj)) { + goto exit; + } + return_value = _overlapped_Overlapped_ConnectEx_impl(self, ConnectSocket, AddressObj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_DisconnectEx__doc__, +"DisconnectEx($self, handle, flags, /)\n" +"--\n" +"\n"); + +#define _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF \ + {"DisconnectEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_DisconnectEx, METH_FASTCALL, _overlapped_Overlapped_DisconnectEx__doc__}, + +static PyObject * +_overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self, + HANDLE Socket, DWORD flags); + +static PyObject * +_overlapped_Overlapped_DisconnectEx(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Socket; + DWORD flags; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:DisconnectEx", + &Socket, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_DisconnectEx_impl(self, Socket, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_TransmitFile__doc__, +"TransmitFile($self, socket, file, offset, offset_high, count_to_write,\n" +" count_per_send, flags, /)\n" +"--\n" +"\n" +"Transmit file data over a connected socket."); + +#define _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF \ + {"TransmitFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_TransmitFile, METH_FASTCALL, _overlapped_Overlapped_TransmitFile__doc__}, + +static PyObject * +_overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self, + HANDLE Socket, HANDLE File, + DWORD offset, DWORD offset_high, + DWORD count_to_write, + DWORD count_per_send, DWORD flags); + +static PyObject * +_overlapped_Overlapped_TransmitFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Socket; + HANDLE File; + DWORD offset; + DWORD offset_high; + DWORD count_to_write; + 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)) { + goto exit; + } + return_value = _overlapped_Overlapped_TransmitFile_impl(self, Socket, File, offset, offset_high, count_to_write, count_per_send, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ConnectNamedPipe__doc__, +"ConnectNamedPipe($self, handle, /)\n" +"--\n" +"\n" +"Start overlapped wait for a client to connect."); + +#define _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF \ + {"ConnectNamedPipe", (PyCFunction)_overlapped_Overlapped_ConnectNamedPipe, METH_O, _overlapped_Overlapped_ConnectNamedPipe__doc__}, + +static PyObject * +_overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self, + HANDLE Pipe); + +static PyObject * +_overlapped_Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE Pipe; + + if (!PyArg_Parse(arg, ""F_HANDLE":ConnectNamedPipe", &Pipe)) { + goto exit; + } + return_value = _overlapped_Overlapped_ConnectNamedPipe_impl(self, Pipe); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ConnectPipe__doc__, +"ConnectPipe($self, addr, /)\n" +"--\n" +"\n" +"Connect to the pipe for asynchronous I/O (overlapped)."); + +#define _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF \ + {"ConnectPipe", (PyCFunction)_overlapped_Overlapped_ConnectPipe, METH_O, _overlapped_Overlapped_ConnectPipe__doc__}, + +static PyObject * +_overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self, + const Py_UNICODE *Address); + +static PyObject * +_overlapped_Overlapped_ConnectPipe(OverlappedObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const Py_UNICODE *Address; + + if (!PyUnicode_Check(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; + } + return_value = _overlapped_Overlapped_ConnectPipe_impl(self, Address); + +exit: + /* Cleanup for Address */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)Address); + #endif /* USE_UNICODE_WCHAR_CACHE */ + + return return_value; +} + +PyDoc_STRVAR(_overlapped_WSAConnect__doc__, +"WSAConnect($module, client_handle, address_as_bytes, /)\n" +"--\n" +"\n" +"Bind a remote address to a connectionless (UDP) socket."); + +#define _OVERLAPPED_WSACONNECT_METHODDEF \ + {"WSAConnect", (PyCFunction)(void(*)(void))_overlapped_WSAConnect, METH_FASTCALL, _overlapped_WSAConnect__doc__}, + +static PyObject * +_overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, + PyObject *AddressObj); + +static PyObject * +_overlapped_WSAConnect(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE ConnectSocket; + PyObject *AddressObj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WSAConnect", + &ConnectSocket, &AddressObj)) { + goto exit; + } + return_value = _overlapped_WSAConnect_impl(module, ConnectSocket, AddressObj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSASendTo__doc__, +"WSASendTo($self, handle, buf, flags, address_as_bytes, /)\n" +"--\n" +"\n" +"Start overlapped sendto over a connectionless (UDP) socket."); + +#define _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF \ + {"WSASendTo", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSASendTo, METH_FASTCALL, _overlapped_Overlapped_WSASendTo__doc__}, + +static PyObject * +_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags, + PyObject *AddressObj); + +static PyObject * +_overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + DWORD flags; + PyObject *AddressObj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"OkO:WSASendTo", + &handle, &bufobj, &flags, &AddressObj)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, bufobj, flags, AddressObj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecvFrom__doc__, +"WSARecvFrom($self, handle, size, flags=0, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF \ + {"WSARecvFrom", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecvFrom, METH_FASTCALL, _overlapped_Overlapped_WSARecvFrom__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, + HANDLE handle, DWORD size, + DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD size; + DWORD flags = 0; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecvFrom", + &handle, &size, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecvFrom_impl(self, handle, size, flags); + +exit: + return return_value; +} +/*[clinic end generated code: output=ee2ec2f93c8d334b input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h b/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h index 28798ab99c1..7921c222b90 100644 --- a/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h @@ -187,11 +187,6 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!path_converter(args[0], &path)) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -257,11 +252,6 @@ os_ttyname(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -367,7 +357,7 @@ os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = os_fchdir_impl(module, fd); @@ -431,11 +421,6 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!path_converter(args[0], &path)) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -495,20 +480,10 @@ os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -555,11 +530,6 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!path_converter(args[0], &path)) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -757,7 +727,7 @@ os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = os_fsync_impl(module, fd); @@ -817,7 +787,7 @@ os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = os_fdatasync_impl(module, fd); @@ -952,11 +922,6 @@ os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -1394,11 +1359,6 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto skip_optional_pos; } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -1444,11 +1404,6 @@ os_nice(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int increment; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } increment = _PyLong_AsInt(arg); if (increment == -1 && PyErr_Occurred()) { goto exit; @@ -1489,20 +1444,10 @@ os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } which = _PyLong_AsInt(args[0]); if (which == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } who = _PyLong_AsInt(args[1]); if (who == -1 && PyErr_Occurred()) { goto exit; @@ -1544,29 +1489,14 @@ os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } which = _PyLong_AsInt(args[0]); if (which == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } who = _PyLong_AsInt(args[1]); if (who == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } priority = _PyLong_AsInt(args[2]); if (priority == -1 && PyErr_Occurred()) { goto exit; @@ -1785,12 +1715,25 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k { PyObject *return_value = NULL; static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {"u:system", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + PyObject *argsbuf[1]; const Py_UNICODE *command; long _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &command)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _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; } _return_value = os_system_impl(module, command); @@ -1800,6 +1743,11 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k return_value = PyLong_FromLong(_return_value); exit: + /* Cleanup for command */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)command); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -1869,11 +1817,6 @@ os_umask(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int mask; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mask = _PyLong_AsInt(arg); if (mask == -1 && PyErr_Occurred()) { goto exit; @@ -2134,11 +2077,6 @@ os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -2330,11 +2268,6 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[5]) { - if (PyFloat_Check(args[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } resetids = _PyLong_AsInt(args[5]); if (resetids == -1 && PyErr_Occurred()) { goto exit; @@ -2344,11 +2277,6 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[6]) { - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } setsid = _PyLong_AsInt(args[6]); if (setsid == -1 && PyErr_Occurred()) { goto exit; @@ -2467,11 +2395,6 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[5]) { - if (PyFloat_Check(args[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } resetids = _PyLong_AsInt(args[5]); if (resetids == -1 && PyErr_Occurred()) { goto exit; @@ -2481,11 +2404,6 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[6]) { - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } setsid = _PyLong_AsInt(args[6]); if (setsid == -1 && PyErr_Occurred()) { goto exit; @@ -2551,11 +2469,6 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[0]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -2611,11 +2524,6 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("spawnve", nargs, 4, 4)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[0]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -2779,11 +2687,6 @@ os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t na if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } policy = _PyLong_AsInt(args[0]); if (policy == -1 && PyErr_Occurred()) { goto exit; @@ -2823,11 +2726,6 @@ os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t na if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } policy = _PyLong_AsInt(args[0]); if (policy == -1 && PyErr_Occurred()) { goto exit; @@ -3329,11 +3227,6 @@ os_getgrouplist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } basegid = _PyLong_AsInt(args[1]); if (basegid == -1 && PyErr_Occurred()) { goto exit; @@ -3452,11 +3345,6 @@ os_initgroups(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!PyUnicode_FSConverter(args[0], &oname)) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } gid = _PyLong_AsInt(args[1]); if (gid == -1 && PyErr_Occurred()) { goto exit; @@ -3750,11 +3638,6 @@ os_plock(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int op; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } op = _PyLong_AsInt(arg); if (op == -1 && PyErr_Occurred()) { goto exit; @@ -4010,11 +3893,6 @@ os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } options = _PyLong_AsInt(args[0]); if (options == -1 && PyErr_Occurred()) { goto exit; @@ -4518,11 +4396,6 @@ os_tcgetpgrp(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -4606,11 +4479,6 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn if (!path_converter(args[0], &path)) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -4619,11 +4487,6 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn goto skip_optional_pos; } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -4678,11 +4541,6 @@ os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -4715,20 +4573,10 @@ os_closerange(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("closerange", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd_low = _PyLong_AsInt(args[0]); if (fd_low == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd_high = _PyLong_AsInt(args[1]); if (fd_high == -1 && PyErr_Occurred()) { goto exit; @@ -4758,11 +4606,6 @@ os_dup(PyObject *module, PyObject *arg) int fd; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -4806,20 +4649,10 @@ os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd2 = _PyLong_AsInt(args[1]); if (fd2 == -1 && PyErr_Occurred()) { goto exit; @@ -4874,20 +4707,10 @@ os_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("lockf", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } command = _PyLong_AsInt(args[1]); if (command == -1 && PyErr_Occurred()) { goto exit; @@ -4930,11 +4753,6 @@ os_lseek(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("lseek", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -4942,11 +4760,6 @@ os_lseek(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!Py_off_t_converter(args[1], &position)) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } how = _PyLong_AsInt(args[2]); if (how == -1 && PyErr_Occurred()) { goto exit; @@ -4983,23 +4796,13 @@ os_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("read", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -5048,11 +4851,6 @@ os_readv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("readv", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5098,23 +4896,13 @@ os_pread(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("pread", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -5177,11 +4965,6 @@ os_preadv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("preadv", nargs, 3, 4)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5193,11 +4976,6 @@ os_preadv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -5238,11 +5016,6 @@ os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("write", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5306,20 +5079,10 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } out_fd = _PyLong_AsInt(args[0]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } in_fd = _PyLong_AsInt(args[1]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; @@ -5345,11 +5108,6 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[6]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -5400,20 +5158,10 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } out_fd = _PyLong_AsInt(args[0]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } in_fd = _PyLong_AsInt(args[1]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; @@ -5421,14 +5169,9 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!Py_off_t_converter(args[2], &offset)) { goto exit; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[3]); + PyObject *iobj = _PyNumber_Index(args[3]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -5453,11 +5196,6 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[6]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -5502,33 +5240,18 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } out_fd = _PyLong_AsInt(args[0]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } in_fd = _PyLong_AsInt(args[1]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; } offobj = args[2]; - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[3]); + PyObject *iobj = _PyNumber_Index(args[3]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -5571,29 +5294,14 @@ os__fcopyfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("_fcopyfile", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } in_fd = _PyLong_AsInt(args[0]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } out_fd = _PyLong_AsInt(args[1]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[2]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -5634,11 +5342,6 @@ os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5671,11 +5374,6 @@ os_isatty(PyObject *module, PyObject *arg) int fd; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5741,11 +5439,6 @@ os_pipe2(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flags; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(arg); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -5786,11 +5479,6 @@ os_writev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("writev", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5838,11 +5526,6 @@ os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("pwrite", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5893,6 +5576,7 @@ PyDoc_STRVAR(os_pwritev__doc__, "\n" "- RWF_DSYNC\n" "- RWF_SYNC\n" +"- RWF_APPEND\n" "\n" "Using non-zero flags requires Linux 4.7 or newer."); @@ -5916,11 +5600,6 @@ os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("pwritev", nargs, 3, 4)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -5932,11 +5611,6 @@ os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -6002,32 +5676,17 @@ os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } src = _PyLong_AsInt(args[0]); if (src == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } dst = _PyLong_AsInt(args[1]); if (dst == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -6056,6 +5715,106 @@ exit: #endif /* defined(HAVE_COPY_FILE_RANGE) */ +#if ((defined(HAVE_SPLICE) && !defined(_AIX))) + +PyDoc_STRVAR(os_splice__doc__, +"splice($module, /, src, dst, count, offset_src=None, offset_dst=None,\n" +" flags=0)\n" +"--\n" +"\n" +"Transfer count bytes from one pipe to a descriptor or vice versa.\n" +"\n" +" src\n" +" Source file descriptor.\n" +" dst\n" +" Destination file descriptor.\n" +" count\n" +" Number of bytes to copy.\n" +" offset_src\n" +" Starting offset in src.\n" +" offset_dst\n" +" Starting offset in dst.\n" +" flags\n" +" Flags to modify the semantics of the call.\n" +"\n" +"If offset_src is None, then src is read from the current position;\n" +"respectively for offset_dst. The offset associated to the file\n" +"descriptor that refers to a pipe must be None."); + +#define OS_SPLICE_METHODDEF \ + {"splice", (PyCFunction)(void(*)(void))os_splice, METH_FASTCALL|METH_KEYWORDS, os_splice__doc__}, + +static PyObject * +os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count, + PyObject *offset_src, PyObject *offset_dst, + unsigned int flags); + +static PyObject * +os_splice(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", "flags", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "splice", 0}; + PyObject *argsbuf[6]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + int src; + int dst; + Py_ssize_t count; + PyObject *offset_src = Py_None; + PyObject *offset_dst = Py_None; + unsigned int flags = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 6, 0, argsbuf); + if (!args) { + goto exit; + } + src = _PyLong_AsInt(args[0]); + if (src == -1 && PyErr_Occurred()) { + goto exit; + } + dst = _PyLong_AsInt(args[1]); + if (dst == -1 && PyErr_Occurred()) { + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[3]) { + offset_src = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[4]) { + offset_dst = args[4]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!_PyLong_UnsignedInt_Converter(args[5], &flags)) { + goto exit; + } +skip_optional_pos: + return_value = os_splice_impl(module, src, dst, count, offset_src, offset_dst, flags); + +exit: + return return_value; +} + +#endif /* ((defined(HAVE_SPLICE) && !defined(_AIX))) */ + #if defined(HAVE_MKFIFO) PyDoc_STRVAR(os_mkfifo__doc__, @@ -6098,11 +5857,6 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k goto skip_optional_pos; } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -6181,11 +5935,6 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto skip_optional_pos; } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -6318,20 +6067,10 @@ os_makedev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("makedev", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } major = _PyLong_AsInt(args[0]); if (major == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } minor = _PyLong_AsInt(args[1]); if (minor == -1 && PyErr_Occurred()) { goto exit; @@ -6372,11 +6111,6 @@ os_ftruncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ftruncate", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -6469,11 +6203,6 @@ os_posix_fallocate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("posix_fallocate", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -6527,11 +6256,6 @@ os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("posix_fadvise", nargs, 4, 4)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -6542,11 +6266,6 @@ os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!Py_off_t_converter(args[2], &length)) { goto exit; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } advice = _PyLong_AsInt(args[3]); if (advice == -1 && PyErr_Occurred()) { goto exit; @@ -6738,11 +6457,6 @@ os_strerror(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int code; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } code = _PyLong_AsInt(arg); if (code == -1 && PyErr_Occurred()) { goto exit; @@ -6774,11 +6488,6 @@ os_WCOREDUMP(PyObject *module, PyObject *arg) int status; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(arg); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -6826,11 +6535,6 @@ os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -6875,11 +6579,6 @@ os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -6924,11 +6623,6 @@ os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -6973,11 +6667,6 @@ os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -7022,11 +6711,6 @@ os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -7071,11 +6755,6 @@ os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -7120,11 +6799,6 @@ os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } status = _PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; @@ -7163,11 +6837,6 @@ os_fstatvfs(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -7293,13 +6962,7 @@ os_fpathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("fpathconf", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (!conv_path_confname(args[1], &name)) { @@ -7462,7 +7125,8 @@ os_abort(PyObject *module, PyObject *Py_UNUSED(ignored)) #if defined(MS_WINDOWS) PyDoc_STRVAR(os_startfile__doc__, -"startfile($module, /, filepath, operation=)\n" +"startfile($module, /, filepath, operation=,\n" +" arguments=, cwd=None, show_cmd=1)\n" "--\n" "\n" "Start a file with its associated application.\n" @@ -7474,6 +7138,16 @@ PyDoc_STRVAR(os_startfile__doc__, "When another \"operation\" is given, it specifies what should be done with\n" "the file. A typical operation is \"print\".\n" "\n" +"\"arguments\" is passed to the application, but should be omitted if the\n" +"file is a document.\n" +"\n" +"\"cwd\" is the working directory for the operation. If \"filepath\" is\n" +"relative, it will be resolved against this directory. This argument\n" +"should usually be an absolute path.\n" +"\n" +"\"show_cmd\" can be used to override the recommended visibility option.\n" +"See the Windows ShellExecute documentation for values.\n" +"\n" "startfile returns as soon as the associated application is launched.\n" "There is no option to wait for the application to close, and no way\n" "to retrieve the application\'s exit status.\n" @@ -7487,26 +7161,95 @@ PyDoc_STRVAR(os_startfile__doc__, static PyObject * os_startfile_impl(PyObject *module, path_t *filepath, - const Py_UNICODE *operation); + const Py_UNICODE *operation, const Py_UNICODE *arguments, + path_t *cwd, int show_cmd); static PyObject * os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"filepath", "operation", NULL}; - static _PyArg_Parser _parser = {"O&|u:startfile", _keywords, 0}; + static const char * const _keywords[] = {"filepath", "operation", "arguments", "cwd", "show_cmd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "startfile", 0}; + 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); const Py_UNICODE *operation = NULL; + const Py_UNICODE *arguments = NULL; + path_t cwd = PATH_T_INITIALIZE("startfile", "cwd", 1, 0); + int show_cmd = 1; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - path_converter, &filepath, &operation)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf); + if (!args) { goto exit; } - return_value = os_startfile_impl(module, &filepath, operation); + if (!path_converter(args[0], &filepath)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (!PyUnicode_Check(args[1])) { + _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; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[2]) { + if (!PyUnicode_Check(args[2])) { + _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; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[3]) { + if (!path_converter(args[3], &cwd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + show_cmd = _PyLong_AsInt(args[4]); + if (show_cmd == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = os_startfile_impl(module, &filepath, operation, arguments, &cwd, show_cmd); 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); return return_value; } @@ -7567,11 +7310,6 @@ os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -7829,11 +7567,6 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } if (args[3]) { - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -8015,14 +7748,9 @@ os_urandom(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_ssize_t size; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(arg); + PyObject *iobj = _PyNumber_Index(arg); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -8072,11 +7800,6 @@ os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); if (flags == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -8093,6 +7816,134 @@ exit: #endif /* defined(HAVE_MEMFD_CREATE) */ +#if defined(HAVE_EVENTFD) + +PyDoc_STRVAR(os_eventfd__doc__, +"eventfd($module, /, initval, flags=EFD_CLOEXEC)\n" +"--\n" +"\n" +"Creates and returns an event notification file descriptor."); + +#define OS_EVENTFD_METHODDEF \ + {"eventfd", (PyCFunction)(void(*)(void))os_eventfd, METH_FASTCALL|METH_KEYWORDS, os_eventfd__doc__}, + +static PyObject * +os_eventfd_impl(PyObject *module, unsigned int initval, int flags); + +static PyObject * +os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"initval", "flags", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "eventfd", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + unsigned int initval; + int flags = EFD_CLOEXEC; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_UnsignedInt_Converter(args[0], &initval)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + flags = _PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = os_eventfd_impl(module, initval, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EVENTFD) */ + +#if defined(HAVE_EVENTFD) + +PyDoc_STRVAR(os_eventfd_read__doc__, +"eventfd_read($module, /, fd)\n" +"--\n" +"\n" +"Read eventfd value"); + +#define OS_EVENTFD_READ_METHODDEF \ + {"eventfd_read", (PyCFunction)(void(*)(void))os_eventfd_read, METH_FASTCALL|METH_KEYWORDS, os_eventfd_read__doc__}, + +static PyObject * +os_eventfd_read_impl(PyObject *module, int fd); + +static PyObject * +os_eventfd_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_read", 0}; + PyObject *argsbuf[1]; + int fd; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + return_value = os_eventfd_read_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EVENTFD) */ + +#if defined(HAVE_EVENTFD) + +PyDoc_STRVAR(os_eventfd_write__doc__, +"eventfd_write($module, /, fd, value)\n" +"--\n" +"\n" +"Write eventfd value."); + +#define OS_EVENTFD_WRITE_METHODDEF \ + {"eventfd_write", (PyCFunction)(void(*)(void))os_eventfd_write, METH_FASTCALL|METH_KEYWORDS, os_eventfd_write__doc__}, + +static PyObject * +os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value); + +static PyObject * +os_eventfd_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "value", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_write", 0}; + PyObject *argsbuf[2]; + int fd; + unsigned long long value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + if (!_PyLong_UnsignedLongLong_Converter(args[1], &value)) { + goto exit; + } + return_value = os_eventfd_write_impl(module, fd, value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EVENTFD) */ + #if (defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)) PyDoc_STRVAR(os_get_terminal_size__doc__, @@ -8131,11 +7982,6 @@ os_get_terminal_size(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -8190,11 +8036,6 @@ os_get_inheritable(PyObject *module, PyObject *arg) int fd; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -8231,20 +8072,10 @@ os_set_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("set_inheritable", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } inheritable = _PyLong_AsInt(args[1]); if (inheritable == -1 && PyErr_Occurred()) { goto exit; @@ -8348,11 +8179,6 @@ os_get_blocking(PyObject *module, PyObject *arg) int fd; int _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -8396,20 +8222,10 @@ os_set_blocking(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("set_blocking", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } blocking = _PyLong_AsInt(args[1]); if (blocking == -1 && PyErr_Occurred()) { goto exit; @@ -8708,14 +8524,9 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -8728,11 +8539,6 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -9258,6 +9064,10 @@ exit: #define OS_COPY_FILE_RANGE_METHODDEF #endif /* !defined(OS_COPY_FILE_RANGE_METHODDEF) */ +#ifndef OS_SPLICE_METHODDEF + #define OS_SPLICE_METHODDEF +#endif /* !defined(OS_SPLICE_METHODDEF) */ + #ifndef OS_MKFIFO_METHODDEF #define OS_MKFIFO_METHODDEF #endif /* !defined(OS_MKFIFO_METHODDEF) */ @@ -9406,6 +9216,18 @@ exit: #define OS_MEMFD_CREATE_METHODDEF #endif /* !defined(OS_MEMFD_CREATE_METHODDEF) */ +#ifndef OS_EVENTFD_METHODDEF + #define OS_EVENTFD_METHODDEF +#endif /* !defined(OS_EVENTFD_METHODDEF) */ + +#ifndef OS_EVENTFD_READ_METHODDEF + #define OS_EVENTFD_READ_METHODDEF +#endif /* !defined(OS_EVENTFD_READ_METHODDEF) */ + +#ifndef OS_EVENTFD_WRITE_METHODDEF + #define OS_EVENTFD_WRITE_METHODDEF +#endif /* !defined(OS_EVENTFD_WRITE_METHODDEF) */ + #ifndef OS_GET_TERMINAL_SIZE_METHODDEF #define OS_GET_TERMINAL_SIZE_METHODDEF #endif /* !defined(OS_GET_TERMINAL_SIZE_METHODDEF) */ @@ -9441,4 +9263,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=c7c8796918b09139 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=65a85d7d3f2c487e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h b/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h index ee5907ca7e4..7c56d6a8b25 100644 --- a/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h +++ b/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h @@ -11,37 +11,26 @@ PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, "`isfinal\' should be true at end of input."); #define PYEXPAT_XMLPARSER_PARSE_METHODDEF \ - {"Parse", (PyCFunction)(void(*)(void))pyexpat_xmlparser_Parse, METH_FASTCALL, pyexpat_xmlparser_Parse__doc__}, + {"Parse", (PyCFunction)(void(*)(void))pyexpat_xmlparser_Parse, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_Parse__doc__}, static PyObject * -pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, - int isfinal); +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyTypeObject *cls, + PyObject *data, int isfinal); static PyObject * -pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) +pyexpat_xmlparser_Parse(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"O|i:Parse", _keywords, 0}; PyObject *data; int isfinal = 0; - if (!_PyArg_CheckPositional("Parse", nargs, 1, 2)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &data, &isfinal)) { goto exit; } - data = args[0]; - if (nargs < 2) { - goto skip_optional; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - isfinal = _PyLong_AsInt(args[1]); - if (isfinal == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional: - return_value = pyexpat_xmlparser_Parse_impl(self, data, isfinal); + return_value = pyexpat_xmlparser_Parse_impl(self, cls, data, isfinal); exit: return return_value; @@ -54,7 +43,29 @@ PyDoc_STRVAR(pyexpat_xmlparser_ParseFile__doc__, "Parse XML data from file-like object."); #define PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF \ - {"ParseFile", (PyCFunction)pyexpat_xmlparser_ParseFile, METH_O, pyexpat_xmlparser_ParseFile__doc__}, + {"ParseFile", (PyCFunction)(void(*)(void))pyexpat_xmlparser_ParseFile, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_ParseFile__doc__}, + +static PyObject * +pyexpat_xmlparser_ParseFile_impl(xmlparseobject *self, PyTypeObject *cls, + PyObject *file); + +static PyObject * +pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:ParseFile", _keywords, 0}; + PyObject *file; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &file)) { + goto exit; + } + return_value = pyexpat_xmlparser_ParseFile_impl(self, cls, file); + +exit: + return return_value; +} PyDoc_STRVAR(pyexpat_xmlparser_SetBase__doc__, "SetBase($self, base, /)\n" @@ -140,59 +151,28 @@ PyDoc_STRVAR(pyexpat_xmlparser_ExternalEntityParserCreate__doc__, "Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler."); #define PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF \ - {"ExternalEntityParserCreate", (PyCFunction)(void(*)(void))pyexpat_xmlparser_ExternalEntityParserCreate, METH_FASTCALL, pyexpat_xmlparser_ExternalEntityParserCreate__doc__}, + {"ExternalEntityParserCreate", (PyCFunction)(void(*)(void))pyexpat_xmlparser_ExternalEntityParserCreate, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_ExternalEntityParserCreate__doc__}, static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, + PyTypeObject *cls, const char *context, const char *encoding); static PyObject * -pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) +pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"z|s:ExternalEntityParserCreate", _keywords, 0}; const char *context; const char *encoding = NULL; - if (!_PyArg_CheckPositional("ExternalEntityParserCreate", nargs, 1, 2)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &context, &encoding)) { goto exit; } - if (args[0] == Py_None) { - context = NULL; - } - else if (PyUnicode_Check(args[0])) { - Py_ssize_t context_length; - context = PyUnicode_AsUTF8AndSize(args[0], &context_length); - if (context == NULL) { - goto exit; - } - if (strlen(context) != (size_t)context_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - } - else { - _PyArg_BadArgument("ExternalEntityParserCreate", "argument 1", "str or None", args[0]); - goto exit; - } - if (nargs < 2) { - goto skip_optional; - } - if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("ExternalEntityParserCreate", "argument 2", "str", args[1]); - goto exit; - } - Py_ssize_t encoding_length; - encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); - if (encoding == NULL) { - goto exit; - } - if (strlen(encoding) != (size_t)encoding_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } -skip_optional: - return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, context, encoding); + return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, cls, context, encoding); exit: return return_value; @@ -221,11 +201,6 @@ pyexpat_xmlparser_SetParamEntityParsing(xmlparseobject *self, PyObject *arg) PyObject *return_value = NULL; int flag; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(arg); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -249,29 +224,25 @@ PyDoc_STRVAR(pyexpat_xmlparser_UseForeignDTD__doc__, "information to the parser. \'flag\' defaults to True if not provided."); #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF \ - {"UseForeignDTD", (PyCFunction)(void(*)(void))pyexpat_xmlparser_UseForeignDTD, METH_FASTCALL, pyexpat_xmlparser_UseForeignDTD__doc__}, + {"UseForeignDTD", (PyCFunction)(void(*)(void))pyexpat_xmlparser_UseForeignDTD, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_UseForeignDTD__doc__}, static PyObject * -pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag); +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, PyTypeObject *cls, + int flag); static PyObject * -pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) +pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"|p:UseForeignDTD", _keywords, 0}; int flag = 1; - if (!_PyArg_CheckPositional("UseForeignDTD", nargs, 0, 1)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &flag)) { goto exit; } - if (nargs < 1) { - goto skip_optional; - } - flag = PyObject_IsTrue(args[0]); - if (flag < 0) { - goto exit; - } -skip_optional: - return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, flag); + return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, cls, flag); exit: return return_value; @@ -384,11 +355,6 @@ pyexpat_ErrorString(PyObject *module, PyObject *arg) PyObject *return_value = NULL; long code; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } code = PyLong_AsLong(arg); if (code == -1 && PyErr_Occurred()) { goto exit; @@ -402,4 +368,4 @@ exit: #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=68ce25024280af41 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=612b9d6a17a679a7 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/readline.c.h b/contrib/tools/python3/src/Modules/clinic/readline.c.h new file mode 100644 index 00000000000..d1ee8089f73 --- /dev/null +++ b/contrib/tools/python3/src/Modules/clinic/readline.c.h @@ -0,0 +1,688 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(readline_parse_and_bind__doc__, +"parse_and_bind($module, string, /)\n" +"--\n" +"\n" +"Execute the init line provided in the string argument."); + +#define READLINE_PARSE_AND_BIND_METHODDEF \ + {"parse_and_bind", (PyCFunction)readline_parse_and_bind, METH_O, readline_parse_and_bind__doc__}, + +PyDoc_STRVAR(readline_read_init_file__doc__, +"read_init_file($module, filename=None, /)\n" +"--\n" +"\n" +"Execute a readline initialization file.\n" +"\n" +"The default filename is the last filename used."); + +#define READLINE_READ_INIT_FILE_METHODDEF \ + {"read_init_file", (PyCFunction)(void(*)(void))readline_read_init_file, METH_FASTCALL, readline_read_init_file__doc__}, + +static PyObject * +readline_read_init_file_impl(PyObject *module, PyObject *filename_obj); + +static PyObject * +readline_read_init_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("read_init_file", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + filename_obj = args[0]; +skip_optional: + return_value = readline_read_init_file_impl(module, filename_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_read_history_file__doc__, +"read_history_file($module, filename=None, /)\n" +"--\n" +"\n" +"Load a readline history file.\n" +"\n" +"The default filename is ~/.history."); + +#define READLINE_READ_HISTORY_FILE_METHODDEF \ + {"read_history_file", (PyCFunction)(void(*)(void))readline_read_history_file, METH_FASTCALL, readline_read_history_file__doc__}, + +static PyObject * +readline_read_history_file_impl(PyObject *module, PyObject *filename_obj); + +static PyObject * +readline_read_history_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("read_history_file", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + filename_obj = args[0]; +skip_optional: + return_value = readline_read_history_file_impl(module, filename_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_write_history_file__doc__, +"write_history_file($module, filename=None, /)\n" +"--\n" +"\n" +"Save a readline history file.\n" +"\n" +"The default filename is ~/.history."); + +#define READLINE_WRITE_HISTORY_FILE_METHODDEF \ + {"write_history_file", (PyCFunction)(void(*)(void))readline_write_history_file, METH_FASTCALL, readline_write_history_file__doc__}, + +static PyObject * +readline_write_history_file_impl(PyObject *module, PyObject *filename_obj); + +static PyObject * +readline_write_history_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("write_history_file", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + filename_obj = args[0]; +skip_optional: + return_value = readline_write_history_file_impl(module, filename_obj); + +exit: + return return_value; +} + +#if defined(HAVE_RL_APPEND_HISTORY) + +PyDoc_STRVAR(readline_append_history_file__doc__, +"append_history_file($module, nelements, filename=None, /)\n" +"--\n" +"\n" +"Append the last nelements items of the history list to file.\n" +"\n" +"The default filename is ~/.history."); + +#define READLINE_APPEND_HISTORY_FILE_METHODDEF \ + {"append_history_file", (PyCFunction)(void(*)(void))readline_append_history_file, METH_FASTCALL, readline_append_history_file__doc__}, + +static PyObject * +readline_append_history_file_impl(PyObject *module, int nelements, + PyObject *filename_obj); + +static PyObject * +readline_append_history_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nelements; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("append_history_file", nargs, 1, 2)) { + goto exit; + } + nelements = _PyLong_AsInt(args[0]); + if (nelements == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + filename_obj = args[1]; +skip_optional: + return_value = readline_append_history_file_impl(module, nelements, filename_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_RL_APPEND_HISTORY) */ + +PyDoc_STRVAR(readline_set_history_length__doc__, +"set_history_length($module, length, /)\n" +"--\n" +"\n" +"Set the maximal number of lines which will be written to the history file.\n" +"\n" +"A negative length is used to inhibit history truncation."); + +#define READLINE_SET_HISTORY_LENGTH_METHODDEF \ + {"set_history_length", (PyCFunction)readline_set_history_length, METH_O, readline_set_history_length__doc__}, + +static PyObject * +readline_set_history_length_impl(PyObject *module, int length); + +static PyObject * +readline_set_history_length(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int length; + + length = _PyLong_AsInt(arg); + if (length == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = readline_set_history_length_impl(module, length); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_history_length__doc__, +"get_history_length($module, /)\n" +"--\n" +"\n" +"Return the maximum number of lines that will be written to the history file."); + +#define READLINE_GET_HISTORY_LENGTH_METHODDEF \ + {"get_history_length", (PyCFunction)readline_get_history_length, METH_NOARGS, readline_get_history_length__doc__}, + +static PyObject * +readline_get_history_length_impl(PyObject *module); + +static PyObject * +readline_get_history_length(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_history_length_impl(module); +} + +PyDoc_STRVAR(readline_set_completion_display_matches_hook__doc__, +"set_completion_display_matches_hook($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the completion display function.\n" +"\n" +"The function is called as\n" +" function(substitution, [matches], longest_match_length)\n" +"once each time matches need to be displayed."); + +#define READLINE_SET_COMPLETION_DISPLAY_MATCHES_HOOK_METHODDEF \ + {"set_completion_display_matches_hook", (PyCFunction)(void(*)(void))readline_set_completion_display_matches_hook, METH_FASTCALL, readline_set_completion_display_matches_hook__doc__}, + +static PyObject * +readline_set_completion_display_matches_hook_impl(PyObject *module, + PyObject *function); + +static PyObject * +readline_set_completion_display_matches_hook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_completion_display_matches_hook", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_completion_display_matches_hook_impl(module, function); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_set_startup_hook__doc__, +"set_startup_hook($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the function invoked by the rl_startup_hook callback.\n" +"\n" +"The function is called with no arguments just\n" +"before readline prints the first prompt."); + +#define READLINE_SET_STARTUP_HOOK_METHODDEF \ + {"set_startup_hook", (PyCFunction)(void(*)(void))readline_set_startup_hook, METH_FASTCALL, readline_set_startup_hook__doc__}, + +static PyObject * +readline_set_startup_hook_impl(PyObject *module, PyObject *function); + +static PyObject * +readline_set_startup_hook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_startup_hook", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_startup_hook_impl(module, function); + +exit: + return return_value; +} + +#if defined(HAVE_RL_PRE_INPUT_HOOK) + +PyDoc_STRVAR(readline_set_pre_input_hook__doc__, +"set_pre_input_hook($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the function invoked by the rl_pre_input_hook callback.\n" +"\n" +"The function is called with no arguments after the first prompt\n" +"has been printed and just before readline starts reading input\n" +"characters."); + +#define READLINE_SET_PRE_INPUT_HOOK_METHODDEF \ + {"set_pre_input_hook", (PyCFunction)(void(*)(void))readline_set_pre_input_hook, METH_FASTCALL, readline_set_pre_input_hook__doc__}, + +static PyObject * +readline_set_pre_input_hook_impl(PyObject *module, PyObject *function); + +static PyObject * +readline_set_pre_input_hook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_pre_input_hook", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_pre_input_hook_impl(module, function); + +exit: + return return_value; +} + +#endif /* defined(HAVE_RL_PRE_INPUT_HOOK) */ + +PyDoc_STRVAR(readline_get_completion_type__doc__, +"get_completion_type($module, /)\n" +"--\n" +"\n" +"Get the type of completion being attempted."); + +#define READLINE_GET_COMPLETION_TYPE_METHODDEF \ + {"get_completion_type", (PyCFunction)readline_get_completion_type, METH_NOARGS, readline_get_completion_type__doc__}, + +static PyObject * +readline_get_completion_type_impl(PyObject *module); + +static PyObject * +readline_get_completion_type(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_completion_type_impl(module); +} + +PyDoc_STRVAR(readline_get_begidx__doc__, +"get_begidx($module, /)\n" +"--\n" +"\n" +"Get the beginning index of the completion scope."); + +#define READLINE_GET_BEGIDX_METHODDEF \ + {"get_begidx", (PyCFunction)readline_get_begidx, METH_NOARGS, readline_get_begidx__doc__}, + +static PyObject * +readline_get_begidx_impl(PyObject *module); + +static PyObject * +readline_get_begidx(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_begidx_impl(module); +} + +PyDoc_STRVAR(readline_get_endidx__doc__, +"get_endidx($module, /)\n" +"--\n" +"\n" +"Get the ending index of the completion scope."); + +#define READLINE_GET_ENDIDX_METHODDEF \ + {"get_endidx", (PyCFunction)readline_get_endidx, METH_NOARGS, readline_get_endidx__doc__}, + +static PyObject * +readline_get_endidx_impl(PyObject *module); + +static PyObject * +readline_get_endidx(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_endidx_impl(module); +} + +PyDoc_STRVAR(readline_set_completer_delims__doc__, +"set_completer_delims($module, string, /)\n" +"--\n" +"\n" +"Set the word delimiters for completion."); + +#define READLINE_SET_COMPLETER_DELIMS_METHODDEF \ + {"set_completer_delims", (PyCFunction)readline_set_completer_delims, METH_O, readline_set_completer_delims__doc__}, + +PyDoc_STRVAR(readline_remove_history_item__doc__, +"remove_history_item($module, pos, /)\n" +"--\n" +"\n" +"Remove history item given by its zero-based position."); + +#define READLINE_REMOVE_HISTORY_ITEM_METHODDEF \ + {"remove_history_item", (PyCFunction)readline_remove_history_item, METH_O, readline_remove_history_item__doc__}, + +static PyObject * +readline_remove_history_item_impl(PyObject *module, int entry_number); + +static PyObject * +readline_remove_history_item(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int entry_number; + + entry_number = _PyLong_AsInt(arg); + if (entry_number == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = readline_remove_history_item_impl(module, entry_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_replace_history_item__doc__, +"replace_history_item($module, pos, line, /)\n" +"--\n" +"\n" +"Replaces history item given by its position with contents of line.\n" +"\n" +"pos is zero-based."); + +#define READLINE_REPLACE_HISTORY_ITEM_METHODDEF \ + {"replace_history_item", (PyCFunction)(void(*)(void))readline_replace_history_item, METH_FASTCALL, readline_replace_history_item__doc__}, + +static PyObject * +readline_replace_history_item_impl(PyObject *module, int entry_number, + PyObject *line); + +static PyObject * +readline_replace_history_item(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int entry_number; + PyObject *line; + + if (!_PyArg_CheckPositional("replace_history_item", nargs, 2, 2)) { + goto exit; + } + entry_number = _PyLong_AsInt(args[0]); + if (entry_number == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("replace_history_item", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + line = args[1]; + return_value = readline_replace_history_item_impl(module, entry_number, line); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_add_history__doc__, +"add_history($module, string, /)\n" +"--\n" +"\n" +"Add an item to the history buffer."); + +#define READLINE_ADD_HISTORY_METHODDEF \ + {"add_history", (PyCFunction)readline_add_history, METH_O, readline_add_history__doc__}, + +PyDoc_STRVAR(readline_set_auto_history__doc__, +"set_auto_history($module, enabled, /)\n" +"--\n" +"\n" +"Enables or disables automatic history."); + +#define READLINE_SET_AUTO_HISTORY_METHODDEF \ + {"set_auto_history", (PyCFunction)readline_set_auto_history, METH_O, readline_set_auto_history__doc__}, + +static PyObject * +readline_set_auto_history_impl(PyObject *module, + int _should_auto_add_history); + +static PyObject * +readline_set_auto_history(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int _should_auto_add_history; + + _should_auto_add_history = PyObject_IsTrue(arg); + if (_should_auto_add_history < 0) { + goto exit; + } + return_value = readline_set_auto_history_impl(module, _should_auto_add_history); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_completer_delims__doc__, +"get_completer_delims($module, /)\n" +"--\n" +"\n" +"Get the word delimiters for completion."); + +#define READLINE_GET_COMPLETER_DELIMS_METHODDEF \ + {"get_completer_delims", (PyCFunction)readline_get_completer_delims, METH_NOARGS, readline_get_completer_delims__doc__}, + +static PyObject * +readline_get_completer_delims_impl(PyObject *module); + +static PyObject * +readline_get_completer_delims(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_completer_delims_impl(module); +} + +PyDoc_STRVAR(readline_set_completer__doc__, +"set_completer($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the completer function.\n" +"\n" +"The function is called as function(text, state),\n" +"for state in 0, 1, 2, ..., until it returns a non-string.\n" +"It should return the next possible completion starting with \'text\'."); + +#define READLINE_SET_COMPLETER_METHODDEF \ + {"set_completer", (PyCFunction)(void(*)(void))readline_set_completer, METH_FASTCALL, readline_set_completer__doc__}, + +static PyObject * +readline_set_completer_impl(PyObject *module, PyObject *function); + +static PyObject * +readline_set_completer(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_completer", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_completer_impl(module, function); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_completer__doc__, +"get_completer($module, /)\n" +"--\n" +"\n" +"Get the current completer function."); + +#define READLINE_GET_COMPLETER_METHODDEF \ + {"get_completer", (PyCFunction)readline_get_completer, METH_NOARGS, readline_get_completer__doc__}, + +static PyObject * +readline_get_completer_impl(PyObject *module); + +static PyObject * +readline_get_completer(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_completer_impl(module); +} + +PyDoc_STRVAR(readline_get_history_item__doc__, +"get_history_item($module, index, /)\n" +"--\n" +"\n" +"Return the current contents of history item at one-based index."); + +#define READLINE_GET_HISTORY_ITEM_METHODDEF \ + {"get_history_item", (PyCFunction)readline_get_history_item, METH_O, readline_get_history_item__doc__}, + +static PyObject * +readline_get_history_item_impl(PyObject *module, int idx); + +static PyObject * +readline_get_history_item(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int idx; + + idx = _PyLong_AsInt(arg); + if (idx == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = readline_get_history_item_impl(module, idx); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_current_history_length__doc__, +"get_current_history_length($module, /)\n" +"--\n" +"\n" +"Return the current (not the maximum) length of history."); + +#define READLINE_GET_CURRENT_HISTORY_LENGTH_METHODDEF \ + {"get_current_history_length", (PyCFunction)readline_get_current_history_length, METH_NOARGS, readline_get_current_history_length__doc__}, + +static PyObject * +readline_get_current_history_length_impl(PyObject *module); + +static PyObject * +readline_get_current_history_length(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_current_history_length_impl(module); +} + +PyDoc_STRVAR(readline_get_line_buffer__doc__, +"get_line_buffer($module, /)\n" +"--\n" +"\n" +"Return the current contents of the line buffer."); + +#define READLINE_GET_LINE_BUFFER_METHODDEF \ + {"get_line_buffer", (PyCFunction)readline_get_line_buffer, METH_NOARGS, readline_get_line_buffer__doc__}, + +static PyObject * +readline_get_line_buffer_impl(PyObject *module); + +static PyObject * +readline_get_line_buffer(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_line_buffer_impl(module); +} + +#if defined(HAVE_RL_COMPLETION_APPEND_CHARACTER) + +PyDoc_STRVAR(readline_clear_history__doc__, +"clear_history($module, /)\n" +"--\n" +"\n" +"Clear the current readline history."); + +#define READLINE_CLEAR_HISTORY_METHODDEF \ + {"clear_history", (PyCFunction)readline_clear_history, METH_NOARGS, readline_clear_history__doc__}, + +static PyObject * +readline_clear_history_impl(PyObject *module); + +static PyObject * +readline_clear_history(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_clear_history_impl(module); +} + +#endif /* defined(HAVE_RL_COMPLETION_APPEND_CHARACTER) */ + +PyDoc_STRVAR(readline_insert_text__doc__, +"insert_text($module, string, /)\n" +"--\n" +"\n" +"Insert text into the line buffer at the cursor position."); + +#define READLINE_INSERT_TEXT_METHODDEF \ + {"insert_text", (PyCFunction)readline_insert_text, METH_O, readline_insert_text__doc__}, + +PyDoc_STRVAR(readline_redisplay__doc__, +"redisplay($module, /)\n" +"--\n" +"\n" +"Change what\'s displayed on the screen to reflect contents of the line buffer."); + +#define READLINE_REDISPLAY_METHODDEF \ + {"redisplay", (PyCFunction)readline_redisplay, METH_NOARGS, readline_redisplay__doc__}, + +static PyObject * +readline_redisplay_impl(PyObject *module); + +static PyObject * +readline_redisplay(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_redisplay_impl(module); +} + +#ifndef READLINE_APPEND_HISTORY_FILE_METHODDEF + #define READLINE_APPEND_HISTORY_FILE_METHODDEF +#endif /* !defined(READLINE_APPEND_HISTORY_FILE_METHODDEF) */ + +#ifndef READLINE_SET_PRE_INPUT_HOOK_METHODDEF + #define READLINE_SET_PRE_INPUT_HOOK_METHODDEF +#endif /* !defined(READLINE_SET_PRE_INPUT_HOOK_METHODDEF) */ + +#ifndef READLINE_CLEAR_HISTORY_METHODDEF + #define READLINE_CLEAR_HISTORY_METHODDEF +#endif /* !defined(READLINE_CLEAR_HISTORY_METHODDEF) */ +/*[clinic end generated code: output=f7d390113b27989f input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/resource.c.h b/contrib/tools/python3/src/Modules/clinic/resource.c.h index 80efb714bb6..32c092ad7a9 100644 --- a/contrib/tools/python3/src/Modules/clinic/resource.c.h +++ b/contrib/tools/python3/src/Modules/clinic/resource.c.h @@ -19,11 +19,6 @@ resource_getrusage(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int who; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } who = _PyLong_AsInt(arg); if (who == -1 && PyErr_Occurred()) { goto exit; @@ -51,11 +46,6 @@ resource_getrlimit(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int resource; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } resource = _PyLong_AsInt(arg); if (resource == -1 && PyErr_Occurred()) { goto exit; @@ -87,11 +77,6 @@ resource_setrlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setrlimit", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } resource = _PyLong_AsInt(args[0]); if (resource == -1 && PyErr_Occurred()) { goto exit; @@ -178,4 +163,4 @@ exit: #ifndef RESOURCE_PRLIMIT_METHODDEF #define RESOURCE_PRLIMIT_METHODDEF #endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */ -/*[clinic end generated code: output=ef3034f291156a34 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ad190fb33d647d1e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/selectmodule.c.h b/contrib/tools/python3/src/Modules/clinic/selectmodule.c.h index 7791af8f931..be752e98166 100644 --- a/contrib/tools/python3/src/Modules/clinic/selectmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/selectmodule.c.h @@ -92,7 +92,7 @@ select_poll_register(pollObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("register", nargs, 1, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (nargs < 2) { @@ -140,7 +140,7 @@ select_poll_modify(pollObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("modify", nargs, 2, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) { @@ -174,7 +174,7 @@ select_poll_unregister(pollObject *self, PyObject *arg) PyObject *return_value = NULL; int fd; - if (!fildes_converter(arg, &fd)) { + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { goto exit; } return_value = select_poll_unregister_impl(self, fd); @@ -260,7 +260,7 @@ select_devpoll_register(devpollObject *self, PyObject *const *args, Py_ssize_t n if (!_PyArg_CheckPositional("register", nargs, 1, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (nargs < 2) { @@ -310,7 +310,7 @@ select_devpoll_modify(devpollObject *self, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("modify", nargs, 1, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (nargs < 2) { @@ -348,7 +348,7 @@ select_devpoll_unregister(devpollObject *self, PyObject *arg) PyObject *return_value = NULL; int fd; - if (!fildes_converter(arg, &fd)) { + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { goto exit; } return_value = select_devpoll_unregister_impl(self, fd); @@ -539,11 +539,6 @@ select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } if (fastargs[0]) { - if (PyFloat_Check(fastargs[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } sizehint = _PyLong_AsInt(fastargs[0]); if (sizehint == -1 && PyErr_Occurred()) { goto exit; @@ -552,11 +547,6 @@ select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } } - if (PyFloat_Check(fastargs[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(fastargs[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -636,11 +626,6 @@ select_epoll_fromfd(PyTypeObject *type, PyObject *arg) PyObject *return_value = NULL; int fd; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -691,17 +676,12 @@ select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t na if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); if (eventmask == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -749,12 +729,7 @@ select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t narg if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); @@ -799,7 +774,7 @@ select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = select_epoll_unregister_impl(self, fd); @@ -858,11 +833,6 @@ select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } maxevents = _PyLong_AsInt(args[1]); if (maxevents == -1 && PyErr_Occurred()) { goto exit; @@ -971,11 +941,11 @@ select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - if ((type == _selectstate_global->kqueue_queue_Type) && + if ((type == _selectstate_by_type(type)->kqueue_queue_Type) && !_PyArg_NoPositional("kqueue", args)) { goto exit; } - if ((type == _selectstate_global->kqueue_queue_Type) && + if ((type == _selectstate_by_type(type)->kqueue_queue_Type) && !_PyArg_NoKeywords("kqueue", kwargs)) { goto exit; } @@ -1053,11 +1023,6 @@ select_kqueue_fromfd(PyTypeObject *type, PyObject *arg) PyObject *return_value = NULL; int fd; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -1106,11 +1071,6 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize goto exit; } changelist = args[0]; - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } maxevents = _PyLong_AsInt(args[1]); if (maxevents == -1 && PyErr_Occurred()) { goto exit; @@ -1227,4 +1187,4 @@ exit: #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=d78e30f231a926d6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a8fc031269d28454 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/sha1module.c.h b/contrib/tools/python3/src/Modules/clinic/sha1module.c.h index fc37b1ab880..3a3ab58c123 100644 --- a/contrib/tools/python3/src/Modules/clinic/sha1module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/sha1module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(SHA1Type_copy__doc__, "Return a copy of the hash object."); #define SHA1TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA1Type_copy, METH_NOARGS, SHA1Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))SHA1Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA1Type_copy__doc__}, static PyObject * -SHA1Type_copy_impl(SHA1object *self); +SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls); static PyObject * -SHA1Type_copy(SHA1object *self, PyObject *Py_UNUSED(ignored)) +SHA1Type_copy(SHA1object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return SHA1Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = SHA1Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(SHA1Type_digest__doc__, @@ -115,4 +126,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=3ddd637ae17e14b3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=abf1ab2545cea5a2 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/sha256module.c.h b/contrib/tools/python3/src/Modules/clinic/sha256module.c.h index 2a788ea9849..89205c4f14f 100644 --- a/contrib/tools/python3/src/Modules/clinic/sha256module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/sha256module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(SHA256Type_copy__doc__, "Return a copy of the hash object."); #define SHA256TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA256Type_copy, METH_NOARGS, SHA256Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))SHA256Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA256Type_copy__doc__}, static PyObject * -SHA256Type_copy_impl(SHAobject *self); +SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * -SHA256Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +SHA256Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return SHA256Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = SHA256Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(SHA256Type_digest__doc__, @@ -166,4 +177,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=c8cca8adbe72ec9a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7283f75c9d08f30 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/sha512module.c.h b/contrib/tools/python3/src/Modules/clinic/sha512module.c.h index b8185b62bb6..f1192d74f9a 100644 --- a/contrib/tools/python3/src/Modules/clinic/sha512module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/sha512module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(SHA512Type_copy__doc__, "Return a copy of the hash object."); #define SHA512TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA512Type_copy, METH_NOARGS, SHA512Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))SHA512Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA512Type_copy__doc__}, static PyObject * -SHA512Type_copy_impl(SHAobject *self); +SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * -SHA512Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +SHA512Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return SHA512Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = SHA512Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(SHA512Type_digest__doc__, @@ -166,4 +177,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=bbfa72d8703c82b5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9ff9f11937fabf35 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h b/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h index 0fb25d5640b..4c27314a80c 100644 --- a/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h @@ -2,6 +2,42 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(signal_default_int_handler__doc__, +"default_int_handler($module, signalnum, frame, /)\n" +"--\n" +"\n" +"The default handler for SIGINT installed by Python.\n" +"\n" +"It raises KeyboardInterrupt."); + +#define SIGNAL_DEFAULT_INT_HANDLER_METHODDEF \ + {"default_int_handler", (PyCFunction)(void(*)(void))signal_default_int_handler, METH_FASTCALL, signal_default_int_handler__doc__}, + +static PyObject * +signal_default_int_handler_impl(PyObject *module, int signalnum, + PyObject *frame); + +static PyObject * +signal_default_int_handler(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int signalnum; + PyObject *frame; + + if (!_PyArg_CheckPositional("default_int_handler", nargs, 2, 2)) { + goto exit; + } + signalnum = _PyLong_AsInt(args[0]); + if (signalnum == -1 && PyErr_Occurred()) { + goto exit; + } + frame = args[1]; + return_value = signal_default_int_handler_impl(module, signalnum, frame); + +exit: + return return_value; +} + #if defined(HAVE_ALARM) PyDoc_STRVAR(signal_alarm__doc__, @@ -23,11 +59,6 @@ signal_alarm(PyObject *module, PyObject *arg) int seconds; long _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } seconds = _PyLong_AsInt(arg); if (seconds == -1 && PyErr_Occurred()) { goto exit; @@ -84,11 +115,6 @@ signal_raise_signal(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int signalnum; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } signalnum = _PyLong_AsInt(arg); if (signalnum == -1 && PyErr_Occurred()) { goto exit; @@ -128,11 +154,6 @@ signal_signal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("signal", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } signalnum = _PyLong_AsInt(args[0]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; @@ -168,11 +189,6 @@ signal_getsignal(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int signalnum; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } signalnum = _PyLong_AsInt(arg); if (signalnum == -1 && PyErr_Occurred()) { goto exit; @@ -204,11 +220,6 @@ signal_strsignal(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int signalnum; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } signalnum = _PyLong_AsInt(arg); if (signalnum == -1 && PyErr_Occurred()) { goto exit; @@ -246,20 +257,10 @@ signal_siginterrupt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("siginterrupt", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } signalnum = _PyLong_AsInt(args[0]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(args[1]); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -303,11 +304,6 @@ signal_setitimer(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setitimer", nargs, 2, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } which = _PyLong_AsInt(args[0]); if (which == -1 && PyErr_Occurred()) { goto exit; @@ -346,11 +342,6 @@ signal_getitimer(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int which; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } which = _PyLong_AsInt(arg); if (which == -1 && PyErr_Occurred()) { goto exit; @@ -387,11 +378,6 @@ signal_pthread_sigmask(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (!_PyArg_CheckPositional("pthread_sigmask", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } how = _PyLong_AsInt(args[0]); if (how == -1 && PyErr_Occurred()) { goto exit; @@ -594,11 +580,6 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } thread_id = PyLong_AsUnsignedLongMask(args[0]); - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } signalnum = _PyLong_AsInt(args[1]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; @@ -638,20 +619,10 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("pidfd_send_signal", nargs, 2, 4)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } pidfd = _PyLong_AsInt(args[0]); if (pidfd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } signalnum = _PyLong_AsInt(args[1]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; @@ -663,11 +634,6 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -732,4 +698,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=3c8b80f14df17563 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c353e686367bc384 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/termios.c.h b/contrib/tools/python3/src/Modules/clinic/termios.c.h new file mode 100644 index 00000000000..a45c1f64262 --- /dev/null +++ b/contrib/tools/python3/src/Modules/clinic/termios.c.h @@ -0,0 +1,225 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(termios_tcgetattr__doc__, +"tcgetattr($module, fd, /)\n" +"--\n" +"\n" +"Get the tty attributes for file descriptor fd.\n" +"\n" +"Returns a list [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]\n" +"where cc is a list of the tty special characters (each a string of\n" +"length 1, except the items with indices VMIN and VTIME, which are\n" +"integers when these fields are defined). The interpretation of the\n" +"flags and the speeds as well as the indexing in the cc array must be\n" +"done using the symbolic constants defined in this module."); + +#define TERMIOS_TCGETATTR_METHODDEF \ + {"tcgetattr", (PyCFunction)termios_tcgetattr, METH_O, termios_tcgetattr__doc__}, + +static PyObject * +termios_tcgetattr_impl(PyObject *module, int fd); + +static PyObject * +termios_tcgetattr(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = termios_tcgetattr_impl(module, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(termios_tcsetattr__doc__, +"tcsetattr($module, fd, when, attributes, /)\n" +"--\n" +"\n" +"Set the tty attributes for file descriptor fd.\n" +"\n" +"The attributes to be set are taken from the attributes argument, which\n" +"is a list like the one returned by tcgetattr(). The when argument\n" +"determines when the attributes are changed: termios.TCSANOW to\n" +"change immediately, termios.TCSADRAIN to change after transmitting all\n" +"queued output, or termios.TCSAFLUSH to change after transmitting all\n" +"queued output and discarding all queued input."); + +#define TERMIOS_TCSETATTR_METHODDEF \ + {"tcsetattr", (PyCFunction)(void(*)(void))termios_tcsetattr, METH_FASTCALL, termios_tcsetattr__doc__}, + +static PyObject * +termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term); + +static PyObject * +termios_tcsetattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int when; + PyObject *term; + + if (!_PyArg_CheckPositional("tcsetattr", nargs, 3, 3)) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + when = _PyLong_AsInt(args[1]); + if (when == -1 && PyErr_Occurred()) { + goto exit; + } + term = args[2]; + return_value = termios_tcsetattr_impl(module, fd, when, term); + +exit: + return return_value; +} + +PyDoc_STRVAR(termios_tcsendbreak__doc__, +"tcsendbreak($module, fd, duration, /)\n" +"--\n" +"\n" +"Send a break on file descriptor fd.\n" +"\n" +"A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n" +"has a system dependent meaning."); + +#define TERMIOS_TCSENDBREAK_METHODDEF \ + {"tcsendbreak", (PyCFunction)(void(*)(void))termios_tcsendbreak, METH_FASTCALL, termios_tcsendbreak__doc__}, + +static PyObject * +termios_tcsendbreak_impl(PyObject *module, int fd, int duration); + +static PyObject * +termios_tcsendbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int duration; + + if (!_PyArg_CheckPositional("tcsendbreak", nargs, 2, 2)) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + duration = _PyLong_AsInt(args[1]); + if (duration == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = termios_tcsendbreak_impl(module, fd, duration); + +exit: + return return_value; +} + +PyDoc_STRVAR(termios_tcdrain__doc__, +"tcdrain($module, fd, /)\n" +"--\n" +"\n" +"Wait until all output written to file descriptor fd has been transmitted."); + +#define TERMIOS_TCDRAIN_METHODDEF \ + {"tcdrain", (PyCFunction)termios_tcdrain, METH_O, termios_tcdrain__doc__}, + +static PyObject * +termios_tcdrain_impl(PyObject *module, int fd); + +static PyObject * +termios_tcdrain(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = termios_tcdrain_impl(module, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(termios_tcflush__doc__, +"tcflush($module, fd, queue, /)\n" +"--\n" +"\n" +"Discard queued data on file descriptor fd.\n" +"\n" +"The queue selector specifies which queue: termios.TCIFLUSH for the input\n" +"queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n" +"both queues."); + +#define TERMIOS_TCFLUSH_METHODDEF \ + {"tcflush", (PyCFunction)(void(*)(void))termios_tcflush, METH_FASTCALL, termios_tcflush__doc__}, + +static PyObject * +termios_tcflush_impl(PyObject *module, int fd, int queue); + +static PyObject * +termios_tcflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int queue; + + if (!_PyArg_CheckPositional("tcflush", nargs, 2, 2)) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + queue = _PyLong_AsInt(args[1]); + if (queue == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = termios_tcflush_impl(module, fd, queue); + +exit: + return return_value; +} + +PyDoc_STRVAR(termios_tcflow__doc__, +"tcflow($module, fd, action, /)\n" +"--\n" +"\n" +"Suspend or resume input or output on file descriptor fd.\n" +"\n" +"The action argument can be termios.TCOOFF to suspend output,\n" +"termios.TCOON to restart output, termios.TCIOFF to suspend input,\n" +"or termios.TCION to restart input."); + +#define TERMIOS_TCFLOW_METHODDEF \ + {"tcflow", (PyCFunction)(void(*)(void))termios_tcflow, METH_FASTCALL, termios_tcflow__doc__}, + +static PyObject * +termios_tcflow_impl(PyObject *module, int fd, int action); + +static PyObject * +termios_tcflow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int action; + + if (!_PyArg_CheckPositional("tcflow", nargs, 2, 2)) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + action = _PyLong_AsInt(args[1]); + if (action == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = termios_tcflow_impl(module, fd, action); + +exit: + return return_value; +} +/*[clinic end generated code: output=a129179f1e2545cc input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h b/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h index 77ea04a353b..14e955db64e 100644 --- a/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h @@ -44,11 +44,6 @@ zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } level = _PyLong_AsInt(args[1]); if (level == -1 && PyErr_Occurred()) { goto exit; @@ -112,11 +107,6 @@ zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } wbits = _PyLong_AsInt(args[1]); if (wbits == -1 && PyErr_Occurred()) { goto exit; @@ -125,8 +115,17 @@ zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } } - if (!ssize_t_converter(args[2], &bufsize)) { - goto exit; + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + bufsize = ival; } skip_optional_pos: return_value = zlib_decompress_impl(module, &data, wbits, bufsize); @@ -200,11 +199,6 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } if (args[0]) { - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } level = _PyLong_AsInt(args[0]); if (level == -1 && PyErr_Occurred()) { goto exit; @@ -214,11 +208,6 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } method = _PyLong_AsInt(args[1]); if (method == -1 && PyErr_Occurred()) { goto exit; @@ -228,11 +217,6 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } wbits = _PyLong_AsInt(args[2]); if (wbits == -1 && PyErr_Occurred()) { goto exit; @@ -242,11 +226,6 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[3]) { - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } memLevel = _PyLong_AsInt(args[3]); if (memLevel == -1 && PyErr_Occurred()) { goto exit; @@ -256,11 +235,6 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[4]) { - if (PyFloat_Check(args[4])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } strategy = _PyLong_AsInt(args[4]); if (strategy == -1 && PyErr_Occurred()) { goto exit; @@ -325,11 +299,6 @@ zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto skip_optional_pos; } if (args[0]) { - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } wbits = _PyLong_AsInt(args[0]); if (wbits == -1 && PyErr_Occurred()) { goto exit; @@ -360,25 +329,25 @@ PyDoc_STRVAR(zlib_Compress_compress__doc__, "Call the flush() method to clear these buffers."); #define ZLIB_COMPRESS_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)zlib_Compress_compress, METH_O, zlib_Compress_compress__doc__}, + {"compress", (PyCFunction)(void(*)(void))zlib_Compress_compress, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_compress__doc__}, static PyObject * -zlib_Compress_compress_impl(compobject *self, Py_buffer *data); +zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data); static PyObject * -zlib_Compress_compress(compobject *self, PyObject *arg) +zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"y*:compress", _keywords, 0}; Py_buffer data = {NULL, NULL}; - if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { - goto exit; - } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &data)) { goto exit; } - return_value = zlib_Compress_compress_impl(self, &data); + return_value = zlib_Compress_compress_impl(self, cls, &data); exit: /* Cleanup for data */ @@ -407,42 +376,26 @@ PyDoc_STRVAR(zlib_Decompress_decompress__doc__, "Call the flush() method to clear these buffers."); #define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)(void(*)(void))zlib_Decompress_decompress, METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, + {"decompress", (PyCFunction)(void(*)(void))zlib_Decompress_decompress, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, - Py_ssize_t max_length); +zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data, Py_ssize_t max_length); static PyObject * -zlib_Decompress_decompress(compobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"y*|n:decompress", _keywords, 0}; Py_buffer data = {NULL, NULL}; Py_ssize_t max_length = 0; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &data, &max_length)) { goto exit; } - if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { - goto exit; - } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (!ssize_t_converter(args[1], &max_length)) { - goto exit; - } -skip_optional_pos: - return_value = zlib_Decompress_decompress_impl(self, &data, max_length); + return_value = zlib_Decompress_decompress_impl(self, cls, &data, max_length); exit: /* Cleanup for data */ @@ -466,34 +419,24 @@ PyDoc_STRVAR(zlib_Compress_flush__doc__, " can still be compressed."); #define ZLIB_COMPRESS_FLUSH_METHODDEF \ - {"flush", (PyCFunction)(void(*)(void))zlib_Compress_flush, METH_FASTCALL, zlib_Compress_flush__doc__}, + {"flush", (PyCFunction)(void(*)(void))zlib_Compress_flush, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_flush__doc__}, static PyObject * -zlib_Compress_flush_impl(compobject *self, int mode); +zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode); static PyObject * -zlib_Compress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) +zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"|i:flush", _keywords, 0}; int mode = Z_FINISH; - if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &mode)) { goto exit; } - mode = _PyLong_AsInt(args[0]); - if (mode == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional: - return_value = zlib_Compress_flush_impl(self, mode); + return_value = zlib_Compress_flush_impl(self, cls, mode); exit: return return_value; @@ -508,15 +451,26 @@ PyDoc_STRVAR(zlib_Compress_copy__doc__, "Return a copy of the compression object."); #define ZLIB_COMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))zlib_Compress_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_copy__doc__}, static PyObject * -zlib_Compress_copy_impl(compobject *self); +zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Compress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Compress_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Compress_copy_impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -529,15 +483,26 @@ PyDoc_STRVAR(zlib_Compress___copy____doc__, "\n"); #define ZLIB_COMPRESS___COPY___METHODDEF \ - {"__copy__", (PyCFunction)zlib_Compress___copy__, METH_NOARGS, zlib_Compress___copy____doc__}, + {"__copy__", (PyCFunction)(void(*)(void))zlib_Compress___copy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___copy____doc__}, static PyObject * -zlib_Compress___copy___impl(compobject *self); +zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Compress___copy__(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Compress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Compress___copy___impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Compress___copy___impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -550,7 +515,29 @@ PyDoc_STRVAR(zlib_Compress___deepcopy____doc__, "\n"); #define ZLIB_COMPRESS___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)zlib_Compress___deepcopy__, METH_O, zlib_Compress___deepcopy____doc__}, + {"__deepcopy__", (PyCFunction)(void(*)(void))zlib_Compress___deepcopy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___deepcopy____doc__}, + +static PyObject * +zlib_Compress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo); + +static PyObject * +zlib_Compress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + PyObject *memo; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &memo)) { + goto exit; + } + return_value = zlib_Compress___deepcopy___impl(self, cls, memo); + +exit: + return return_value; +} #endif /* defined(HAVE_ZLIB_COPY) */ @@ -563,15 +550,26 @@ PyDoc_STRVAR(zlib_Decompress_copy__doc__, "Return a copy of the decompression object."); #define ZLIB_DECOMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))zlib_Decompress_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_copy__doc__}, static PyObject * -zlib_Decompress_copy_impl(compobject *self); +zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Decompress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Decompress_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Decompress_copy_impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -584,15 +582,26 @@ PyDoc_STRVAR(zlib_Decompress___copy____doc__, "\n"); #define ZLIB_DECOMPRESS___COPY___METHODDEF \ - {"__copy__", (PyCFunction)zlib_Decompress___copy__, METH_NOARGS, zlib_Decompress___copy____doc__}, + {"__copy__", (PyCFunction)(void(*)(void))zlib_Decompress___copy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___copy____doc__}, static PyObject * -zlib_Decompress___copy___impl(compobject *self); +zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Decompress___copy__(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Decompress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Decompress___copy___impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Decompress___copy___impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -605,7 +614,29 @@ PyDoc_STRVAR(zlib_Decompress___deepcopy____doc__, "\n"); #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)zlib_Decompress___deepcopy__, METH_O, zlib_Decompress___deepcopy____doc__}, + {"__deepcopy__", (PyCFunction)(void(*)(void))zlib_Decompress___deepcopy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___deepcopy____doc__}, + +static PyObject * +zlib_Decompress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo); + +static PyObject * +zlib_Decompress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + PyObject *memo; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &memo)) { + goto exit; + } + return_value = zlib_Decompress___deepcopy___impl(self, cls, memo); + +exit: + return return_value; +} #endif /* defined(HAVE_ZLIB_COPY) */ @@ -619,28 +650,25 @@ PyDoc_STRVAR(zlib_Decompress_flush__doc__, " the initial size of the output buffer."); #define ZLIB_DECOMPRESS_FLUSH_METHODDEF \ - {"flush", (PyCFunction)(void(*)(void))zlib_Decompress_flush, METH_FASTCALL, zlib_Decompress_flush__doc__}, + {"flush", (PyCFunction)(void(*)(void))zlib_Decompress_flush, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_flush__doc__}, static PyObject * -zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length); +zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, + Py_ssize_t length); static PyObject * -zlib_Decompress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) +zlib_Decompress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"|n:flush", _keywords, 0}; Py_ssize_t length = DEF_BUF_SIZE; - if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &length)) { goto exit; } - if (nargs < 1) { - goto skip_optional; - } - if (!ssize_t_converter(args[0], &length)) { - goto exit; - } -skip_optional: - return_value = zlib_Decompress_flush_impl(self, length); + return_value = zlib_Decompress_flush_impl(self, cls, length); exit: return return_value; @@ -683,11 +711,6 @@ zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); if (value == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -741,11 +764,6 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); if (value == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -785,4 +803,4 @@ exit: #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=faae38ef96b88b16 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6736bae59fab268b input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/cmathmodule.c b/contrib/tools/python3/src/Modules/cmathmodule.c index 5eac4b4940b..0f22049a170 100644 --- a/contrib/tools/python3/src/Modules/cmathmodule.c +++ b/contrib/tools/python3/src/Modules/cmathmodule.c @@ -1254,37 +1254,35 @@ static PyMethodDef cmath_methods[] = { {NULL, NULL} /* sentinel */ }; - -static struct PyModuleDef cmathmodule = { - PyModuleDef_HEAD_INIT, - "cmath", - module_doc, - -1, - cmath_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_cmath(void) +static int +cmath_exec(PyObject *mod) { - PyObject *m; - - m = PyModule_Create(&cmathmodule); - if (m == NULL) - return NULL; - - PyModule_AddObject(m, "pi", - PyFloat_FromDouble(Py_MATH_PI)); - PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); - PyModule_AddObject(m, "tau", PyFloat_FromDouble(Py_MATH_TAU)); /* 2pi */ - PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); - PyModule_AddObject(m, "infj", PyComplex_FromCComplex(c_infj())); + if (PyModule_AddObject(mod, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { + return -1; + } + if (PyModule_AddObject(mod, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { + return -1; + } + // 2pi + if (PyModule_AddObject(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { + return -1; + } + if (PyModule_AddObject(mod, "inf", PyFloat_FromDouble(m_inf())) < 0) { + return -1; + } + + if (PyModule_AddObject(mod, "infj", + PyComplex_FromCComplex(c_infj())) < 0) { + return -1; + } #if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) - PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); - PyModule_AddObject(m, "nanj", PyComplex_FromCComplex(c_nanj())); + if (PyModule_AddObject(mod, "nan", PyFloat_FromDouble(m_nan())) < 0) { + return -1; + } + if (PyModule_AddObject(mod, "nanj", + PyComplex_FromCComplex(c_nanj())) < 0) { + return -1; + } #endif /* initialize special value tables */ @@ -1401,5 +1399,25 @@ PyInit_cmath(void) C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N) }) - return m; + return 0; } + +static PyModuleDef_Slot cmath_slots[] = { + {Py_mod_exec, cmath_exec}, + {0, NULL} +}; + +static struct PyModuleDef cmathmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "cmath", + .m_doc = module_doc, + .m_size = 0, + .m_methods = cmath_methods, + .m_slots = cmath_slots +}; + +PyMODINIT_FUNC +PyInit_cmath(void) +{ + return PyModuleDef_Init(&cmathmodule); +} \ No newline at end of file diff --git a/contrib/tools/python3/src/Modules/config.c b/contrib/tools/python3/src/Modules/config.c index 2128f544e58..527f5889ee8 100644 --- a/contrib/tools/python3/src/Modules/config.c +++ b/contrib/tools/python3/src/Modules/config.c @@ -58,7 +58,6 @@ extern PyObject* PyInit__multibytecodec(void); // _multibytecodec extern PyObject* PyInit__multiprocessing(void); // _multiprocessing extern PyObject* PyInit__opcode(void); // _opcode extern PyObject* PyInit__operator(void); // _operator -extern PyObject* PyInit__peg_parser(void); // _peg_parser extern PyObject* PyInit__pickle(void); // _pickle extern PyObject* PyInit__posixshmem(void); // _posixshmem #if !defined(_MSC_VER) @@ -95,16 +94,15 @@ extern PyObject* PyInit_faulthandler(void); // faulthandler #if !defined(_MSC_VER) extern PyObject* PyInit_fcntl(void); // fcntl #endif +#if defined(_MSC_VER) +extern PyObject* PyInit_nt(void); // nt +#endif #if !defined(_MSC_VER) extern PyObject* PyInit_grp(void); // grp #endif extern PyObject* PyInit_itertools(void); // itertools extern PyObject* PyInit_math(void); // math extern PyObject* PyInit_mmap(void); // mmap -#if defined(_MSC_VER) -extern PyObject* PyInit_nt(void); // nt -#endif -extern PyObject* PyInit_parser(void); // parser #if !defined(_MSC_VER) extern PyObject* PyInit_posix(void); // posix #endif @@ -192,7 +190,6 @@ struct _inittab _PyImport_Inittab[] = { {"_multiprocessing", PyInit__multiprocessing}, {"_opcode", PyInit__opcode}, {"_operator", PyInit__operator}, - {"_peg_parser", PyInit__peg_parser}, {"_pickle", PyInit__pickle}, {"_posixshmem", PyInit__posixshmem}, #if !defined(_MSC_VER) @@ -225,6 +222,9 @@ struct _inittab _PyImport_Inittab[] = { {"binascii", PyInit_binascii}, {"cmath", PyInit_cmath}, {"errno", PyInit_errno}, +#if defined(_MSC_VER) + {"nt", PyInit_nt}, +#endif {"faulthandler", PyInit_faulthandler}, #if !defined(_MSC_VER) {"fcntl", PyInit_fcntl}, @@ -235,10 +235,6 @@ struct _inittab _PyImport_Inittab[] = { {"itertools", PyInit_itertools}, {"math", PyInit_math}, {"mmap", PyInit_mmap}, -#if defined(_MSC_VER) - {"nt", PyInit_nt}, -#endif - {"parser", PyInit_parser}, #if !defined(_MSC_VER) {"posix", PyInit_posix}, #endif diff --git a/contrib/tools/python3/src/Modules/faulthandler.c b/contrib/tools/python3/src/Modules/faulthandler.c index 16f98ace3bb..4af8702068b 100644 --- a/contrib/tools/python3/src/Modules/faulthandler.c +++ b/contrib/tools/python3/src/Modules/faulthandler.c @@ -1,6 +1,8 @@ #include "Python.h" -#include "pycore_initconfig.h" -#include "pycore_traceback.h" +#include "pycore_initconfig.h" // _PyStatus_ERR +#include "pycore_pyerrors.h" // _Py_DumpExtensionModules +#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_traceback.h" // _Py_DumpTracebackThreads #include #include #include @@ -229,7 +231,7 @@ faulthandler_get_fileno(PyObject **file_ptr) static PyThreadState* get_thread_state(void) { - PyThreadState *tstate = _PyThreadState_UncheckedGet(); + PyThreadState *tstate = _PyThreadState_GET(); if (tstate == NULL) { /* just in case but very unlikely... */ PyErr_SetString(PyExc_RuntimeError, @@ -371,6 +373,8 @@ faulthandler_fatal_error(int signum) faulthandler_dump_traceback(fd, fatal_error.all_threads, fatal_error.interp); + _Py_DumpExtensionModules(fd, fatal_error.interp); + errno = save_errno; #ifdef MS_WINDOWS if (signum == SIGSEGV) { @@ -1148,25 +1152,6 @@ faulthandler_sigabrt(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * -faulthandler_fatal_error_py(PyObject *self, PyObject *args) -{ - char *message; - int release_gil = 0; - if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) - return NULL; - faulthandler_suppress_crash_report(); - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - Py_FatalError(message); - Py_END_ALLOW_THREADS - } - else { - Py_FatalError(message); - } - Py_RETURN_NONE; -} - #if defined(FAULTHANDLER_USE_ALT_STACK) #define FAULTHANDLER_STACK_OVERFLOW @@ -1303,8 +1288,6 @@ static PyMethodDef module_methods[] = { PyDoc_STR("_sigabrt(): raise a SIGABRT signal")}, {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS, PyDoc_STR("_sigfpe(): raise a SIGFPE signal")}, - {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS, - PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")}, #ifdef FAULTHANDLER_STACK_OVERFLOW {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS, PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")}, @@ -1316,59 +1299,55 @@ static PyMethodDef module_methods[] = { {NULL, NULL} /* sentinel */ }; -static struct PyModuleDef module_def = { - PyModuleDef_HEAD_INIT, - "faulthandler", - module_doc, - 0, /* non-negative size to be able to unload the module */ - module_methods, - NULL, - faulthandler_traverse, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_faulthandler(void) -{ - PyObject *m = PyModule_Create(&module_def); - if (m == NULL) - return NULL; - +static int +PyExec_faulthandler(PyObject *module) { /* Add constants for unit tests */ #ifdef MS_WINDOWS /* RaiseException() codes (prefixed by an underscore) */ - if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", + if (PyModule_AddIntConstant(module, "_EXCEPTION_ACCESS_VIOLATION", EXCEPTION_ACCESS_VIOLATION)) { - goto error; + return -1; } - if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", + if (PyModule_AddIntConstant(module, "_EXCEPTION_INT_DIVIDE_BY_ZERO", EXCEPTION_INT_DIVIDE_BY_ZERO)) { - goto error; + return -1; } - if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", + if (PyModule_AddIntConstant(module, "_EXCEPTION_STACK_OVERFLOW", EXCEPTION_STACK_OVERFLOW)) { - goto error; + return -1; } /* RaiseException() flags (prefixed by an underscore) */ - if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", + if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE", EXCEPTION_NONCONTINUABLE)) { - goto error; + return -1; } - if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", + if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", EXCEPTION_NONCONTINUABLE_EXCEPTION)) { - goto error; + return -1; } #endif + return 0; +} - return m; +static PyModuleDef_Slot faulthandler_slots[] = { + {Py_mod_exec, PyExec_faulthandler}, + {0, NULL} +}; -#ifdef MS_WINDOWS -error: - Py_DECREF(m); - return NULL; -#endif +static struct PyModuleDef module_def = { + PyModuleDef_HEAD_INIT, + .m_name = "faulthandler", + .m_doc = module_doc, + .m_methods = module_methods, + .m_traverse = faulthandler_traverse, + .m_slots = faulthandler_slots +}; + +PyMODINIT_FUNC +PyInit_faulthandler(void) +{ + return PyModuleDef_Init(&module_def); } static int diff --git a/contrib/tools/python3/src/Modules/fcntlmodule.c b/contrib/tools/python3/src/Modules/fcntlmodule.c index 43f9b22f672..cdf0f9bf379 100644 --- a/contrib/tools/python3/src/Modules/fcntlmodule.c +++ b/contrib/tools/python3/src/Modules/fcntlmodule.c @@ -20,24 +20,12 @@ module fcntl [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/ -static int -conv_descriptor(PyObject *object, int *target) -{ - int fd = PyObject_AsFileDescriptor(object); - - if (fd < 0) - return 0; - *target = fd; - return 1; -} - -/* Must come after conv_descriptor definition. */ #include "clinic/fcntlmodule.c.h" /*[clinic input] fcntl.fcntl - fd: object(type='int', converter='conv_descriptor') + fd: fildes cmd as code: int arg: object(c_default='NULL') = 0 / @@ -57,7 +45,7 @@ corresponding to the return value of the fcntl call in the C code. static PyObject * fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) -/*[clinic end generated code: output=888fc93b51c295bd input=8cefbe59b29efbe2]*/ +/*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/ { unsigned int int_arg = 0; int ret; @@ -116,7 +104,7 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) /*[clinic input] fcntl.ioctl - fd: object(type='int', converter='conv_descriptor') + fd: fildes request as code: unsigned_int(bitwise=True) arg as ob_arg: object(c_default='NULL') = 0 mutate_flag as mutate_arg: bool = True @@ -155,7 +143,7 @@ code. static PyObject * fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, PyObject *ob_arg, int mutate_arg) -/*[clinic end generated code: output=7f7f5840c65991be input=ede70c433cccbbb2]*/ +/*[clinic end generated code: output=7f7f5840c65991be input=967b4a4cbeceb0a8]*/ { #define IOCTL_BUFSZ 1024 /* We use the unsigned non-checked 'I' format for the 'code' parameter @@ -280,7 +268,7 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, /*[clinic input] fcntl.flock - fd: object(type='int', converter='conv_descriptor') + fd: fildes operation as code: int / @@ -292,7 +280,7 @@ function is emulated using fcntl()). static PyObject * fcntl_flock_impl(PyObject *module, int fd, int code) -/*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/ +/*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/ { int ret; int async_err = 0; @@ -346,7 +334,7 @@ fcntl_flock_impl(PyObject *module, int fd, int code) /*[clinic input] fcntl.lockf - fd: object(type='int', converter='conv_descriptor') + fd: fildes cmd as code: int len as lenobj: object(c_default='NULL') = 0 start as startobj: object(c_default='NULL') = 0 @@ -380,7 +368,7 @@ starts. `whence` is as with fileobj.seek(), specifically: static PyObject * fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, PyObject *startobj, int whence) -/*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/ +/*[clinic end generated code: output=4985e7a172e7461a input=5480479fc63a04b8]*/ { int ret; int async_err = 0; @@ -577,6 +565,14 @@ all_ins(PyObject* m) if (PyModule_AddIntMacro(m, F_SHLCK)) return -1; #endif +/* Linux specifics */ +#ifdef F_SETPIPE_SZ + if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1; +#endif +#ifdef F_GETPIPE_SZ + if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1; +#endif + /* OS X specifics */ #ifdef F_FULLFSYNC if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1; @@ -662,34 +658,31 @@ all_ins(PyObject* m) return 0; } +static int +fcntl_exec(PyObject *module) +{ + if (all_ins(module) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot fcntl_slots[] = { + {Py_mod_exec, fcntl_exec}, + {0, NULL} +}; static struct PyModuleDef fcntlmodule = { PyModuleDef_HEAD_INIT, - "fcntl", - module_doc, - -1, - fcntl_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "fcntl", + .m_doc = module_doc, + .m_size = 0, + .m_methods = fcntl_methods, + .m_slots = fcntl_slots, }; PyMODINIT_FUNC PyInit_fcntl(void) { - PyObject *m; - - /* Create the module and add the functions and documentation */ - m = PyModule_Create(&fcntlmodule); - if (m == NULL) - return NULL; - - /* Add some symbolic constants to the module */ - if (all_ins(m) < 0) { - Py_DECREF(m); - return NULL; - } - - return m; + return PyModuleDef_Init(&fcntlmodule); } diff --git a/contrib/tools/python3/src/Modules/gcmodule.c b/contrib/tools/python3/src/Modules/gcmodule.c index 3cf1a00b003..805a159d53d 100644 --- a/contrib/tools/python3/src/Modules/gcmodule.c +++ b/contrib/tools/python3/src/Modules/gcmodule.c @@ -31,7 +31,6 @@ #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() #include "pydtrace.h" -#include "pytime.h" // _PyTime_GetMonotonicClock() typedef struct _gc_runtime_state GCState; @@ -128,6 +127,15 @@ gc_decref(PyGC_Head *g) #define GEN_HEAD(gcstate, n) (&(gcstate)->generations[n].head) + +static GCState * +get_gc_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->gc; +} + + void _PyGC_InitState(GCState *gcstate) { @@ -153,15 +161,20 @@ _PyGC_InitState(GCState *gcstate) PyStatus -_PyGC_Init(PyThreadState *tstate) +_PyGC_Init(PyInterpreterState *interp) { - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &interp->gc; + + gcstate->garbage = PyList_New(0); if (gcstate->garbage == NULL) { - gcstate->garbage = PyList_New(0); - if (gcstate->garbage == NULL) { - return _PyStatus_NO_MEMORY(); - } + return _PyStatus_NO_MEMORY(); } + + gcstate->callbacks = PyList_New(0); + if (gcstate->callbacks == NULL) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); } @@ -1023,15 +1036,15 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, * Clearing the free lists may give back memory to the OS earlier. */ static void -clear_freelists(void) +clear_freelists(PyInterpreterState *interp) { - _PyFrame_ClearFreeList(); - _PyTuple_ClearFreeList(); - _PyFloat_ClearFreeList(); - _PyList_ClearFreeList(); - _PyDict_ClearFreeList(); - _PyAsyncGen_ClearFreeLists(); - _PyContext_ClearFreeList(); + _PyFrame_ClearFreeList(interp); + _PyTuple_ClearFreeList(interp); + _PyFloat_ClearFreeList(interp); + _PyList_ClearFreeList(interp); + _PyDict_ClearFreeList(interp); + _PyAsyncGen_ClearFreeLists(interp); + _PyContext_ClearFreeList(interp); } // Show stats for objects in each generations @@ -1043,7 +1056,7 @@ show_stats_each_generations(GCState *gcstate) for (int i = 0; i < NUM_GENERATIONS && pos < sizeof(buf); i++) { pos += PyOS_snprintf(buf+pos, sizeof(buf)-pos, - " %"PY_FORMAT_SIZE_T"d", + " %zd", gc_list_size(GEN_HEAD(gcstate, i))); } @@ -1167,8 +1180,9 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable, /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t -collect(PyThreadState *tstate, int generation, - Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail) +gc_collect_main(PyThreadState *tstate, int generation, + Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, + int nofail) { int i; Py_ssize_t m = 0; /* # objects collected */ @@ -1181,6 +1195,19 @@ collect(PyThreadState *tstate, int generation, _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ GCState *gcstate = &tstate->interp->gc; + // gc_collect_main() must not be called before _PyGC_Init + // or after _PyGC_Fini() + assert(gcstate->garbage != NULL); + assert(!_PyErr_Occurred(tstate)); + +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + if (tstate->interp->config._isolated_interpreter) { + // bpo-40533: The garbage collector must not be run on parallel on + // Python objects shared by multiple interpreters. + return 0; + } +#endif + if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); show_stats_each_generations(gcstate); @@ -1282,8 +1309,7 @@ collect(PyThreadState *tstate, int generation, if (gcstate->debug & DEBUG_STATS) { double d = _PyTime_AsSecondsDouble(_PyTime_GetMonotonicClock() - t1); PySys_WriteStderr( - "gc: done, %" PY_FORMAT_SIZE_T "d unreachable, " - "%" PY_FORMAT_SIZE_T "d uncollectable, %.4fs elapsed\n", + "gc: done, %zd unreachable, %zd uncollectable, %.4fs elapsed\n", n+m, n, d); } @@ -1297,7 +1323,7 @@ collect(PyThreadState *tstate, int generation, /* Clear free list only during the collection of the highest * generation */ if (generation == NUM_GENERATIONS-1) { - clear_freelists(); + clear_freelists(tstate->interp); } if (_PyErr_Occurred(tstate)) { @@ -1379,19 +1405,19 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase, * progress callbacks. */ static Py_ssize_t -collect_with_callback(PyThreadState *tstate, int generation) +gc_collect_with_callback(PyThreadState *tstate, int generation) { assert(!_PyErr_Occurred(tstate)); Py_ssize_t result, collected, uncollectable; invoke_gc_callback(tstate, "start", generation, 0, 0); - result = collect(tstate, generation, &collected, &uncollectable, 0); + result = gc_collect_main(tstate, generation, &collected, &uncollectable, 0); invoke_gc_callback(tstate, "stop", generation, collected, uncollectable); assert(!_PyErr_Occurred(tstate)); return result; } static Py_ssize_t -collect_generations(PyThreadState *tstate) +gc_collect_generations(PyThreadState *tstate) { GCState *gcstate = &tstate->interp->gc; /* Find the oldest generation (highest numbered) where the count @@ -1439,7 +1465,7 @@ collect_generations(PyThreadState *tstate) if (i == NUM_GENERATIONS - 1 && gcstate->long_lived_pending < gcstate->long_lived_total / 4) continue; - n = collect_with_callback(tstate, i); + n = gc_collect_with_callback(tstate, i); break; } } @@ -1458,9 +1484,7 @@ static PyObject * gc_enable_impl(PyObject *module) /*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; - gcstate->enabled = 1; + PyGC_Enable(); Py_RETURN_NONE; } @@ -1474,9 +1498,7 @@ static PyObject * gc_disable_impl(PyObject *module) /*[clinic end generated code: output=97d1030f7aa9d279 input=8c2e5a14e800d83b]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; - gcstate->enabled = 0; + PyGC_Disable(); Py_RETURN_NONE; } @@ -1490,9 +1512,7 @@ static int gc_isenabled_impl(PyObject *module) /*[clinic end generated code: output=1874298331c49130 input=30005e0422373b31]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; - return gcstate->enabled; + return PyGC_IsEnabled(); } /*[clinic input] @@ -1528,7 +1548,7 @@ gc_collect_impl(PyObject *module, int generation) } else { gcstate->collecting = 1; - n = collect_with_callback(tstate, generation); + n = gc_collect_with_callback(tstate, generation); gcstate->collecting = 0; } return n; @@ -1556,8 +1576,7 @@ static PyObject * gc_set_debug_impl(PyObject *module, int flags) /*[clinic end generated code: output=7c8366575486b228 input=5e5ce15e84fbed15]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); gcstate->debug = flags; Py_RETURN_NONE; } @@ -1572,8 +1591,7 @@ static int gc_get_debug_impl(PyObject *module) /*[clinic end generated code: output=91242f3506cd1e50 input=91a101e1c3b98366]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return gcstate->debug; } @@ -1586,8 +1604,7 @@ PyDoc_STRVAR(gc_set_thresh__doc__, static PyObject * gc_set_threshold(PyObject *self, PyObject *args) { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &gcstate->generations[0].threshold, &gcstate->generations[1].threshold, @@ -1610,8 +1627,7 @@ static PyObject * gc_get_threshold_impl(PyObject *module) /*[clinic end generated code: output=7902bc9f41ecbbd8 input=286d79918034d6e6]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return Py_BuildValue("(iii)", gcstate->generations[0].threshold, gcstate->generations[1].threshold, @@ -1628,8 +1644,7 @@ static PyObject * gc_get_count_impl(PyObject *module) /*[clinic end generated code: output=354012e67b16398f input=a392794a08251751]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return Py_BuildValue("(iii)", gcstate->generations[0].count, gcstate->generations[1].count, @@ -1672,9 +1687,6 @@ Return the list of objects that directly refer to any of objs."); static PyObject * gc_get_referrers(PyObject *self, PyObject *args) { - PyThreadState *tstate = _PyThreadState_GET(); - int i; - if (PySys_Audit("gc.get_referrers", "(O)", args) < 0) { return NULL; } @@ -1684,8 +1696,8 @@ gc_get_referrers(PyObject *self, PyObject *args) return NULL; } - GCState *gcstate = &tstate->interp->gc; - for (i = 0; i < NUM_GENERATIONS; i++) { + GCState *gcstate = get_gc_state(); + for (int i = 0; i < NUM_GENERATIONS; i++) { if (!(gc_referrers_for(args, GEN_HEAD(gcstate, i), result))) { Py_DECREF(result); return NULL; @@ -1811,11 +1823,10 @@ gc_get_stats_impl(PyObject *module) { int i; struct gc_generation_stats stats[NUM_GENERATIONS], *st; - PyThreadState *tstate = _PyThreadState_GET(); /* To get consistent values despite allocations while constructing the result list, we use a snapshot of the running stats. */ - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); for (i = 0; i < NUM_GENERATIONS; i++) { stats[i] = gcstate->generation_stats[i]; } @@ -1906,8 +1917,7 @@ static PyObject * gc_freeze_impl(PyObject *module) /*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); for (int i = 0; i < NUM_GENERATIONS; ++i) { gc_list_merge(GEN_HEAD(gcstate, i), &gcstate->permanent_generation.head); gcstate->generations[i].count = 0; @@ -1927,8 +1937,7 @@ static PyObject * gc_unfreeze_impl(PyObject *module) /*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); gc_list_merge(&gcstate->permanent_generation.head, GEN_HEAD(gcstate, NUM_GENERATIONS-1)); Py_RETURN_NONE; @@ -1944,8 +1953,7 @@ static Py_ssize_t gc_get_freeze_count_impl(PyObject *module) /*[clinic end generated code: output=61cbd9f43aa032e1 input=45ffbc65cfe2a6ed]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); return gc_list_size(&gcstate->permanent_generation.head); } @@ -1996,63 +2004,79 @@ static PyMethodDef GcMethods[] = { {NULL, NULL} /* Sentinel */ }; -static struct PyModuleDef gcmodule = { - PyModuleDef_HEAD_INIT, - "gc", /* m_name */ - gc__doc__, /* m_doc */ - -1, /* m_size */ - GcMethods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; - -PyMODINIT_FUNC -PyInit_gc(void) +static int +gcmodule_exec(PyObject *module) { - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; - - PyObject *m = PyModule_Create(&gcmodule); - - if (m == NULL) { - return NULL; - } + GCState *gcstate = get_gc_state(); - if (gcstate->garbage == NULL) { - gcstate->garbage = PyList_New(0); - if (gcstate->garbage == NULL) { - return NULL; - } - } - Py_INCREF(gcstate->garbage); - if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) { - return NULL; - } - - if (gcstate->callbacks == NULL) { - gcstate->callbacks = PyList_New(0); - if (gcstate->callbacks == NULL) { - return NULL; - } + /* garbage and callbacks are initialized by _PyGC_Init() early in + * interpreter lifecycle. */ + assert(gcstate->garbage != NULL); + if (PyModule_AddObjectRef(module, "garbage", gcstate->garbage) < 0) { + return -1; } - Py_INCREF(gcstate->callbacks); - if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) { - return NULL; + assert(gcstate->callbacks != NULL); + if (PyModule_AddObjectRef(module, "callbacks", gcstate->callbacks) < 0) { + return -1; } -#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) { return NULL; } +#define ADD_INT(NAME) if (PyModule_AddIntConstant(module, #NAME, NAME) < 0) { return -1; } ADD_INT(DEBUG_STATS); ADD_INT(DEBUG_COLLECTABLE); ADD_INT(DEBUG_UNCOLLECTABLE); ADD_INT(DEBUG_SAVEALL); ADD_INT(DEBUG_LEAK); #undef ADD_INT - return m; + return 0; +} + +static PyModuleDef_Slot gcmodule_slots[] = { + {Py_mod_exec, gcmodule_exec}, + {0, NULL} +}; + +static struct PyModuleDef gcmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "gc", + .m_doc = gc__doc__, + .m_size = 0, // per interpreter state, see: get_gc_state() + .m_methods = GcMethods, + .m_slots = gcmodule_slots +}; + +PyMODINIT_FUNC +PyInit_gc(void) +{ + return PyModuleDef_Init(&gcmodule); +} + +/* C API for controlling the state of the garbage collector */ +int +PyGC_Enable(void) +{ + GCState *gcstate = get_gc_state(); + int old_state = gcstate->enabled; + gcstate->enabled = 1; + return old_state; +} + +int +PyGC_Disable(void) +{ + GCState *gcstate = get_gc_state(); + int old_state = gcstate->enabled; + gcstate->enabled = 0; + return old_state; } -/* API to invoke gc.collect() from C */ +int +PyGC_IsEnabled(void) +{ + GCState *gcstate = get_gc_state(); + return gcstate->enabled; +} + +/* Public API to invoke gc.collect() from C */ Py_ssize_t PyGC_Collect(void) { @@ -2072,7 +2096,7 @@ PyGC_Collect(void) PyObject *exc, *value, *tb; gcstate->collecting = 1; _PyErr_Fetch(tstate, &exc, &value, &tb); - n = collect_with_callback(tstate, NUM_GENERATIONS - 1); + n = gc_collect_with_callback(tstate, NUM_GENERATIONS - 1); _PyErr_Restore(tstate, exc, value, tb); gcstate->collecting = 0; } @@ -2081,41 +2105,30 @@ PyGC_Collect(void) } Py_ssize_t -_PyGC_CollectIfEnabled(void) +_PyGC_CollectNoFail(PyThreadState *tstate) { - return PyGC_Collect(); -} - -Py_ssize_t -_PyGC_CollectNoFail(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - assert(!_PyErr_Occurred(tstate)); - - GCState *gcstate = &tstate->interp->gc; - Py_ssize_t n; - /* Ideally, this function is only called on interpreter shutdown, and therefore not recursively. Unfortunately, when there are daemon threads, a daemon thread can start a cyclic garbage collection during interpreter shutdown (and then never finish it). See http://bugs.python.org/issue8713#msg195178 for an example. */ + GCState *gcstate = &tstate->interp->gc; if (gcstate->collecting) { - n = 0; - } - else { - gcstate->collecting = 1; - n = collect(tstate, NUM_GENERATIONS - 1, NULL, NULL, 1); - gcstate->collecting = 0; + return 0; } + + Py_ssize_t n; + gcstate->collecting = 1; + n = gc_collect_main(tstate, NUM_GENERATIONS - 1, NULL, NULL, 1); + gcstate->collecting = 0; return n; } void -_PyGC_DumpShutdownStats(PyThreadState *tstate) +_PyGC_DumpShutdownStats(PyInterpreterState *interp) { - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &interp->gc; if (!(gcstate->debug & DEBUG_SAVEALL) && gcstate->garbage != NULL && PyList_GET_SIZE(gcstate->garbage) > 0) { const char *message; @@ -2162,13 +2175,13 @@ gc_fini_untrack(PyGC_Head *list) void -_PyGC_Fini(PyThreadState *tstate) +_PyGC_Fini(PyInterpreterState *interp) { - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = &interp->gc; Py_CLEAR(gcstate->garbage); Py_CLEAR(gcstate->callbacks); - if (!_Py_IsMainInterpreter(tstate)) { + 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 @@ -2275,7 +2288,7 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize) !_PyErr_Occurred(tstate)) { gcstate->collecting = 1; - collect_generations(tstate); + gc_collect_generations(tstate); gcstate->collecting = 0; } PyObject *op = FROM_GC(g); @@ -2298,8 +2311,10 @@ PyObject * _PyObject_GC_New(PyTypeObject *tp) { PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp)); - if (op != NULL) - op = PyObject_INIT(op, tp); + if (op == NULL) { + return NULL; + } + _PyObject_Init(op, tp); return op; } @@ -2315,8 +2330,10 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) } size = _PyObject_VAR_SIZE(tp, nitems); op = (PyVarObject *) _PyObject_GC_Malloc(size); - if (op != NULL) - op = PyObject_INIT_VAR(op, tp, nitems); + if (op == NULL) { + return NULL; + } + _PyObject_InitVar(op, tp, nitems); return op; } @@ -2330,7 +2347,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) } PyGC_Head *g = AS_GC(op); - g = (PyGC_Head *)PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize); + g = (PyGC_Head *)PyObject_Realloc(g, sizeof(PyGC_Head) + basicsize); if (g == NULL) return (PyVarObject *)PyErr_NoMemory(); op = (PyVarObject *) FROM_GC(g); @@ -2345,12 +2362,11 @@ PyObject_GC_Del(void *op) if (_PyObject_GC_IS_TRACKED(op)) { gc_list_remove(g); } - PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->gc; + GCState *gcstate = get_gc_state(); if (gcstate->generations[0].count > 0) { gcstate->generations[0].count--; } - PyObject_FREE(g); + PyObject_Free(g); } int diff --git a/contrib/tools/python3/src/Modules/getpath.c b/contrib/tools/python3/src/Modules/getpath.c index 5014dde930e..519a7d54240 100644 --- a/contrib/tools/python3/src/Modules/getpath.c +++ b/contrib/tools/python3/src/Modules/getpath.c @@ -1325,11 +1325,6 @@ calculate_zip_path(PyCalculatePath *calculate) goto done; } - /* Replace "00" with version */ - size_t len = wcslen(calculate->zip_path); - calculate->zip_path[len - 6] = VERSION[0]; - calculate->zip_path[len - 5] = VERSION[2]; - res = _PyStatus_OK(); done: diff --git a/contrib/tools/python3/src/Modules/grpmodule.c b/contrib/tools/python3/src/Modules/grpmodule.c index cdb3ae859b3..f6298ca0ee8 100644 --- a/contrib/tools/python3/src/Modules/grpmodule.c +++ b/contrib/tools/python3/src/Modules/grpmodule.c @@ -46,20 +46,19 @@ get_grp_state(PyObject *module) return (grpmodulestate *)state; } -#define modulestate_global get_grp_state(PyState_FindModule(&grpmodule)) - static struct PyModuleDef grpmodule; #define DEFAULT_BUFFER_SIZE 1024 static PyObject * -mkgrent(struct group *p) +mkgrent(PyObject *module, struct group *p) { int setIndex = 0; PyObject *v, *w; char **member; - if ((v = PyStructSequence_New(modulestate_global->StructGrpType)) == NULL) + v = PyStructSequence_New(get_grp_state(module)->StructGrpType); + if (v == NULL) return NULL; if ((w = PyList_New(0)) == NULL) { @@ -111,30 +110,14 @@ static PyObject * grp_getgrgid_impl(PyObject *module, PyObject *id) /*[clinic end generated code: output=30797c289504a1ba input=15fa0e2ccf5cda25]*/ { - PyObject *py_int_id, *retval = NULL; + PyObject *retval = NULL; int nomem = 0; char *buf = NULL, *buf2 = NULL; gid_t gid; struct group *p; if (!_Py_Gid_Converter(id, &gid)) { - if (!PyErr_ExceptionMatches(PyExc_TypeError)) { - return NULL; - } - PyErr_Clear(); - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "group id must be int, not %.200", - Py_TYPE(id)->tp_name) < 0) { - return NULL; - } - py_int_id = PyNumber_Long(id); - if (!py_int_id) - return NULL; - if (!_Py_Gid_Converter(py_int_id, &gid)) { - Py_DECREF(py_int_id); - return NULL; - } - Py_DECREF(py_int_id); + return NULL; } #ifdef HAVE_GETGRGID_R int status; @@ -186,7 +169,7 @@ grp_getgrgid_impl(PyObject *module, PyObject *id) Py_DECREF(gid_obj); return NULL; } - retval = mkgrent(p); + retval = mkgrent(module, p); #ifdef HAVE_GETGRGID_R PyMem_RawFree(buf); #endif @@ -264,7 +247,7 @@ grp_getgrnam_impl(PyObject *module, PyObject *name) } goto out; } - retval = mkgrent(p); + retval = mkgrent(module, p); out: PyMem_RawFree(buf); Py_DECREF(bytes); @@ -291,7 +274,7 @@ grp_getgrall_impl(PyObject *module) return NULL; setgrent(); while ((p = getgrent()) != NULL) { - PyObject *v = mkgrent(p); + PyObject *v = mkgrent(module, p); if (v == NULL || PyList_Append(d, v) != 0) { Py_XDECREF(v); Py_DECREF(d); @@ -327,6 +310,26 @@ users are not explicitly listed as members of the groups they are in\n\ according to the password database. Check both databases to get\n\ complete membership information.)"); +static int +grpmodule_exec(PyObject *module) +{ + grpmodulestate *state = get_grp_state(module); + + state->StructGrpType = PyStructSequence_NewType(&struct_group_type_desc); + if (state->StructGrpType == NULL) { + return -1; + } + if (PyModule_AddType(module, state->StructGrpType) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot grpmodule_slots[] = { + {Py_mod_exec, grpmodule_exec}, + {0, NULL} +}; + static int grpmodule_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_grp_state(m)->StructGrpType); return 0; @@ -342,37 +345,19 @@ static void grpmodule_free(void *m) { } static struct PyModuleDef grpmodule = { - PyModuleDef_HEAD_INIT, - "grp", - grp__doc__, - sizeof(grpmodulestate), - grp_methods, - NULL, - grpmodule_traverse, - grpmodule_clear, - grpmodule_free, + PyModuleDef_HEAD_INIT, + .m_name = "grp", + .m_doc = grp__doc__, + .m_size = sizeof(grpmodulestate), + .m_methods = grp_methods, + .m_slots = grpmodule_slots, + .m_traverse = grpmodule_traverse, + .m_clear = grpmodule_clear, + .m_free = grpmodule_free, }; PyMODINIT_FUNC PyInit_grp(void) { - PyObject *m; - if ((m = PyState_FindModule(&grpmodule)) != NULL) { - Py_INCREF(m); - return m; - } - - if ((m = PyModule_Create(&grpmodule)) == NULL) { - return NULL; - } - - grpmodulestate *state = PyModule_GetState(m); - state->StructGrpType = PyStructSequence_NewType(&struct_group_type_desc); - if (state->StructGrpType == NULL) { - return NULL; - } - - Py_INCREF(state->StructGrpType); - PyModule_AddObject(m, "struct_group", (PyObject *) state->StructGrpType); - return m; + return PyModuleDef_Init(&grpmodule); } diff --git a/contrib/tools/python3/src/Modules/itertoolsmodule.c b/contrib/tools/python3/src/Modules/itertoolsmodule.c index fae5560ab71..f8e2c45aeca 100644 --- a/contrib/tools/python3/src/Modules/itertoolsmodule.c +++ b/contrib/tools/python3/src/Modules/itertoolsmodule.c @@ -1,8 +1,10 @@ + #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_tupleobject.h" +#include "pycore_long.h" // _PyLong_GetZero() #include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_tuple.h" // _PyTuple_ITEMS() #include // offsetof() /* Itertools module written and maintained @@ -27,8 +29,9 @@ 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" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ea05c93c6d94726a]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6498ed21fbe1bf94]*/ static PyTypeObject groupby_type; static PyTypeObject _grouper_type; @@ -45,9 +48,140 @@ static PyTypeObject accumulate_type; static PyTypeObject compress_type; static PyTypeObject filterfalse_type; static PyTypeObject count_type; +static PyTypeObject pairwise_type; #include "clinic/itertoolsmodule.c.h" +/* pairwise object ***********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *it; + PyObject *old; +} pairwiseobject; + +/*[clinic input] +@classmethod +itertools.pairwise.__new__ as pairwise_new + iterable: object + / +Return an iterator of overlapping pairs taken from the input iterator. + + s -> (s0,s1), (s1,s2), (s2, s3), ... + +[clinic start generated code]*/ + +static PyObject * +pairwise_new_impl(PyTypeObject *type, PyObject *iterable) +/*[clinic end generated code: output=9f0267062d384456 input=6e7c3cddb431a8d6]*/ +{ + PyObject *it; + pairwiseobject *po; + + it = PyObject_GetIter(iterable); + if (it == NULL) { + return NULL; + } + po = (pairwiseobject *)type->tp_alloc(type, 0); + if (po == NULL) { + Py_DECREF(it); + return NULL; + } + po->it = it; + po->old = NULL; + return (PyObject *)po; +} + +static void +pairwise_dealloc(pairwiseobject *po) +{ + PyObject_GC_UnTrack(po); + Py_XDECREF(po->it); + Py_XDECREF(po->old); + Py_TYPE(po)->tp_free(po); +} + +static int +pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg) +{ + Py_VISIT(po->it); + Py_VISIT(po->old); + return 0; +} + +static PyObject * +pairwise_next(pairwiseobject *po) +{ + PyObject *it = po->it; + PyObject *old = po->old; + PyObject *new, *result; + + if (it == NULL) { + return NULL; + } + if (old == NULL) { + po->old = old = (*Py_TYPE(it)->tp_iternext)(it); + if (old == NULL) { + Py_CLEAR(po->it); + return NULL; + } + } + new = (*Py_TYPE(it)->tp_iternext)(it); + if (new == NULL) { + Py_CLEAR(po->it); + Py_CLEAR(po->old); + return NULL; + } + /* Future optimization: Reuse the result tuple as we do in enumerate() */ + result = PyTuple_Pack(2, old, new); + Py_SETREF(po->old, new); + 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 */ +}; + /* groupby object ************************************************************/ @@ -1001,8 +1135,7 @@ cycle_dealloc(cycleobject *lz) static int cycle_traverse(cycleobject *lz, visitproc visit, void *arg) { - if (lz->it) - Py_VISIT(lz->it); + Py_VISIT(lz->it); Py_VISIT(lz->saved); return 0; } @@ -4063,13 +4196,14 @@ itertools_count_impl(PyTypeObject *type, PyObject *long_cnt, } } else { cnt = 0; - long_cnt = _PyLong_Zero; + long_cnt = _PyLong_GetZero(); } Py_INCREF(long_cnt); /* If not specified, step defaults to 1 */ - if (long_step == NULL) - long_step = _PyLong_One; + if (long_step == NULL) { + long_step = _PyLong_GetOne(); + } Py_INCREF(long_step); assert(long_cnt != NULL && long_step != NULL); @@ -4692,6 +4826,7 @@ groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ filterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\ islice(seq, [start,] stop [, step]) --> elements from\n\ seq[start:stop:step]\n\ +pairwise(s) --> (s[0],s[1]), (s[1],s[2]), (s[2], s[3]), ...\n\ starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\ takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ @@ -4721,6 +4856,7 @@ itertoolsmodule_exec(PyObject *m) &filterfalse_type, &count_type, &ziplongest_type, + &pairwise_type, &permutations_type, &product_type, &repeat_type, diff --git a/contrib/tools/python3/src/Modules/main.c b/contrib/tools/python3/src/Modules/main.c index 1eec0f96c09..1ae2b34cac2 100644 --- a/contrib/tools/python3/src/Modules/main.c +++ b/contrib/tools/python3/src/Modules/main.c @@ -88,7 +88,7 @@ static inline int config_run_code(const PyConfig *config) } -/* Return non-zero is stdin is a TTY or if -i command line option is used */ +/* Return non-zero if stdin is a TTY or if -i command line option is used */ static int stdin_is_interactive(const PyConfig *config) { @@ -224,7 +224,7 @@ pymain_import_readline(const PyConfig *config) static int -pymain_run_command(wchar_t *command, PyCompilerFlags *cf) +pymain_run_command(wchar_t *command) { PyObject *unicode, *bytes; int ret; @@ -244,7 +244,9 @@ pymain_run_command(wchar_t *command, PyCompilerFlags *cf) goto error; } - ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf); + PyCompilerFlags cf = _PyCompilerFlags_INIT; + cf.cf_flags |= PyCF_IGNORE_COOKIE; + ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), &cf); Py_DECREF(bytes); return (ret != 0); @@ -306,29 +308,23 @@ pymain_run_module(const wchar_t *modname, int set_argv0) static int -pymain_run_file(const PyConfig *config, PyCompilerFlags *cf) +pymain_run_file_obj(PyObject *program_name, PyObject *filename, + int skip_source_first_line) { - const wchar_t *filename = config->run_filename; - if (PySys_Audit("cpython.run_file", "u", filename) < 0) { + if (PySys_Audit("cpython.run_file", "O", filename) < 0) { return pymain_exit_err_print(); } - FILE *fp = _Py_wfopen(filename, L"rb"); + + FILE *fp = _Py_fopen_obj(filename, "rb"); if (fp == NULL) { - char *cfilename_buffer; - const char *cfilename; - int err = errno; - cfilename_buffer = _Py_EncodeLocaleRaw(filename, NULL); - if (cfilename_buffer != NULL) - cfilename = cfilename_buffer; - else - cfilename = ""; - fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n", - config->program_name, cfilename, err, strerror(err)); - PyMem_RawFree(cfilename_buffer); + // Ignore the OSError + PyErr_Clear(); + PySys_FormatStderr("%S: can't open file %R: [Errno %d] %s\n", + program_name, filename, errno, strerror(errno)); return 2; } - if (config->skip_source_first_line) { + if (skip_source_first_line) { int ch; /* Push back first newline so line numbers remain the same */ while ((ch = getc(fp)) != EOF) { @@ -341,104 +337,97 @@ pymain_run_file(const PyConfig *config, PyCompilerFlags *cf) struct _Py_stat_struct sb; if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { - fprintf(stderr, - "%ls: '%ls' is a directory, cannot continue\n", - config->program_name, filename); + PySys_FormatStderr("%S: %R is a directory, cannot continue\n", + program_name, filename); fclose(fp); return 1; } - /* call pending calls like signal handlers (SIGINT) */ + // Call pending calls like signal handlers (SIGINT) if (Py_MakePendingCalls() == -1) { fclose(fp); return pymain_exit_err_print(); } - PyObject *unicode, *bytes = NULL; - const char *filename_str; + /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */ + PyCompilerFlags cf = _PyCompilerFlags_INIT; + int run = _PyRun_AnyFileObject(fp, filename, 1, &cf); + return (run != 0); +} - unicode = PyUnicode_FromWideChar(filename, wcslen(filename)); - if (unicode != NULL) { - bytes = PyUnicode_EncodeFSDefault(unicode); - Py_DECREF(unicode); - } - if (bytes != NULL) { - filename_str = PyBytes_AsString(bytes); +static int +pymain_run_file(const PyConfig *config) +{ + PyObject *filename = PyUnicode_FromWideChar(config->run_filename, -1); + if (filename == NULL) { + PyErr_Print(); + return -1; } - else { - PyErr_Clear(); - filename_str = ""; + PyObject *program_name = PyUnicode_FromWideChar(config->program_name, -1); + if (program_name == NULL) { + Py_DECREF(filename); + PyErr_Print(); + return -1; } - /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */ - int run = PyRun_AnyFileExFlags(fp, filename_str, 1, cf); - Py_XDECREF(bytes); - return (run != 0); + int res = pymain_run_file_obj(program_name, filename, + config->skip_source_first_line); + Py_DECREF(filename); + Py_DECREF(program_name); + return res; } static int -pymain_run_startup(PyConfig *config, PyCompilerFlags *cf, int *exitcode) +pymain_run_startup(PyConfig *config, int *exitcode) { int ret; - PyObject *startup_obj = NULL; if (!config->use_environment) { return 0; } + PyObject *startup = NULL; #ifdef MS_WINDOWS - const wchar_t *wstartup = _wgetenv(L"PYTHONSTARTUP"); - if (wstartup == NULL || wstartup[0] == L'\0') { + const wchar_t *env = _wgetenv(L"PYTHONSTARTUP"); + if (env == NULL || env[0] == L'\0') { return 0; } - PyObject *startup_bytes = NULL; - startup_obj = PyUnicode_FromWideChar(wstartup, wcslen(wstartup)); - if (startup_obj == NULL) { - goto error; - } - startup_bytes = PyUnicode_EncodeFSDefault(startup_obj); - if (startup_bytes == NULL) { + startup = PyUnicode_FromWideChar(env, wcslen(env)); + if (startup == NULL) { goto error; } - const char *startup = PyBytes_AS_STRING(startup_bytes); #else - const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP"); - if (startup == NULL) { + const char *env = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP"); + if (env == NULL) { return 0; } - startup_obj = PyUnicode_DecodeFSDefault(startup); - if (startup_obj == NULL) { + startup = PyUnicode_DecodeFSDefault(env); + if (startup == NULL) { goto error; } #endif - if (PySys_Audit("cpython.run_startup", "O", startup_obj) < 0) { + if (PySys_Audit("cpython.run_startup", "O", startup) < 0) { goto error; } -#ifdef MS_WINDOWS - FILE *fp = _Py_wfopen(wstartup, L"r"); -#else - FILE *fp = _Py_fopen(startup, "r"); -#endif + FILE *fp = _Py_fopen_obj(startup, "r"); if (fp == NULL) { int save_errno = errno; PyErr_Clear(); PySys_WriteStderr("Could not open PYTHONSTARTUP\n"); errno = save_errno; - PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, startup_obj, NULL); + PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, startup, NULL); goto error; } - (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf); + PyCompilerFlags cf = _PyCompilerFlags_INIT; + (void) _PyRun_SimpleFileObject(fp, startup, 0, &cf); PyErr_Clear(); fclose(fp); ret = 0; done: -#ifdef MS_WINDOWS - Py_XDECREF(startup_bytes); -#endif - Py_XDECREF(startup_obj); + Py_XDECREF(startup); return ret; error: @@ -485,14 +474,14 @@ error: static int -pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf) +pymain_run_stdin(PyConfig *config) { if (stdin_is_interactive(config)) { config->inspect = 0; Py_InspectFlag = 0; /* do exit on SystemExit */ int exitcode; - if (pymain_run_startup(config, cf, &exitcode)) { + if (pymain_run_startup(config, &exitcode)) { return exitcode; } @@ -510,13 +499,14 @@ pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf) return pymain_exit_err_print(); } - int run = PyRun_AnyFileExFlags(stdin, "", 0, cf); + PyCompilerFlags cf = _PyCompilerFlags_INIT; + int run = PyRun_AnyFileExFlags(stdin, "", 0, &cf); return (run != 0); } static void -pymain_repl(PyConfig *config, PyCompilerFlags *cf, int *exitcode) +pymain_repl(PyConfig *config, int *exitcode) { /* Check this environment variable at the end, to give programs the opportunity to set it from Python. */ @@ -535,7 +525,8 @@ pymain_repl(PyConfig *config, PyCompilerFlags *cf, int *exitcode) return; } - int res = PyRun_AnyFileFlags(stdin, "", cf); + PyCompilerFlags cf = _PyCompilerFlags_INIT; + int res = PyRun_AnyFileFlags(stdin, "", &cf); *exitcode = (res != 0); } @@ -581,13 +572,11 @@ pymain_run_python(int *exitcode) } } - PyCompilerFlags cf = _PyCompilerFlags_INIT; - pymain_header(config); pymain_import_readline(config); if (config->run_command) { - *exitcode = pymain_run_command(config->run_command, &cf); + *exitcode = pymain_run_command(config->run_command); } else if (config->run_module) { *exitcode = pymain_run_module(config->run_module, 1); @@ -596,13 +585,13 @@ pymain_run_python(int *exitcode) *exitcode = pymain_run_module(L"__main__", 0); } else if (config->run_filename != NULL) { - *exitcode = pymain_run_file(config, &cf); + *exitcode = pymain_run_file(config); } else { - *exitcode = pymain_run_stdin(config, &cf); + *exitcode = pymain_run_stdin(config); } - pymain_repl(config, &cf, exitcode); + pymain_repl(config, exitcode); goto done; error: diff --git a/contrib/tools/python3/src/Modules/mathmodule.c b/contrib/tools/python3/src/Modules/mathmodule.c index 1f16849a3e6..4534176adce 100644 --- a/contrib/tools/python3/src/Modules/mathmodule.c +++ b/contrib/tools/python3/src/Modules/mathmodule.c @@ -53,7 +53,9 @@ raised for division by zero and mod by zero. */ #include "Python.h" +#include "pycore_bitutils.h" // _Py_bit_length() #include "pycore_dtoa.h" +#include "pycore_long.h" // _PyLong_GetZero() #include "_math.h" #include "clinic/mathmodule.c.h" @@ -843,13 +845,15 @@ math_gcd(PyObject *module, PyObject * const *args, Py_ssize_t nargs) Py_SETREF(res, PyNumber_Absolute(res)); return res; } + + PyObject *one = _PyLong_GetOne(); // borrowed ref for (i = 1; i < nargs; i++) { - x = PyNumber_Index(args[i]); + x = _PyNumber_Index(args[i]); if (x == NULL) { Py_DECREF(res); return NULL; } - if (res == _PyLong_One) { + if (res == one) { /* Fast path: just check arguments. It is okay to use identity comparison here. */ Py_DECREF(x); @@ -916,13 +920,15 @@ math_lcm(PyObject *module, PyObject * const *args, Py_ssize_t nargs) Py_SETREF(res, PyNumber_Absolute(res)); return res; } + + PyObject *zero = _PyLong_GetZero(); // borrowed ref for (i = 1; i < nargs; i++) { x = PyNumber_Index(args[i]); if (x == NULL) { Py_DECREF(res); return NULL; } - if (res == _PyLong_Zero) { + if (res == zero) { /* Fast path: just check arguments. It is okay to use identity comparison here. */ Py_DECREF(x); @@ -1732,7 +1738,7 @@ math_isqrt(PyObject *module, PyObject *n) uint64_t m, u; PyObject *a = NULL, *b; - n = PyNumber_Index(n); + n = _PyNumber_Index(n); if (n == NULL) { return NULL; } @@ -1840,7 +1846,7 @@ math_isqrt(PyObject *module, PyObject *n) } if (a_too_large) { - Py_SETREF(a, PyNumber_Subtract(a, _PyLong_One)); + Py_SETREF(a, PyNumber_Subtract(a, _PyLong_GetOne())); } Py_DECREF(n); return a; @@ -1877,7 +1883,7 @@ math_isqrt(PyObject *module, PyObject *n) * (1) * * (1) * * (1 * 3 * 5) * - * (1 * 3 * 5 * 7 * 9) + * (1 * 3 * 5 * 7 * 9) * * (1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19) * * Here i goes from large to small: the first term corresponds to i=4 (any @@ -2056,37 +2062,9 @@ math_factorial(PyObject *module, PyObject *arg) { long x, two_valuation; int overflow; - PyObject *result, *odd_part, *pyint_form; - - if (PyFloat_Check(arg)) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Using factorial() with floats is deprecated", - 1) < 0) - { - return NULL; - } - PyObject *lx; - double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); - if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { - PyErr_SetString(PyExc_ValueError, - "factorial() only accepts integral values"); - return NULL; - } - lx = PyLong_FromDouble(dx); - if (lx == NULL) - return NULL; - x = PyLong_AsLongAndOverflow(lx, &overflow); - Py_DECREF(lx); - } - else { - pyint_form = PyNumber_Index(arg); - if (pyint_form == NULL) { - return NULL; - } - x = PyLong_AsLongAndOverflow(pyint_form, &overflow); - Py_DECREF(pyint_form); - } + PyObject *result, *odd_part; + x = PyLong_AsLongAndOverflow(arg, &overflow); if (x == -1 && PyErr_Occurred()) { return NULL; } @@ -2435,40 +2413,108 @@ math_fmod_impl(PyObject *module, double x, double y) } /* -Given an *n* length *vec* of values and a value *max*, compute: +Given a *vec* of values, compute the vector norm: - max * sqrt(sum((x / max) ** 2 for x in vec)) + sqrt(sum(x ** 2 for x in vec)) -The value of the *max* variable must be non-negative and -equal to the absolute value of the largest magnitude -entry in the vector. If n==0, then *max* should be 0.0. +The *max* variable should be equal to the largest fabs(x). +The *n* variable is the length of *vec*. +If n==0, then *max* should be 0.0. If an infinity is present in the vec, *max* should be INF. - The *found_nan* variable indicates whether some member of the *vec* is a NaN. -To improve accuracy and to increase the number of cases where -vector_norm() is commutative, we use a variant of Neumaier -summation specialized to exploit that we always know that -|csum| >= |x|. - -The *csum* variable tracks the cumulative sum and *frac* tracks -the cumulative fractional errors at each step. Since this -variant assumes that |csum| >= |x| at each step, we establish -the precondition by starting the accumulation from 1.0 which -represents the largest possible value of (x/max)**2. - -After the loop is finished, the initial 1.0 is subtracted out -for a net zero effect on the final sum. Since *csum* will be -greater than 1.0, the subtraction of 1.0 will not cause -fractional digits to be dropped from *csum*. +To avoid overflow/underflow and to achieve high accuracy giving results +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] +* compensated summation using a variant of the Neumaier algorithm [2] +* differential correction of the square root [3] + +The usual presentation of the Neumaier summation algorithm has an +expensive branch depending on which operand has the larger +magnitude. We avoid this cost by arranging the calculation so that +fabs(csum) is always as large as fabs(x). + +To establish the invariant, *csum* is initialized to 1.0 which is +always larger than x**2 after scaling or after division by *max*. +After the loop is finished, the initial 1.0 is subtracted out for a +net zero effect on the final sum. Since *csum* will be greater than +1.0, the subtraction of 1.0 will not cause fractional digits to be +dropped from *csum*. + +To get the full benefit from compensated summation, the largest +addend should be in the range: 0.5 <= |x| <= 1.0. Accordingly, +scaling or division by *max* should not be skipped even if not +otherwise needed to prevent overflow or loss of precision. + +The assertion that hi*hi <= 1.0 is a bit subtle. Each vector element +gets scaled to a magnitude below 1.0. The Veltkamp-Dekker splitting +algorithm gives a *hi* value that is correctly rounded to half +precision. When a value at or below 1.0 is correctly rounded, it +never goes above 1.0. And when values at or below 1.0 are squared, +they remain at or below 1.0, thus preserving the summation invariant. + +Another interesting assertion is that csum+lo*lo == csum. In the loop, +each scaled vector element has a magnitude less than 1.0. After the +Veltkamp split, *lo* has a maximum value of 2**-27. So the maximum +value of *lo* squared is 2**-54. The value of ulp(1.0)/2.0 is 2**-53. +Given that csum >= 1.0, we have: + lo**2 <= 2**-54 < 2**-53 == 1/2*ulp(1.0) <= ulp(csum)/2 +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). + +The square root differential correction is needed because a +correctly rounded square root of a correctly rounded sum of +squares can still be off by as much as one ulp. + +The differential correction starts with a value *x* that is +the difference between the square of *h*, the possibly inaccurately +rounded square root, and the accurately computed sum of squares. +The correction is the first order term of the Maclaurin series +expansion of sqrt(h**2 + x) == h + x/(2*h) + O(x**2). [5] + +Essentially, this differential correction is equivalent to one +refinement step in Newton's divide-and-average square root +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] + +References: + +1. Veltkamp-Dekker splitting: http://csclub.uwaterloo.ca/~pbarfuss/dekker1971.pdf +2. Compensated summation: http://www.ti3.tu-harburg.de/paper/rump/Ru08b.pdf +3. Square root differential correction: https://arxiv.org/pdf/1904.09481.pdf +4. Data dependency graph: https://bugs.python.org/file49439/hypot.png +5. https://www.wolframalpha.com/input/?i=Maclaurin+series+sqrt%28h**2+%2B+x%29+at+x%3D0 +6. Analysis of internal accuracy: https://bugs.python.org/file49484/best_frac.py +7. Commutativity test: https://bugs.python.org/file49448/test_hypot_commutativity.py */ static inline double vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { - double x, csum = 1.0, oldcsum, frac = 0.0; + 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; + int max_e; Py_ssize_t i; if (Py_IS_INFINITY(max)) { @@ -2480,17 +2526,83 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) if (max == 0.0 || n <= 1) { 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); + 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*. + */ 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; - assert(csum >= x); - frac += (oldcsum - csum) + x; + frac1 += (oldcsum - csum) + x; } - return max * sqrt(csum - 1.0 + frac); + return max * sqrt(csum - 1.0 + frac1); } #define NUM_STACK_ELEMS 16 @@ -2973,7 +3085,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) } if (result == NULL) { - result = _PyLong_One; + result = _PyLong_GetOne(); } Py_INCREF(result); #ifndef SLOW_PROD @@ -3135,24 +3247,11 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) if (n == NULL) { return NULL; } - if (!PyLong_CheckExact(n)) { - Py_SETREF(n, _PyLong_Copy((PyLongObject *)n)); - if (n == NULL) { - return NULL; - } - } k = PyNumber_Index(k); if (k == NULL) { Py_DECREF(n); return NULL; } - if (!PyLong_CheckExact(k)) { - Py_SETREF(k, _PyLong_Copy((PyLongObject *)k)); - if (k == NULL) { - Py_DECREF(n); - return NULL; - } - } if (Py_SIZE(n) < 0) { PyErr_SetString(PyExc_ValueError, @@ -3197,10 +3296,10 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) goto done; } - factor = n; - Py_INCREF(factor); + factor = Py_NewRef(n); + PyObject *one = _PyLong_GetOne(); // borrowed ref for (i = 1; i < factors; ++i) { - Py_SETREF(factor, PyNumber_Subtract(factor, _PyLong_One)); + Py_SETREF(factor, PyNumber_Subtract(factor, one)); if (factor == NULL) { goto error; } @@ -3258,24 +3357,11 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) if (n == NULL) { return NULL; } - if (!PyLong_CheckExact(n)) { - Py_SETREF(n, _PyLong_Copy((PyLongObject *)n)); - if (n == NULL) { - return NULL; - } - } k = PyNumber_Index(k); if (k == NULL) { Py_DECREF(n); return NULL; } - if (!PyLong_CheckExact(k)) { - Py_SETREF(k, _PyLong_Copy((PyLongObject *)k)); - if (k == NULL) { - Py_DECREF(n); - return NULL; - } - } if (Py_SIZE(n) < 0) { PyErr_SetString(PyExc_ValueError, @@ -3332,10 +3418,10 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) goto done; } - factor = n; - Py_INCREF(factor); + factor = Py_NewRef(n); + PyObject *one = _PyLong_GetOne(); // borrowed ref for (i = 1; i < factors; ++i) { - Py_SETREF(factor, PyNumber_Subtract(factor, _PyLong_One)); + Py_SETREF(factor, PyNumber_Subtract(factor, one)); if (factor == NULL) { goto error; } @@ -3390,6 +3476,12 @@ math_nextafter_impl(PyObject *module, double x, double y) Bug fixed in bos.adt.libm 7.2.2.0 by APAR IV95512. */ return PyFloat_FromDouble(y); } + if (Py_IS_NAN(x)) { + return PyFloat_FromDouble(x); + } + if (Py_IS_NAN(y)) { + return PyFloat_FromDouble(y); + } #endif return PyFloat_FromDouble(nextafter(x, y)); } diff --git a/contrib/tools/python3/src/Modules/md5module.c b/contrib/tools/python3/src/Modules/md5module.c index 6ed843376ae..b50d2e5b0bd 100644 --- a/contrib/tools/python3/src/Modules/md5module.c +++ b/contrib/tools/python3/src/Modules/md5module.c @@ -211,7 +211,7 @@ static void md5_compress(struct md5_state *md5, const unsigned char *buf) /** Initialize the hash state - @param sha1 The hash state you wish to initialize + @param md5 The hash state you wish to initialize */ static void md5_init(struct md5_state *md5) @@ -227,7 +227,7 @@ md5_init(struct md5_state *md5) /** Process a block of memory though the hash - @param sha1 The hash state + @param md5 The hash state @param in The data to hash @param inlen The length of the data (octets) */ @@ -263,7 +263,7 @@ md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen) /** Terminate the hash to get the digest - @param sha1 The hash state + @param md5 The hash state @param out [out] The destination of the hash (16 bytes) */ static void @@ -318,22 +318,41 @@ md5_done(struct md5_state *md5, unsigned char *out) * ------------------------------------------------------------------------ */ -static PyTypeObject MD5type; +typedef struct { + PyTypeObject* md5_type; +} MD5State; +static inline MD5State* +md5_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (MD5State *)state; +} static MD5object * -newMD5object(void) +newMD5object(MD5State * st) { - return (MD5object *)PyObject_New(MD5object, &MD5type); + MD5object *md5 = (MD5object *)PyObject_GC_New(MD5object, st->md5_type); + PyObject_GC_Track(md5); + return md5; } - /* Internal methods for a hash object */ +static int +MD5_traverse(PyObject *ptr, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(ptr)); + return 0; +} static void MD5_dealloc(PyObject *ptr) { - PyObject_Del(ptr); + PyTypeObject *tp = Py_TYPE(ptr); + PyObject_GC_UnTrack(ptr); + PyObject_GC_Del(ptr); + Py_DECREF(tp); } @@ -342,16 +361,19 @@ MD5_dealloc(PyObject *ptr) /*[clinic input] MD5Type.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -MD5Type_copy_impl(MD5object *self) -/*[clinic end generated code: output=596eb36852f02071 input=2c09e6d2493f3079]*/ +MD5Type_copy_impl(MD5object *self, PyTypeObject *cls) +/*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/ { - MD5object *newobj; + MD5State *st = PyType_GetModuleState(cls); - if ((newobj = newMD5object())==NULL) + MD5object *newobj; + if ((newobj = newMD5object(st))==NULL) return NULL; newobj->hash_state = self->hash_state; @@ -445,7 +467,6 @@ md5_get_digest_size(PyObject *self, void *closure) return PyLong_FromLong(MD5_DIGESTSIZE); } - static PyGetSetDef MD5_getseters[] = { {"block_size", (getter)MD5_get_block_size, NULL, @@ -462,40 +483,21 @@ static PyGetSetDef MD5_getseters[] = { {NULL} /* Sentinel */ }; -static PyTypeObject MD5type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_md5.md5", /*tp_name*/ - sizeof(MD5object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - MD5_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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - MD5_methods, /* tp_methods */ - NULL, /* tp_members */ - MD5_getseters, /* tp_getset */ +static PyType_Slot md5_type_slots[] = { + {Py_tp_dealloc, MD5_dealloc}, + {Py_tp_methods, MD5_methods}, + {Py_tp_getset, MD5_getseters}, + {Py_tp_traverse, MD5_traverse}, + {0,0} }; +static PyType_Spec md5_type_spec = { + .name = "_md5.md5", + .basicsize = sizeof(MD5object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), + .slots = md5_type_slots +}; /* The single module-level function: new() */ @@ -519,7 +521,8 @@ _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity) if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newMD5object()) == NULL) { + MD5State *st = md5_get_state(module); + if ((new = newMD5object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -549,37 +552,69 @@ static struct PyMethodDef MD5_functions[] = { {NULL, NULL} /* Sentinel */ }; +static int +_md5_traverse(PyObject *module, visitproc visit, void *arg) +{ + MD5State *state = md5_get_state(module); + Py_VISIT(state->md5_type); + return 0; +} + +static int +_md5_clear(PyObject *module) +{ + MD5State *state = md5_get_state(module); + Py_CLEAR(state->md5_type); + return 0; +} + +static void +_md5_free(void *module) +{ + _md5_clear((PyObject *)module); +} /* Initialize this module. */ +static int +md5_exec(PyObject *m) +{ + MD5State *st = md5_get_state(m); + + st->md5_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &md5_type_spec, NULL); + + if (st->md5_type == NULL) { + return -1; + } + + Py_INCREF((PyObject *)st->md5_type); + if (PyModule_AddObject(m, "MD5Type", (PyObject *)st->md5_type) < 0) { + Py_DECREF(st->md5_type); + return -1; + } + + return 0; +} + +static PyModuleDef_Slot _md5_slots[] = { + {Py_mod_exec, md5_exec}, + {0, NULL} +}; + static struct PyModuleDef _md5module = { PyModuleDef_HEAD_INIT, - "_md5", - NULL, - -1, - MD5_functions, - NULL, - NULL, - NULL, - NULL + .m_name = "_md5", + .m_size = sizeof(MD5State), + .m_methods = MD5_functions, + .m_slots = _md5_slots, + .m_traverse = _md5_traverse, + .m_clear = _md5_clear, + .m_free = _md5_free, }; PyMODINIT_FUNC PyInit__md5(void) { - PyObject *m; - - Py_SET_TYPE(&MD5type, &PyType_Type); - if (PyType_Ready(&MD5type) < 0) { - return NULL; - } - - m = PyModule_Create(&_md5module); - if (m == NULL) { - return NULL; - } - - Py_INCREF((PyObject *)&MD5type); - PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type); - return m; + return PyModuleDef_Init(&_md5module); } diff --git a/contrib/tools/python3/src/Modules/mmapmodule.c b/contrib/tools/python3/src/Modules/mmapmodule.c index a3e22d0a511..6397b0d4b81 100644 --- a/contrib/tools/python3/src/Modules/mmapmodule.c +++ b/contrib/tools/python3/src/Modules/mmapmodule.c @@ -20,6 +20,7 @@ #define PY_SSIZE_T_CLEAN #include +#include "structmember.h" // PyMemberDef #include // offsetof() #ifndef MS_WINDOWS @@ -113,10 +114,31 @@ 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) +{ + Py_VISIT(Py_TYPE(m_obj)); + return 0; +} static void mmap_object_dealloc(mmap_object *m_obj) { + PyTypeObject *tp = Py_TYPE(m_obj); + PyObject_GC_UnTrack(m_obj); + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS if (m_obj->data != NULL) @@ -142,7 +164,9 @@ mmap_object_dealloc(mmap_object *m_obj) if (m_obj->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) m_obj); - Py_TYPE(m_obj)->tp_free((PyObject*)m_obj); + + tp->tp_free(m_obj); + Py_DECREF(tp); } static PyObject * @@ -793,6 +817,11 @@ mmap_madvise_method(mmap_object *self, PyObject *args) } #endif // HAVE_MADVISE +static struct PyMemberDef mmap_object_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(mmap_object, weakreflist), READONLY}, + {NULL}, +}; + static struct PyMethodDef mmap_object_methods[] = { {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, @@ -1035,27 +1064,6 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) } } -static PySequenceMethods mmap_as_sequence = { - (lenfunc)mmap_length, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - (ssizeargfunc)mmap_item, /*sq_item*/ - 0, /*sq_slice*/ - (ssizeobjargproc)mmap_ass_item, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ -}; - -static PyMappingMethods mmap_as_mapping = { - (lenfunc)mmap_length, - (binaryfunc)mmap_subscript, - (objobjargproc)mmap_ass_subscript, -}; - -static PyBufferProcs mmap_as_buffer = { - (getbufferproc)mmap_buffer_getbuf, - (releasebufferproc)mmap_buffer_releasebuf, -}; - static PyObject * new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict); @@ -1083,47 +1091,39 @@ The default value is MAP_SHARED.\n\ To map anonymous memory, pass -1 as the fileno (both versions)."); -static PyTypeObject mmap_object_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "mmap.mmap", /* tp_name */ - sizeof(mmap_object), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mmap_object_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)mmap__repr__method, /* tp_repr */ - 0, /* tp_as_number */ - &mmap_as_sequence, /* tp_as_sequence */ - &mmap_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - &mmap_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - mmap_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(mmap_object, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - mmap_object_methods, /* tp_methods */ - 0, /* tp_members */ - mmap_object_getset, /* 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 */ - new_mmap_object, /* tp_new */ - PyObject_Del, /* tp_free */ +static PyType_Slot mmap_object_slots[] = { + {Py_tp_new, new_mmap_object}, + {Py_tp_dealloc, mmap_object_dealloc}, + {Py_tp_repr, mmap__repr__method}, + {Py_tp_doc, (void *)mmap_doc}, + {Py_tp_methods, mmap_object_methods}, + {Py_tp_members, mmap_object_members}, + {Py_tp_getset, mmap_object_getset}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mmap_object_traverse}, + + /* as sequence */ + {Py_sq_length, mmap_length}, + {Py_sq_item, mmap_item}, + {Py_sq_ass_item, mmap_ass_item}, + + /* as mapping */ + {Py_mp_length, mmap_length}, + {Py_mp_subscript, mmap_subscript}, + {Py_mp_ass_subscript, mmap_ass_subscript}, + + /* as buffer */ + {Py_bf_getbuffer, mmap_buffer_getbuf}, + {Py_bf_releasebuffer, mmap_buffer_releasebuf}, + {0, NULL}, +}; + +static PyType_Spec mmap_object_spec = { + .name = "mmap.mmap", + .basicsize = sizeof(mmap_object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = mmap_object_slots, }; @@ -1378,13 +1378,10 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) */ if (fileno != -1 && fileno != 0) { /* Ensure that fileno is within the CRT's valid range */ - _Py_BEGIN_SUPPRESS_IPH - fh = (HANDLE)_get_osfhandle(fileno); - _Py_END_SUPPRESS_IPH - if (fh==(HANDLE)-1) { - PyErr_SetFromErrno(PyExc_OSError); + fh = _Py_get_osfhandle(fileno); + if (fh == INVALID_HANDLE_VALUE) return NULL; - } + /* Win9x appears to need us seeked to zero */ lseek(fileno, 0, SEEK_SET); } @@ -1509,154 +1506,201 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } #endif /* MS_WINDOWS */ -static void -setint(PyObject *d, const char *name, long value) +static int +mmap_traverse(PyObject *module, visitproc visit, void *arg) { - PyObject *o = PyLong_FromLong(value); - if (o) { - PyDict_SetItemString(d, name, o); - Py_DECREF(o); - } + 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 struct PyModuleDef mmapmodule = { - PyModuleDef_HEAD_INIT, - "mmap", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; +static void +mmap_free(void *module) +{ + mmap_clear((PyObject *)module); +} -PyMODINIT_FUNC -PyInit_mmap(void) +static int +mmap_exec(PyObject *module) { - PyObject *dict, *module; + mmap_state *state = get_mmap_state(module); - if (PyType_Ready(&mmap_object_type) < 0) - return NULL; + 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) { + return -1; + } + if (PyModule_AddType(module, state->mmap_object_type) < 0) { + return -1; + } + +#define ADD_INT_MACRO(module, constant) \ + do { \ + if (PyModule_AddIntConstant(module, #constant, constant) < 0) { \ + return -1; \ + } \ + } while (0) - module = PyModule_Create(&mmapmodule); - if (module == NULL) - return NULL; - dict = PyModule_GetDict(module); - if (!dict) - return NULL; - PyDict_SetItemString(dict, "error", PyExc_OSError); - PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); #ifdef PROT_EXEC - setint(dict, "PROT_EXEC", PROT_EXEC); + ADD_INT_MACRO(module, PROT_EXEC); #endif #ifdef PROT_READ - setint(dict, "PROT_READ", PROT_READ); + ADD_INT_MACRO(module, PROT_READ); #endif #ifdef PROT_WRITE - setint(dict, "PROT_WRITE", PROT_WRITE); + ADD_INT_MACRO(module, PROT_WRITE); #endif #ifdef MAP_SHARED - setint(dict, "MAP_SHARED", MAP_SHARED); + ADD_INT_MACRO(module, MAP_SHARED); #endif #ifdef MAP_PRIVATE - setint(dict, "MAP_PRIVATE", MAP_PRIVATE); + ADD_INT_MACRO(module, MAP_PRIVATE); #endif #ifdef MAP_DENYWRITE - setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); + ADD_INT_MACRO(module, MAP_DENYWRITE); #endif #ifdef MAP_EXECUTABLE - setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); + ADD_INT_MACRO(module, MAP_EXECUTABLE); #endif #ifdef MAP_ANONYMOUS - setint(dict, "MAP_ANON", MAP_ANONYMOUS); - setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); + if (PyModule_AddIntConstant(module, "MAP_ANON", MAP_ANONYMOUS) < 0 ) { + return -1; + } + ADD_INT_MACRO(module, MAP_ANONYMOUS); #endif +#ifdef MAP_POPULATE + ADD_INT_MACRO(module, MAP_POPULATE); +#endif + if (PyModule_AddIntConstant(module, "PAGESIZE", (long)my_getpagesize()) < 0 ) { + return -1; + } - setint(dict, "PAGESIZE", (long)my_getpagesize()); - - setint(dict, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); + if (PyModule_AddIntConstant(module, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()) < 0 ) { + return -1; + } - setint(dict, "ACCESS_DEFAULT", ACCESS_DEFAULT); - setint(dict, "ACCESS_READ", ACCESS_READ); - setint(dict, "ACCESS_WRITE", ACCESS_WRITE); - setint(dict, "ACCESS_COPY", ACCESS_COPY); + ADD_INT_MACRO(module, ACCESS_DEFAULT); + ADD_INT_MACRO(module, ACCESS_READ); + ADD_INT_MACRO(module, ACCESS_WRITE); + ADD_INT_MACRO(module, ACCESS_COPY); #ifdef HAVE_MADVISE // Conventional advice values #ifdef MADV_NORMAL - setint(dict, "MADV_NORMAL", MADV_NORMAL); + ADD_INT_MACRO(module, MADV_NORMAL); #endif #ifdef MADV_RANDOM - setint(dict, "MADV_RANDOM", MADV_RANDOM); + ADD_INT_MACRO(module, MADV_RANDOM); #endif #ifdef MADV_SEQUENTIAL - setint(dict, "MADV_SEQUENTIAL", MADV_SEQUENTIAL); + ADD_INT_MACRO(module, MADV_SEQUENTIAL); #endif #ifdef MADV_WILLNEED - setint(dict, "MADV_WILLNEED", MADV_WILLNEED); + ADD_INT_MACRO(module, MADV_WILLNEED); #endif #ifdef MADV_DONTNEED - setint(dict, "MADV_DONTNEED", MADV_DONTNEED); + ADD_INT_MACRO(module, MADV_DONTNEED); #endif // Linux-specific advice values #ifdef MADV_REMOVE - setint(dict, "MADV_REMOVE", MADV_REMOVE); + ADD_INT_MACRO(module, MADV_REMOVE); #endif #ifdef MADV_DONTFORK - setint(dict, "MADV_DONTFORK", MADV_DONTFORK); + ADD_INT_MACRO(module, MADV_DONTFORK); #endif #ifdef MADV_DOFORK - setint(dict, "MADV_DOFORK", MADV_DOFORK); + ADD_INT_MACRO(module, MADV_DOFORK); #endif #ifdef MADV_HWPOISON - setint(dict, "MADV_HWPOISON", MADV_HWPOISON); + ADD_INT_MACRO(module, MADV_HWPOISON); #endif #ifdef MADV_MERGEABLE - setint(dict, "MADV_MERGEABLE", MADV_MERGEABLE); + ADD_INT_MACRO(module, MADV_MERGEABLE); #endif #ifdef MADV_UNMERGEABLE - setint(dict, "MADV_UNMERGEABLE", MADV_UNMERGEABLE); + ADD_INT_MACRO(module, MADV_UNMERGEABLE); #endif #ifdef MADV_SOFT_OFFLINE - setint(dict, "MADV_SOFT_OFFLINE", MADV_SOFT_OFFLINE); + ADD_INT_MACRO(module, MADV_SOFT_OFFLINE); #endif #ifdef MADV_HUGEPAGE - setint(dict, "MADV_HUGEPAGE", MADV_HUGEPAGE); + ADD_INT_MACRO(module, MADV_HUGEPAGE); #endif #ifdef MADV_NOHUGEPAGE - setint(dict, "MADV_NOHUGEPAGE", MADV_NOHUGEPAGE); + ADD_INT_MACRO(module, MADV_NOHUGEPAGE); #endif #ifdef MADV_DONTDUMP - setint(dict, "MADV_DONTDUMP", MADV_DONTDUMP); + ADD_INT_MACRO(module, MADV_DONTDUMP); #endif #ifdef MADV_DODUMP - setint(dict, "MADV_DODUMP", MADV_DODUMP); + ADD_INT_MACRO(module, MADV_DODUMP); #endif #ifdef MADV_FREE // (Also present on FreeBSD and macOS.) - setint(dict, "MADV_FREE", MADV_FREE); + ADD_INT_MACRO(module, MADV_FREE); #endif // FreeBSD-specific #ifdef MADV_NOSYNC - setint(dict, "MADV_NOSYNC", MADV_NOSYNC); + ADD_INT_MACRO(module, MADV_NOSYNC); #endif #ifdef MADV_AUTOSYNC - setint(dict, "MADV_AUTOSYNC", MADV_AUTOSYNC); + ADD_INT_MACRO(module, MADV_AUTOSYNC); #endif #ifdef MADV_NOCORE - setint(dict, "MADV_NOCORE", MADV_NOCORE); + ADD_INT_MACRO(module, MADV_NOCORE); #endif #ifdef MADV_CORE - setint(dict, "MADV_CORE", MADV_CORE); + ADD_INT_MACRO(module, MADV_CORE); #endif #ifdef MADV_PROTECT - setint(dict, "MADV_PROTECT", MADV_PROTECT); + ADD_INT_MACRO(module, MADV_PROTECT); +#endif + + // Darwin-specific +#ifdef MADV_FREE_REUSABLE // (As MADV_FREE but reclaims more faithful for task_info/Activity Monitor...) + ADD_INT_MACRO(module, MADV_FREE_REUSABLE); +#endif +#ifdef MADV_FREE_REUSE // (Reuse pages previously tagged as reusable) + ADD_INT_MACRO(module, MADV_FREE_REUSE); #endif #endif // HAVE_MADVISE + return 0; +} - return module; +static PyModuleDef_Slot mmap_slots[] = { + {Py_mod_exec, mmap_exec}, + {0, NULL} +}; + +static struct PyModuleDef mmapmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "mmap", + .m_size = sizeof(mmap_state), + .m_slots = mmap_slots, + .m_traverse = mmap_traverse, + .m_clear = mmap_clear, + .m_free = mmap_free, +}; + +PyMODINIT_FUNC +PyInit_mmap(void) +{ + return PyModuleDef_Init(&mmapmodule); } diff --git a/contrib/tools/python3/src/Modules/overlapped.c b/contrib/tools/python3/src/Modules/overlapped.c index cd7869fa8aa..7c4570896bc 100644 --- a/contrib/tools/python3/src/Modules/overlapped.c +++ b/contrib/tools/python3/src/Modules/overlapped.c @@ -37,6 +37,36 @@ #define T_HANDLE T_POINTER +/*[python input] +class OVERLAPPED_converter(CConverter): + type = 'OVERLAPPED *' + format_unit = '"F_POINTER"' + +class HANDLE_converter(CConverter): + type = 'HANDLE' + format_unit = '"F_HANDLE"' + +class ULONG_PTR_converter(CConverter): + type = 'ULONG_PTR' + format_unit = '"F_ULONG_PTR"' + +class DWORD_converter(CConverter): + type = 'DWORD' + format_unit = 'k' + +class BOOL_converter(CConverter): + type = 'BOOL' + format_unit = 'i' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=83bb8c2c2514f2a8]*/ + +/*[clinic input] +module _overlapped +class _overlapped.Overlapped "OverlappedObject *" "&OverlappedType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92e5a799db35b96c]*/ + + enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE, TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE, TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM, @@ -70,6 +100,19 @@ 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; +} + + /* * Map Windows error codes to subclasses of OSError */ @@ -150,25 +193,27 @@ initialize_function_pointers(void) * Completion port stuff */ -PyDoc_STRVAR( - CreateIoCompletionPort_doc, - "CreateIoCompletionPort(handle, port, key, concurrency) -> port\n\n" - "Create a completion port or register a handle with a port."); +/*[clinic input] +_overlapped.CreateIoCompletionPort + + handle as FileHandle: HANDLE + port as ExistingCompletionPort: HANDLE + key as CompletionKey: ULONG_PTR + concurrency as NumberOfConcurrentThreads: DWORD + / + +Create a completion port or register a handle with a port. +[clinic start generated code]*/ static PyObject * -overlapped_CreateIoCompletionPort(PyObject *self, PyObject *args) +_overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle, + HANDLE ExistingCompletionPort, + ULONG_PTR CompletionKey, + DWORD NumberOfConcurrentThreads) +/*[clinic end generated code: output=24ede2b0f05e5433 input=847bae4d0efe1976]*/ { - HANDLE FileHandle; - HANDLE ExistingCompletionPort; - ULONG_PTR CompletionKey; - DWORD NumberOfConcurrentThreads; HANDLE ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_ULONG_PTR F_DWORD, - &FileHandle, &ExistingCompletionPort, &CompletionKey, - &NumberOfConcurrentThreads)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = CreateIoCompletionPort(FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads); @@ -179,26 +224,30 @@ overlapped_CreateIoCompletionPort(PyObject *self, PyObject *args) return Py_BuildValue(F_HANDLE, ret); } -PyDoc_STRVAR( - GetQueuedCompletionStatus_doc, - "GetQueuedCompletionStatus(port, msecs) -> (err, bytes, key, address)\n\n" - "Get a message from completion port. Wait for up to msecs milliseconds."); +/*[clinic input] +_overlapped.GetQueuedCompletionStatus + + port as CompletionPort: HANDLE + msecs as Milliseconds: DWORD + / + +Get a message from completion port. + +Wait for up to msecs milliseconds. +[clinic start generated code]*/ static PyObject * -overlapped_GetQueuedCompletionStatus(PyObject *self, PyObject *args) +_overlapped_GetQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD Milliseconds) +/*[clinic end generated code: output=68314171628dddb7 input=94a042d14c4f6410]*/ { - HANDLE CompletionPort = NULL; DWORD NumberOfBytes = 0; ULONG_PTR CompletionKey = 0; OVERLAPPED *Overlapped = NULL; - DWORD Milliseconds; DWORD err; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, - &CompletionPort, &Milliseconds)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes, &CompletionKey, &Overlapped, Milliseconds); @@ -215,25 +264,28 @@ overlapped_GetQueuedCompletionStatus(PyObject *self, PyObject *args) err, NumberOfBytes, CompletionKey, Overlapped); } -PyDoc_STRVAR( - PostQueuedCompletionStatus_doc, - "PostQueuedCompletionStatus(port, bytes, key, address) -> None\n\n" - "Post a message to completion port."); +/*[clinic input] +_overlapped.PostQueuedCompletionStatus + + port as CompletionPort: HANDLE + bytes as NumberOfBytes: DWORD + key as CompletionKey: ULONG_PTR + address as Overlapped: OVERLAPPED + / + +Post a message to completion port. +[clinic start generated code]*/ static PyObject * -overlapped_PostQueuedCompletionStatus(PyObject *self, PyObject *args) +_overlapped_PostQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD NumberOfBytes, + ULONG_PTR CompletionKey, + OVERLAPPED *Overlapped) +/*[clinic end generated code: output=93e73f2933a43e9e input=e936202d87937aca]*/ { - HANDLE CompletionPort; - DWORD NumberOfBytes; - ULONG_PTR CompletionKey; - OVERLAPPED *Overlapped; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD F_ULONG_PTR F_POINTER, - &CompletionPort, &NumberOfBytes, &CompletionKey, - &Overlapped)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = PostQueuedCompletionStatus(CompletionPort, NumberOfBytes, CompletionKey, Overlapped); @@ -264,26 +316,27 @@ PostToQueueCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) PyMem_RawFree(p); } -PyDoc_STRVAR( - RegisterWaitWithQueue_doc, - "RegisterWaitWithQueue(Object, CompletionPort, Overlapped, Timeout)\n" - " -> WaitHandle\n\n" - "Register wait for Object; when complete CompletionPort is notified.\n"); +/*[clinic input] +_overlapped.RegisterWaitWithQueue + + Object: HANDLE + CompletionPort: HANDLE + Overlapped: OVERLAPPED + Timeout as Milliseconds: DWORD + / + +Register wait for Object; when complete CompletionPort is notified. +[clinic start generated code]*/ static PyObject * -overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args) +_overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, + HANDLE CompletionPort, + OVERLAPPED *Overlapped, + DWORD Milliseconds) +/*[clinic end generated code: output=c2ace732e447fe45 input=2dd4efee44abe8ee]*/ { HANDLE NewWaitObject; - HANDLE Object; - ULONG Milliseconds; - struct PostCallbackData data, *pdata; - - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_POINTER F_DWORD, - &Object, - &data.CompletionPort, - &data.Overlapped, - &Milliseconds)) - return NULL; + struct PostCallbackData data = {CompletionPort, Overlapped}, *pdata; /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since PostToQueueCallback() will call PyMem_Free() from a new C thread @@ -305,20 +358,21 @@ overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args) return Py_BuildValue(F_HANDLE, NewWaitObject); } -PyDoc_STRVAR( - UnregisterWait_doc, - "UnregisterWait(WaitHandle) -> None\n\n" - "Unregister wait handle.\n"); +/*[clinic input] +_overlapped.UnregisterWait + + WaitHandle: HANDLE + / + +Unregister wait handle. +[clinic start generated code]*/ static PyObject * -overlapped_UnregisterWait(PyObject *self, PyObject *args) +_overlapped_UnregisterWait_impl(PyObject *module, HANDLE WaitHandle) +/*[clinic end generated code: output=ec90cd955a9a617d input=a56709544cb2df0f]*/ { - HANDLE WaitHandle; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE, &WaitHandle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = UnregisterWait(WaitHandle); Py_END_ALLOW_THREADS @@ -328,20 +382,23 @@ overlapped_UnregisterWait(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR( - UnregisterWaitEx_doc, - "UnregisterWaitEx(WaitHandle, Event) -> None\n\n" - "Unregister wait handle.\n"); +/*[clinic input] +_overlapped.UnregisterWaitEx + + WaitHandle: HANDLE + Event: HANDLE + / + +Unregister wait handle. +[clinic start generated code]*/ static PyObject * -overlapped_UnregisterWaitEx(PyObject *self, PyObject *args) +_overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle, + HANDLE Event) +/*[clinic end generated code: output=2e3d84c1d5f65b92 input=953cddc1de50fab9]*/ { - HANDLE WaitHandle, Event; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &WaitHandle, &Event)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = UnregisterWaitEx(WaitHandle, Event); Py_END_ALLOW_THREADS @@ -355,26 +412,28 @@ overlapped_UnregisterWaitEx(PyObject *self, PyObject *args) * Event functions -- currently only used by tests */ -PyDoc_STRVAR( - CreateEvent_doc, - "CreateEvent(EventAttributes, ManualReset, InitialState, Name)" - " -> Handle\n\n" - "Create an event. EventAttributes must be None.\n"); +/*[clinic input] +_overlapped.CreateEvent + + EventAttributes: object + ManualReset: BOOL + InitialState: BOOL + Name: Py_UNICODE(accept={str, NoneType}) + / + +Create an event. + +EventAttributes must be None. +[clinic start generated code]*/ static PyObject * -overlapped_CreateEvent(PyObject *self, PyObject *args) +_overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes, + BOOL ManualReset, BOOL InitialState, + const Py_UNICODE *Name) +/*[clinic end generated code: output=8e04f0916c17b13d input=dbc36ae14375ba24]*/ { - PyObject *EventAttributes; - BOOL ManualReset; - BOOL InitialState; - Py_UNICODE *Name; HANDLE Event; - if (!PyArg_ParseTuple(args, "O" F_BOOL F_BOOL "Z", - &EventAttributes, &ManualReset, - &InitialState, &Name)) - return NULL; - if (EventAttributes != Py_None) { PyErr_SetString(PyExc_ValueError, "EventAttributes must be None"); return NULL; @@ -389,20 +448,21 @@ overlapped_CreateEvent(PyObject *self, PyObject *args) return Py_BuildValue(F_HANDLE, Event); } -PyDoc_STRVAR( - SetEvent_doc, - "SetEvent(Handle) -> None\n\n" - "Set event.\n"); +/*[clinic input] +_overlapped.SetEvent + + Handle: HANDLE + / + +Set event. +[clinic start generated code]*/ static PyObject * -overlapped_SetEvent(PyObject *self, PyObject *args) +_overlapped_SetEvent_impl(PyObject *module, HANDLE Handle) +/*[clinic end generated code: output=5b8d974216b0e569 input=d8b0d26eb7391e80]*/ { - HANDLE Handle; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = SetEvent(Handle); Py_END_ALLOW_THREADS @@ -412,20 +472,21 @@ overlapped_SetEvent(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR( - ResetEvent_doc, - "ResetEvent(Handle) -> None\n\n" - "Reset event.\n"); +/*[clinic input] +_overlapped.ResetEvent + + Handle: HANDLE + / + +Reset event. +[clinic start generated code]*/ static PyObject * -overlapped_ResetEvent(PyObject *self, PyObject *args) +_overlapped_ResetEvent_impl(PyObject *module, HANDLE Handle) +/*[clinic end generated code: output=066537a8405cddb2 input=d4e089c9ba84ff2f]*/ { - HANDLE Handle; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = ResetEvent(Handle); Py_END_ALLOW_THREADS @@ -439,36 +500,40 @@ overlapped_ResetEvent(PyObject *self, PyObject *args) * Bind socket handle to local port without doing slow getaddrinfo() */ -PyDoc_STRVAR( - BindLocal_doc, - "BindLocal(handle, family) -> None\n\n" - "Bind a socket handle to an arbitrary local port.\n" - "family should AF_INET or AF_INET6.\n"); +/*[clinic input] +_overlapped.BindLocal + + handle as Socket: HANDLE + family as Family: int + / + +Bind a socket handle to an arbitrary local port. + +family should be AF_INET or AF_INET6. +[clinic start generated code]*/ static PyObject * -overlapped_BindLocal(PyObject *self, PyObject *args) +_overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family) +/*[clinic end generated code: output=edb93862697aed9c input=a0e7b5c2f541170c]*/ { - SOCKET Socket; - int Family; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE "i", &Socket, &Family)) - return NULL; - if (Family == AF_INET) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.S_un.S_addr = INADDR_ANY; - ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; + ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr)) + != SOCKET_ERROR; } else if (Family == AF_INET6) { struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_port = 0; addr.sin6_addr = in6addr_any; - ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; + ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr)) + != SOCKET_ERROR; } else { PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4"); return NULL; @@ -483,21 +548,23 @@ overlapped_BindLocal(PyObject *self, PyObject *args) * Windows equivalent of os.strerror() -- compare _ctypes/callproc.c */ -PyDoc_STRVAR( - FormatMessage_doc, - "FormatMessage(error_code) -> error_message\n\n" - "Return error message for an error code."); +/*[clinic input] +_overlapped.FormatMessage + + error_code as code: DWORD + / + +Return error message for an error code. +[clinic start generated code]*/ static PyObject * -overlapped_FormatMessage(PyObject *ignore, PyObject *args) +_overlapped_FormatMessage_impl(PyObject *module, DWORD code) +/*[clinic end generated code: output=02c964ff22407c6b input=644bb5b80326179e]*/ { - DWORD code, n; + DWORD n; WCHAR *lpMsgBuf; PyObject *res; - if (!PyArg_ParseTuple(args, F_DWORD, &code)) - return NULL; - n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -537,19 +604,20 @@ mark_as_completed(OVERLAPPED *ov) * for overlapped I/O */ -PyDoc_STRVAR( - Overlapped_doc, - "Overlapped object"); +/*[clinic input] +@classmethod +_overlapped.Overlapped.__new__ + + event: HANDLE(c_default='INVALID_HANDLE_VALUE') = _overlapped.INVALID_HANDLE_VALUE + +OVERLAPPED structure wrapper. +[clinic start generated code]*/ static PyObject * -Overlapped_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +_overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event) +/*[clinic end generated code: output=6da60504a18eb421 input=26b8a7429e629e95]*/ { OverlappedObject *self; - HANDLE event = INVALID_HANDLE_VALUE; - static char *kwlist[] = {"event", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|" F_HANDLE, kwlist, &event)) - return NULL; if (event == INVALID_HANDLE_VALUE) { event = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -651,8 +719,11 @@ Overlapped_dealloc(OverlappedObject *self) } Overlapped_clear(self); - PyObject_Del(self); SetLastError(olderr); + + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); } @@ -719,13 +790,15 @@ unparse_address(LPSOCKADDR Address, DWORD Length) } } -PyDoc_STRVAR( - Overlapped_cancel_doc, - "cancel() -> None\n\n" - "Cancel overlapped operation"); +/*[clinic input] +_overlapped.Overlapped.cancel + +Cancel overlapped operation. +[clinic start generated code]*/ static PyObject * -Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) +_overlapped_Overlapped_cancel_impl(OverlappedObject *self) +/*[clinic end generated code: output=54ad7aeece89901c input=80eb67c7b57dbcf1]*/ { BOOL ret = TRUE; @@ -748,25 +821,27 @@ Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -PyDoc_STRVAR( - Overlapped_getresult_doc, - "getresult(wait=False) -> result\n\n" - "Retrieve result of operation. If wait is true then it blocks\n" - "until the operation is finished. If wait is false and the\n" - "operation is still pending then an error is raised."); +/*[clinic input] +_overlapped.Overlapped.getresult + + wait: BOOL(c_default='FALSE') = False + / + +Retrieve result of operation. + +If wait is true then it blocks until the operation is finished. If wait +is false and the operation is still pending then an error is raised. +[clinic start generated code]*/ static PyObject * -Overlapped_getresult(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) +/*[clinic end generated code: output=8c9bd04d08994f6c input=aa5b03e9897ca074]*/ { - BOOL wait = FALSE; DWORD transferred = 0; BOOL ret; DWORD err; PyObject *addr; - if (!PyArg_ParseTuple(args, "|" F_BOOL, &wait)) - return NULL; - if (self->type == TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation not yet attempted"); return NULL; @@ -878,21 +953,23 @@ do_ReadFile(OverlappedObject *self, HANDLE handle, } } -PyDoc_STRVAR( - Overlapped_ReadFile_doc, - "ReadFile(handle, size) -> Overlapped[message]\n\n" - "Start overlapped read"); +/*[clinic input] +_overlapped.Overlapped.ReadFile + + handle: HANDLE + size: DWORD + / + +Start overlapped read. +[clinic start generated code]*/ static PyObject * -Overlapped_ReadFile(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, + DWORD size) +/*[clinic end generated code: output=4c8557e16941e4ae input=98c495baa0342425]*/ { - HANDLE handle; - DWORD size; PyObject *buf; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &handle, &size)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -912,20 +989,21 @@ Overlapped_ReadFile(OverlappedObject *self, PyObject *args) return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size); } -PyDoc_STRVAR( - Overlapped_ReadFileInto_doc, - "ReadFileInto(handle, buf) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.ReadFileInto -static PyObject * -Overlapped_ReadFileInto(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; + handle: HANDLE + buf as bufobj: object + / - if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) - return NULL; +Start overlapped receive. +[clinic start generated code]*/ +static PyObject * +_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj) +/*[clinic end generated code: output=1e9e712e742e5b2a input=16f6cc268d1d0387]*/ +{ if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -981,23 +1059,24 @@ do_WSARecv(OverlappedObject *self, HANDLE handle, } } -PyDoc_STRVAR( - Overlapped_WSARecv_doc, - "RecvFile(handle, size, flags) -> Overlapped[message]\n\n" - "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.WSARecv + + handle: HANDLE + size: DWORD + flags: DWORD = 0 + / + +Start overlapped receive. +[clinic start generated code]*/ static PyObject * -Overlapped_WSARecv(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, + DWORD size, DWORD flags) +/*[clinic end generated code: output=3a5e9c61ff040906 input=8c04e506cc3d741a]*/ { - HANDLE handle; - DWORD size; - DWORD flags = 0; PyObject *buf; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD "|" F_DWORD, - &handle, &size, &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1017,22 +1096,23 @@ Overlapped_WSARecv(OverlappedObject *self, PyObject *args) return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags); } -PyDoc_STRVAR( - Overlapped_WSARecvInto_doc, - "WSARecvInto(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.WSARecvInto -static PyObject * -Overlapped_WSARecvInto(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; - DWORD flags; + handle: HANDLE + buf as bufobj: object + flags: DWORD + / - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, - &handle, &bufobj, &flags)) - return NULL; +Start overlapped receive. +[clinic start generated code]*/ +static PyObject * +_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj, + DWORD flags) +/*[clinic end generated code: output=9a438abc436fe87c input=4f87c38fc381d525]*/ +{ if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1056,23 +1136,25 @@ Overlapped_WSARecvInto(OverlappedObject *self, PyObject *args) (DWORD)self->user_buffer.len, flags); } -PyDoc_STRVAR( - Overlapped_WriteFile_doc, - "WriteFile(handle, buf) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped write"); +/*[clinic input] +_overlapped.Overlapped.WriteFile + + handle: HANDLE + buf as bufobj: object + / + +Start overlapped write. +[clinic start generated code]*/ static PyObject * -Overlapped_WriteFile(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj) +/*[clinic end generated code: output=c376230b6120d877 input=b8d9a7608d8a1e72]*/ { - HANDLE handle; - PyObject *bufobj; DWORD written; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1109,26 +1191,27 @@ Overlapped_WriteFile(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_WSASend_doc, - "WSASend(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped send"); +/*[clinic input] +_overlapped.Overlapped.WSASend + + handle: HANDLE + buf as bufobj: object + flags: DWORD + / + +Start overlapped send. +[clinic start generated code]*/ static PyObject * -Overlapped_WSASend(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags) +/*[clinic end generated code: output=316031c7467040cc input=932e7cba6d18f708]*/ { - HANDLE handle; - PyObject *bufobj; - DWORD flags; DWORD written; WSABUF wsabuf; int ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, - &handle, &bufobj, &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1166,26 +1249,28 @@ Overlapped_WSASend(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_AcceptEx_doc, - "AcceptEx(listen_handle, accept_handle) -> Overlapped[address_as_bytes]\n\n" - "Start overlapped wait for client to connect"); +/*[clinic input] +_overlapped.Overlapped.AcceptEx + + listen_handle as ListenSocket: HANDLE + accept_handle as AcceptSocket: HANDLE + / + +Start overlapped wait for client to connect. +[clinic start generated code]*/ static PyObject * -Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self, + HANDLE ListenSocket, + HANDLE AcceptSocket) +/*[clinic end generated code: output=9a7381d4232af889 input=b83473224fc3a1c5]*/ { - SOCKET ListenSocket; - SOCKET AcceptSocket; DWORD BytesReceived; DWORD size; PyObject *buf; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, - &ListenSocket, &AcceptSocket)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1197,12 +1282,13 @@ Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) return NULL; self->type = TYPE_ACCEPT; - self->handle = (HANDLE)ListenSocket; + self->handle = ListenSocket; self->allocated_buffer = buf; Py_BEGIN_ALLOW_THREADS - ret = Py_AcceptEx(ListenSocket, AcceptSocket, PyBytes_AS_STRING(buf), - 0, size, size, &BytesReceived, &self->overlapped); + ret = Py_AcceptEx((SOCKET)ListenSocket, (SOCKET)AcceptSocket, + PyBytes_AS_STRING(buf), 0, size, size, &BytesReceived, + &self->overlapped); Py_END_ALLOW_THREADS self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); @@ -1220,6 +1306,7 @@ Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) static int parse_address(PyObject *obj, SOCKADDR *Address, int Length) { + PyObject *Host_obj; Py_UNICODE *Host; unsigned short Port; unsigned long FlowInfo; @@ -1227,57 +1314,92 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) memset(Address, 0, Length); - if (PyArg_ParseTuple(obj, "uH", &Host, &Port)) - { + switch (PyTuple_GET_SIZE(obj)) { + case 2: { + 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; + } Address->sa_family = AF_INET; if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) { SetFromWindowsErr(WSAGetLastError()); - return -1; + Length = -1; } - ((SOCKADDR_IN*)Address)->sin_port = htons(Port); + else { + ((SOCKADDR_IN*)Address)->sin_port = htons(Port); + } +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(Host); +#endif /* USE_UNICODE_WCHAR_CACHE */ return Length; } - else if (PyArg_ParseTuple(obj, - "uHkk;ConnectEx(): illegal address_as_bytes " - "argument", &Host, &Port, &FlowInfo, &ScopeId)) - { - PyErr_Clear(); + case 4: { + if (!PyArg_ParseTuple(obj, + "UHkk;ConnectEx(): illegal address_as_bytes argument", + &Host_obj, &Port, &FlowInfo, &ScopeId)) + { + 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; + } Address->sa_family = AF_INET6; if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) { SetFromWindowsErr(WSAGetLastError()); - return -1; + Length = -1; + } + else { + ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port); + ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo; + ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId; } - ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port); - ((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; } - - return -1; + default: + PyErr_SetString(PyExc_ValueError, "illegal address_as_bytes argument"); + return -1; + } } -PyDoc_STRVAR( - Overlapped_ConnectEx_doc, - "ConnectEx(client_handle, address_as_bytes) -> Overlapped[None]\n\n" - "Start overlapped connect. client_handle should be unbound."); +/*[clinic input] +_overlapped.Overlapped.ConnectEx + + client_handle as ConnectSocket: HANDLE + address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type') + / + +Start overlapped connect. + +client_handle should be unbound. +[clinic start generated code]*/ static PyObject * -Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self, + HANDLE ConnectSocket, + PyObject *AddressObj) +/*[clinic end generated code: output=5aebbbdb4f022833 input=d6bbd2d84b156fc1]*/ { - SOCKET ConnectSocket; - PyObject *AddressObj; char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; int Length; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O!:ConnectEx", - &ConnectSocket, &PyTuple_Type, &AddressObj)) - { - return NULL; - } - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1289,10 +1411,10 @@ Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) return NULL; self->type = TYPE_CONNECT; - self->handle = (HANDLE)ConnectSocket; + self->handle = ConnectSocket; Py_BEGIN_ALLOW_THREADS - ret = Py_ConnectEx(ConnectSocket, Address, Length, + ret = Py_ConnectEx((SOCKET)ConnectSocket, Address, Length, NULL, 0, NULL, &self->overlapped); Py_END_ALLOW_THREADS @@ -1307,32 +1429,33 @@ Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_DisconnectEx_doc, - "DisconnectEx(handle, flags) -> Overlapped[None]\n\n" - "Start overlapped connect. client_handle should be unbound."); +/*[clinic input] +_overlapped.Overlapped.DisconnectEx + + handle as Socket: HANDLE + flags: DWORD + / + +[clinic start generated code]*/ static PyObject * -Overlapped_DisconnectEx(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self, + HANDLE Socket, DWORD flags) +/*[clinic end generated code: output=8d64ddb8c93c2126 input=680845cdcdf820eb]*/ { - SOCKET Socket; - DWORD flags; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &Socket, &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } self->type = TYPE_DISCONNECT; - self->handle = (HANDLE)Socket; + self->handle = Socket; Py_BEGIN_ALLOW_THREADS - ret = Py_DisconnectEx(Socket, &self->overlapped, flags, 0); + ret = Py_DisconnectEx((SOCKET)Socket, &self->overlapped, flags, 0); Py_END_ALLOW_THREADS self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); @@ -1346,48 +1469,45 @@ Overlapped_DisconnectEx(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_TransmitFile_doc, - "TransmitFile(socket, file, offset, offset_high, " - "count_to_write, count_per_send, flags) " - "-> Overlapped[None]\n\n" - "Transmit file data over a connected socket."); +/*[clinic input] +_overlapped.Overlapped.TransmitFile + + socket as Socket: HANDLE + file as File: HANDLE + offset: DWORD + offset_high: DWORD + count_to_write: DWORD + count_per_send: DWORD + flags: DWORD + / + +Transmit file data over a connected socket. +[clinic start generated code]*/ static PyObject * -Overlapped_TransmitFile(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self, + HANDLE Socket, HANDLE File, + DWORD offset, DWORD offset_high, + DWORD count_to_write, + DWORD count_per_send, DWORD flags) +/*[clinic end generated code: output=03f3ca5512e678fd input=7e6f97b391f60e8c]*/ { - SOCKET Socket; - HANDLE File; - DWORD offset; - DWORD offset_high; - DWORD count_to_write; - DWORD count_per_send; - DWORD flags; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, - F_HANDLE F_HANDLE F_DWORD F_DWORD - F_DWORD F_DWORD F_DWORD, - &Socket, &File, &offset, &offset_high, - &count_to_write, &count_per_send, - &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } self->type = TYPE_TRANSMIT_FILE; - self->handle = (HANDLE)Socket; + self->handle = Socket; self->overlapped.Offset = offset; self->overlapped.OffsetHigh = offset_high; Py_BEGIN_ALLOW_THREADS - ret = Py_TransmitFile(Socket, File, count_to_write, count_per_send, - &self->overlapped, - NULL, flags); + ret = Py_TransmitFile((SOCKET)Socket, File, count_to_write, + count_per_send, &self->overlapped, NULL, flags); Py_END_ALLOW_THREADS self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); @@ -1401,21 +1521,23 @@ Overlapped_TransmitFile(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_ConnectNamedPipe_doc, - "ConnectNamedPipe(handle) -> Overlapped[None]\n\n" - "Start overlapped wait for a client to connect."); +/*[clinic input] +_overlapped.Overlapped.ConnectNamedPipe + + handle as Pipe: HANDLE + / + +Start overlapped wait for a client to connect. +[clinic start generated code]*/ static PyObject * -Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self, + HANDLE Pipe) +/*[clinic end generated code: output=3e69adfe55818abe input=8b0d4cef8a72f7bc]*/ { - HANDLE Pipe; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE, &Pipe)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1442,25 +1564,22 @@ Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - ConnectPipe_doc, - "ConnectPipe(addr) -> pipe_handle\n\n" - "Connect to the pipe for asynchronous I/O (overlapped)."); +/*[clinic input] +_overlapped.Overlapped.ConnectPipe + + addr as Address: Py_UNICODE + / + +Connect to the pipe for asynchronous I/O (overlapped). +[clinic start generated code]*/ static PyObject * -overlapped_ConnectPipe(PyObject *self, PyObject *args) +_overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self, + const Py_UNICODE *Address) +/*[clinic end generated code: output=3cc9661667d459d4 input=167c06a274efcefc]*/ { - PyObject *AddressObj; - wchar_t *Address; HANDLE PipeHandle; - if (!PyArg_ParseTuple(args, "U", &AddressObj)) - return NULL; - - Address = PyUnicode_AsWideCharString(AddressObj, NULL); - if (Address == NULL) - return NULL; - Py_BEGIN_ALLOW_THREADS PipeHandle = CreateFileW(Address, GENERIC_READ | GENERIC_WRITE, @@ -1468,7 +1587,6 @@ overlapped_ConnectPipe(PyObject *self, PyObject *args) FILE_FLAG_OVERLAPPED, NULL); Py_END_ALLOW_THREADS - PyMem_Free(Address); if (PipeHandle == INVALID_HANDLE_VALUE) return SetFromWindowsErr(0); return Py_BuildValue(F_HANDLE, PipeHandle); @@ -1503,41 +1621,39 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) } break; case TYPE_READ_FROM: - if(self->read_from.result) { - Py_VISIT(self->read_from.result); - } - if(self->read_from.allocated_buffer) { - Py_VISIT(self->read_from.allocated_buffer); - } + Py_VISIT(self->read_from.result); + Py_VISIT(self->read_from.allocated_buffer); } return 0; } // UDP functions -PyDoc_STRVAR( - WSAConnect_doc, - "WSAConnect(client_handle, address_as_bytes) -> Overlapped[None]\n\n" - "Bind a remote address to a connectionless (UDP) socket"); - /* * Note: WSAConnect does not support Overlapped I/O so this function should * _only_ be used for connectionless sockets (UDP). */ + +/*[clinic input] +_overlapped.WSAConnect + + client_handle as ConnectSocket: HANDLE + address_as_bytes as AddressObj: object + / + +Bind a remote address to a connectionless (UDP) socket. +[clinic start generated code]*/ + static PyObject * -overlapped_WSAConnect(PyObject *self, PyObject *args) +_overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, + PyObject *AddressObj) +/*[clinic end generated code: output=ea0b4391e94dad63 input=169f8075e9ae7fa4]*/ { - SOCKET ConnectSocket; - PyObject *AddressObj; char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; int Length; int err; - if (!PyArg_ParseTuple(args, F_HANDLE "O", &ConnectSocket, &AddressObj)) { - return NULL; - } - Length = sizeof(AddressBuf); Length = parse_address(AddressObj, Address, Length); if (Length < 0) { @@ -1547,7 +1663,7 @@ overlapped_WSAConnect(PyObject *self, PyObject *args) Py_BEGIN_ALLOW_THREADS // WSAConnect does not support overlapped I/O so this call will // successfully complete immediately. - err = WSAConnect(ConnectSocket, Address, Length, + err = WSAConnect((SOCKET)ConnectSocket, Address, Length, NULL, NULL, NULL, NULL); Py_END_ALLOW_THREADS @@ -1559,19 +1675,24 @@ overlapped_WSAConnect(PyObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_WSASendTo_doc, - "WSASendTo(handle, buf, flags, address_as_bytes) -> " - "Overlapped[bytes_transferred]\n\n" - "Start overlapped sendto over a connectionless (UDP) socket"); +/*[clinic input] +_overlapped.Overlapped.WSASendTo + + handle: HANDLE + buf as bufobj: object + flags: DWORD + address_as_bytes as AddressObj: object + / + +Start overlapped sendto over a connectionless (UDP) socket. +[clinic start generated code]*/ static PyObject * -Overlapped_WSASendTo(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags, + PyObject *AddressObj) +/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/ { - HANDLE handle; - PyObject *bufobj; - DWORD flags; - PyObject *AddressObj; char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; int AddressLength; @@ -1580,12 +1701,6 @@ Overlapped_WSASendTo(OverlappedObject *self, PyObject *args) int ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD "O", - &handle, &bufobj, &flags, &AddressObj)) - { - return NULL; - } - // Parse the "to" address AddressLength = sizeof(AddressBuf); AddressLength = parse_address(AddressObj, Address, AddressLength); @@ -1640,24 +1755,29 @@ PyDoc_STRVAR( "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n" "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.WSARecvFrom + + handle: HANDLE + size: DWORD + flags: DWORD = 0 + / + +Start overlapped receive. +[clinic start generated code]*/ + static PyObject * -Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, + HANDLE handle, DWORD size, + DWORD flags) +/*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/ { - HANDLE handle; - DWORD size; - DWORD flags = 0; DWORD nread; PyObject *buf; WSABUF wsabuf; int ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD "|" F_DWORD, - &handle, &size, &flags)) - { - return NULL; - } - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1703,38 +1823,24 @@ Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *args) } } +#include "clinic/overlapped.c.h" static PyMethodDef Overlapped_methods[] = { - {"getresult", (PyCFunction) Overlapped_getresult, - METH_VARARGS, Overlapped_getresult_doc}, - {"cancel", (PyCFunction) Overlapped_cancel, - METH_NOARGS, Overlapped_cancel_doc}, - {"ReadFile", (PyCFunction) Overlapped_ReadFile, - METH_VARARGS, Overlapped_ReadFile_doc}, - {"ReadFileInto", (PyCFunction) Overlapped_ReadFileInto, - METH_VARARGS, Overlapped_ReadFileInto_doc}, - {"WSARecv", (PyCFunction) Overlapped_WSARecv, - METH_VARARGS, Overlapped_WSARecv_doc}, - {"WSARecvInto", (PyCFunction) Overlapped_WSARecvInto, - METH_VARARGS, Overlapped_WSARecvInto_doc}, - {"WriteFile", (PyCFunction) Overlapped_WriteFile, - METH_VARARGS, Overlapped_WriteFile_doc}, - {"WSASend", (PyCFunction) Overlapped_WSASend, - METH_VARARGS, Overlapped_WSASend_doc}, - {"AcceptEx", (PyCFunction) Overlapped_AcceptEx, - METH_VARARGS, Overlapped_AcceptEx_doc}, - {"ConnectEx", (PyCFunction) Overlapped_ConnectEx, - METH_VARARGS, Overlapped_ConnectEx_doc}, - {"DisconnectEx", (PyCFunction) Overlapped_DisconnectEx, - METH_VARARGS, Overlapped_DisconnectEx_doc}, - {"TransmitFile", (PyCFunction) Overlapped_TransmitFile, - METH_VARARGS, Overlapped_TransmitFile_doc}, - {"ConnectNamedPipe", (PyCFunction) Overlapped_ConnectNamedPipe, - METH_VARARGS, Overlapped_ConnectNamedPipe_doc}, - {"WSARecvFrom", (PyCFunction) Overlapped_WSARecvFrom, - METH_VARARGS, Overlapped_WSARecvFrom_doc }, - {"WSASendTo", (PyCFunction) Overlapped_WSASendTo, - METH_VARARGS, Overlapped_WSASendTo_doc }, + _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF + _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF + _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF + _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF + _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF + _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF + _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF + _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF + _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF + _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF + _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF + _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF {NULL} }; @@ -1756,112 +1862,100 @@ static PyGetSetDef Overlapped_getsets[] = { {NULL}, }; -PyTypeObject OverlappedType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_overlapped.Overlapped", - /* tp_basicsize */ sizeof(OverlappedObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor) Overlapped_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, - /* tp_doc */ "OVERLAPPED structure wrapper", - /* tp_traverse */ (traverseproc)Overlapped_traverse, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ Overlapped_methods, - /* tp_members */ Overlapped_members, - /* tp_getset */ Overlapped_getsets, - /* 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 */ Overlapped_new, +static PyType_Slot overlapped_type_slots[] = { + {Py_tp_dealloc, Overlapped_dealloc}, + {Py_tp_doc, (char *)_overlapped_Overlapped__doc__}, + {Py_tp_traverse, Overlapped_traverse}, + {Py_tp_methods, Overlapped_methods}, + {Py_tp_members, Overlapped_members}, + {Py_tp_getset, Overlapped_getsets}, + {Py_tp_new, _overlapped_Overlapped}, + {0,0} +}; + +static PyType_Spec overlapped_type_spec = { + .name = "_overlapped.Overlapped", + .basicsize = sizeof(OverlappedObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), + .slots = overlapped_type_slots }; static PyMethodDef overlapped_functions[] = { - {"CreateIoCompletionPort", overlapped_CreateIoCompletionPort, - METH_VARARGS, CreateIoCompletionPort_doc}, - {"GetQueuedCompletionStatus", overlapped_GetQueuedCompletionStatus, - METH_VARARGS, GetQueuedCompletionStatus_doc}, - {"PostQueuedCompletionStatus", overlapped_PostQueuedCompletionStatus, - METH_VARARGS, PostQueuedCompletionStatus_doc}, - {"FormatMessage", overlapped_FormatMessage, - METH_VARARGS, FormatMessage_doc}, - {"BindLocal", overlapped_BindLocal, - METH_VARARGS, BindLocal_doc}, - {"RegisterWaitWithQueue", overlapped_RegisterWaitWithQueue, - METH_VARARGS, RegisterWaitWithQueue_doc}, - {"UnregisterWait", overlapped_UnregisterWait, - METH_VARARGS, UnregisterWait_doc}, - {"UnregisterWaitEx", overlapped_UnregisterWaitEx, - METH_VARARGS, UnregisterWaitEx_doc}, - {"CreateEvent", overlapped_CreateEvent, - METH_VARARGS, CreateEvent_doc}, - {"SetEvent", overlapped_SetEvent, - METH_VARARGS, SetEvent_doc}, - {"ResetEvent", overlapped_ResetEvent, - METH_VARARGS, ResetEvent_doc}, - {"ConnectPipe", overlapped_ConnectPipe, - METH_VARARGS, ConnectPipe_doc}, - {"WSAConnect", overlapped_WSAConnect, - METH_VARARGS, WSAConnect_doc}, + _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF + _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF + _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF + _OVERLAPPED_FORMATMESSAGE_METHODDEF + _OVERLAPPED_BINDLOCAL_METHODDEF + _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF + _OVERLAPPED_UNREGISTERWAIT_METHODDEF + _OVERLAPPED_UNREGISTERWAITEX_METHODDEF + _OVERLAPPED_CREATEEVENT_METHODDEF + _OVERLAPPED_SETEVENT_METHODDEF + _OVERLAPPED_RESETEVENT_METHODDEF + _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF + _OVERLAPPED_WSACONNECT_METHODDEF {NULL} }; -static struct PyModuleDef overlapped_module = { - PyModuleDef_HEAD_INIT, - "_overlapped", - NULL, - -1, - overlapped_functions, - NULL, - NULL, - NULL, - NULL -}; +static int +overlapped_traverse(PyObject *module, visitproc visit, void *arg) +{ + OverlappedState *state = overlapped_get_state(module); + Py_VISIT(state->overlapped_type); + return 0; +} -#define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) +static int +overlapped_clear(PyObject *module) +{ + OverlappedState *state = overlapped_get_state(module); + Py_CLEAR(state->overlapped_type); + return 0; +} -PyMODINIT_FUNC -PyInit__overlapped(void) +static void +overlapped_free(void *module) { - PyObject *m, *d; + overlapped_clear((PyObject *)module); +} +#define WINAPI_CONSTANT(fmt, con) \ + do { \ + PyObject *value = Py_BuildValue(fmt, con); \ + if (value == NULL) { \ + return -1; \ + } \ + if (PyModule_AddObject(module, #con, value) < 0 ) { \ + Py_DECREF(value); \ + return -1; \ + } \ + } while (0) + +static int +overlapped_exec(PyObject *module) +{ /* Ensure WSAStartup() called before initializing function pointers */ - m = PyImport_ImportModule("_socket"); - if (!m) - return NULL; - Py_DECREF(m); + PyObject *socket_module = PyImport_ImportModule("_socket"); + if (!socket_module) { + return -1; + } - if (initialize_function_pointers() < 0) - return NULL; + Py_DECREF(socket_module); - m = PyModule_Create(&overlapped_module); - if (PyModule_AddType(m, &OverlappedType) < 0) { - return NULL; + if (initialize_function_pointers() < 0) { + return -1; } - d = PyModule_GetDict(m); + OverlappedState *st = overlapped_get_state(module); + st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &overlapped_type_spec, NULL); + if (st->overlapped_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, st->overlapped_type) < 0) { + return -1; + } WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); @@ -1875,5 +1969,27 @@ PyInit__overlapped(void) WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT); WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET); - return m; + return 0; +} + +static PyModuleDef_Slot overlapped_slots[] = { + {Py_mod_exec, overlapped_exec}, + {0, NULL} +}; + +static struct PyModuleDef overlapped_module = { + 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 +PyInit__overlapped(void) +{ + return PyModuleDef_Init(&overlapped_module); } diff --git a/contrib/tools/python3/src/Modules/parsermodule.c b/contrib/tools/python3/src/Modules/parsermodule.c deleted file mode 100644 index 24b0ffbe36a..00000000000 --- a/contrib/tools/python3/src/Modules/parsermodule.c +++ /dev/null @@ -1,1222 +0,0 @@ -/* parsermodule.c - * - * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic - * Institute and State University, Blacksburg, Virginia, USA. - * Portions copyright 1991-1995 by Stichting Mathematisch Centrum, - * Amsterdam, The Netherlands. Copying is permitted under the terms - * associated with the main Python distribution, with the additional - * restriction that this additional notice be included and maintained - * on all distributed copies. - * - * This module serves to replace the original parser module written - * by Guido. The functionality is not matched precisely, but the - * original may be implemented on top of this. This is desirable - * since the source of the text to be parsed is now divorced from - * this interface. - * - * Unlike the prior interface, the ability to give a parse tree - * produced by Python code as a tuple to the compiler is enabled by - * this module. See the documentation for more details. - * - * I've added some annotations that help with the lint code-checking - * program, but they're not complete by a long shot. The real errors - * that lint detects are gone, but there are still warnings with - * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations - * look like "NOTE(...)". - * - */ - -#include "Python.h" /* general Python API */ -#include "Python-ast.h" /* mod_ty */ -#undef Yield /* undefine macro conflicting with */ -#include "ast.h" -#include "graminit.h" /* symbols defined in the grammar */ -#include "node.h" /* internal parser structure */ -#include "errcode.h" /* error codes for PyNode_*() */ -#include "token.h" /* token definitions */ - /* ISTERMINAL() / ISNONTERMINAL() */ -#include "grammar.h" -#include "parsetok.h" - -extern grammar _PyParser_Grammar; /* From graminit.c */ - -#ifdef lint -#include -#else -#define NOTE(x) -#endif - -/* String constants used to initialize module attributes. - * - */ -static const char parser_copyright_string[] = -"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\ -University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\ -Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\ -Centrum, Amsterdam, The Netherlands."; - - -PyDoc_STRVAR(parser_doc_string, -"This is an interface to Python's internal parser."); - -static const char parser_version_string[] = "0.5"; - - -typedef PyObject* (*SeqMaker) (Py_ssize_t length); -typedef int (*SeqInserter) (PyObject* sequence, - Py_ssize_t index, - PyObject* element); - -/* The function below is copyrighted by Stichting Mathematisch Centrum. The - * original copyright statement is included below, and continues to apply - * in full to the function immediately following. All other material is - * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic - * Institute and State University. Changes were made to comply with the - * new naming conventions. Added arguments to provide support for creating - * lists as well as tuples, and optionally including the line numbers. - */ - - -static PyObject* -node2tuple(node *n, /* node to convert */ - SeqMaker mkseq, /* create sequence */ - SeqInserter addelem, /* func. to add elem. in seq. */ - int lineno, /* include line numbers? */ - int col_offset) /* include column offsets? */ -{ - PyObject *result = NULL, *w; - - if (n == NULL) { - Py_RETURN_NONE; - } - - if (ISNONTERMINAL(TYPE(n))) { - int i; - - result = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); - if (result == NULL) - goto error; - - w = PyLong_FromLong(TYPE(n)); - if (w == NULL) - goto error; - (void) addelem(result, 0, w); - - for (i = 0; i < NCH(n); i++) { - w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset); - if (w == NULL) - goto error; - (void) addelem(result, i+1, w); - } - - if (TYPE(n) == encoding_decl) { - w = PyUnicode_FromString(STR(n)); - if (w == NULL) - goto error; - (void) addelem(result, i+1, w); - } - } - else if (ISTERMINAL(TYPE(n))) { - result = mkseq(2 + lineno + col_offset); - if (result == NULL) - goto error; - - w = PyLong_FromLong(TYPE(n)); - if (w == NULL) - goto error; - (void) addelem(result, 0, w); - - w = PyUnicode_FromString(STR(n)); - if (w == NULL) - goto error; - (void) addelem(result, 1, w); - - if (lineno) { - w = PyLong_FromLong(n->n_lineno); - if (w == NULL) - goto error; - (void) addelem(result, 2, w); - } - - if (col_offset) { - w = PyLong_FromLong(n->n_col_offset); - if (w == NULL) - goto error; - (void) addelem(result, 2 + lineno, w); - } - } - else { - PyErr_SetString(PyExc_SystemError, - "unrecognized parse tree node type"); - return ((PyObject*) NULL); - } - return result; - -error: - Py_XDECREF(result); - return NULL; -} -/* - * End of material copyrighted by Stichting Mathematisch Centrum. - */ - - - -/* There are two types of intermediate objects we're interested in: - * 'eval' and 'exec' types. These constants can be used in the st_type - * field of the object type to identify which any given object represents. - * These should probably go in an external header to allow other extensions - * to use them, but then, we really should be using C++ too. ;-) - */ - -#define PyST_EXPR 1 -#define PyST_SUITE 2 - - -/* These are the internal objects and definitions required to implement the - * ST type. Most of the internal names are more reminiscent of the 'old' - * naming style, but the code uses the new naming convention. - */ - -static PyObject* -parser_error = 0; - - -typedef struct { - PyObject_HEAD /* standard object header */ - node* st_node; /* the node* returned by the parser */ - int st_type; /* EXPR or SUITE ? */ - PyCompilerFlags st_flags; /* Parser and compiler flags */ -} PyST_Object; - - -static void parser_free(PyST_Object *st); -static PyObject* parser_sizeof(PyST_Object *, void *); -static PyObject* parser_richcompare(PyObject *left, PyObject *right, int op); -static PyObject* parser_compilest(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_isexpr(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_issuite(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_st2list(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_st2tuple(PyST_Object *, PyObject *, PyObject *); - -#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS) - -static PyMethodDef parser_methods[] = { - {"compile", (PyCFunction)(void(*)(void))parser_compilest, PUBLIC_METHOD_TYPE, - PyDoc_STR("Compile this ST object into a code object.")}, - {"isexpr", (PyCFunction)(void(*)(void))parser_isexpr, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if this ST object was created from an expression.")}, - {"issuite", (PyCFunction)(void(*)(void))parser_issuite, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if this ST object was created from a suite.")}, - {"tolist", (PyCFunction)(void(*)(void))parser_st2list, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a list-tree representation of this ST.")}, - {"totuple", (PyCFunction)(void(*)(void))parser_st2tuple, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a tuple-tree representation of this ST.")}, - {"__sizeof__", (PyCFunction)parser_sizeof, METH_NOARGS, - PyDoc_STR("Returns size in memory, in bytes.")}, - {NULL, NULL, 0, NULL} -}; - -static -PyTypeObject PyST_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "parser.st", /* tp_name */ - (int) sizeof(PyST_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)parser_free, /* 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 */ - - /* Functions to access object as input/output buffer */ - 0, /* tp_as_buffer */ - - Py_TPFLAGS_DEFAULT, /* tp_flags */ - - /* __doc__ */ - "Intermediate representation of a Python parse tree.", - 0, /* tp_traverse */ - 0, /* tp_clear */ - parser_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - parser_methods, /* tp_methods */ -}; /* PyST_Type */ - - -/* PyST_Type isn't subclassable, so just check ob_type */ -#define PyST_Object_Check(v) Py_IS_TYPE(v, &PyST_Type) - -static int -parser_compare_nodes(node *left, node *right) -{ - int j; - - if (TYPE(left) < TYPE(right)) - return (-1); - - if (TYPE(right) < TYPE(left)) - return (1); - - if (ISTERMINAL(TYPE(left))) - return (strcmp(STR(left), STR(right))); - - if (NCH(left) < NCH(right)) - return (-1); - - if (NCH(right) < NCH(left)) - return (1); - - for (j = 0; j < NCH(left); ++j) { - int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j)); - - if (v != 0) - return (v); - } - return (0); -} - -/* parser_richcompare(PyObject* left, PyObject* right, int op) - * - * Comparison function used by the Python operators ==, !=, <, >, <=, >= - * This really just wraps a call to parser_compare_nodes() with some easy - * checks and protection code. - * - */ - -static PyObject * -parser_richcompare(PyObject *left, PyObject *right, int op) -{ - int result; - - /* neither argument should be NULL, unless something's gone wrong */ - if (left == NULL || right == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - - /* both arguments should be instances of PyST_Object */ - if (!PyST_Object_Check(left) || !PyST_Object_Check(right)) { - Py_RETURN_NOTIMPLEMENTED; - } - - if (left == right) - /* if arguments are identical, they're equal */ - result = 0; - else - result = parser_compare_nodes(((PyST_Object *)left)->st_node, - ((PyST_Object *)right)->st_node); - - Py_RETURN_RICHCOMPARE(result, 0, op); -} - -/* parser_newstobject(node* st) - * - * Allocates a new Python object representing an ST. This is simply the - * 'wrapper' object that holds a node* and allows it to be passed around in - * Python code. - * - */ -static PyObject* -parser_newstobject(node *st, int type) -{ - PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type); - - if (o != 0) { - o->st_node = st; - o->st_type = type; - o->st_flags = _PyCompilerFlags_INIT; - } - else { - PyNode_Free(st); - } - return ((PyObject*)o); -} - - -/* void parser_free(PyST_Object* st) - * - * This is called by a del statement that reduces the reference count to 0. - * - */ -static void -parser_free(PyST_Object *st) -{ - PyNode_Free(st->st_node); - PyObject_Del(st); -} - -static PyObject * -parser_sizeof(PyST_Object *st, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(st)) + _PyNode_SizeOf(st->st_node); - return PyLong_FromSsize_t(res); -} - - -/* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw) - * - * This provides conversion from a node* to a tuple object that can be - * returned to the Python-level caller. The ST object is not modified. - * - */ -static PyObject* -parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw) -{ - int line_info = 0; - int col_info = 0; - PyObject *res = 0; - int ok; - - static char *keywords[] = {"st", "line_info", "col_info", NULL}; - - if (self == NULL || PyModule_Check(self)) { - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2tuple", keywords, - &PyST_Type, &self, &line_info, - &col_info); - } - else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:totuple", &keywords[1], - &line_info, &col_info); - if (ok != 0) { - /* - * Convert ST into a tuple representation. Use Guido's function, - * since it's known to work already. - */ - res = node2tuple(((PyST_Object*)self)->st_node, - PyTuple_New, PyTuple_SetItem, line_info, col_info); - } - return (res); -} - - -/* parser_st2list(PyObject* self, PyObject* args, PyObject* kw) - * - * This provides conversion from a node* to a list object that can be - * returned to the Python-level caller. The ST object is not modified. - * - */ -static PyObject* -parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) -{ - int line_info = 0; - int col_info = 0; - PyObject *res = 0; - int ok; - - static char *keywords[] = {"st", "line_info", "col_info", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2list", keywords, - &PyST_Type, &self, &line_info, - &col_info); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:tolist", &keywords[1], - &line_info, &col_info); - if (ok) { - /* - * Convert ST into a tuple representation. Use Guido's function, - * since it's known to work already. - */ - res = node2tuple(self->st_node, - PyList_New, PyList_SetItem, line_info, col_info); - } - return (res); -} - - -/* parser_compilest(PyObject* self, PyObject* args) - * - * This function creates code objects from the parse tree represented by - * the passed-in data object. An optional file name is passed in as well. - * - */ -static PyObject* -parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) -{ - PyObject* res = NULL; - PyArena* arena = NULL; - mod_ty mod; - PyObject* filename = NULL; - int ok; - - static char *keywords[] = {"st", "filename", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O&:compilest", keywords, - &PyST_Type, &self, - PyUnicode_FSDecoder, &filename); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1], - PyUnicode_FSDecoder, &filename); - if (!ok) - goto error; - - if (filename == NULL) { - filename = PyUnicode_FromString(""); - if (filename == NULL) - goto error; - } - - arena = PyArena_New(); - if (!arena) - goto error; - - mod = PyAST_FromNodeObject(self->st_node, &self->st_flags, - filename, arena); - if (!mod) - goto error; - - res = (PyObject *)PyAST_CompileObject(mod, filename, - &self->st_flags, -1, arena); -error: - Py_XDECREF(filename); - if (arena != NULL) - PyArena_Free(arena); - return res; -} - - -/* PyObject* parser_isexpr(PyObject* self, PyObject* args) - * PyObject* parser_issuite(PyObject* self, PyObject* args) - * - * Checks the passed-in ST object to determine if it is an expression or - * a statement suite, respectively. The return is a Python truth value. - * - */ -static PyObject* -parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw) -{ - PyObject* res = 0; - int ok; - - static char *keywords[] = {"st", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords, - &PyST_Type, &self); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]); - - if (ok) { - /* Check to see if the ST represents an expression or not. */ - res = (self->st_type == PyST_EXPR) ? Py_True : Py_False; - Py_INCREF(res); - } - return (res); -} - - -static PyObject* -parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw) -{ - PyObject* res = 0; - int ok; - - static char *keywords[] = {"st", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords, - &PyST_Type, &self); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]); - - if (ok) { - /* Check to see if the ST represents an expression or not. */ - res = (self->st_type == PyST_EXPR) ? Py_False : Py_True; - Py_INCREF(res); - } - return (res); -} - - -/* err_string(const char* message) - * - * Sets the error string for an exception of type ParserError. - * - */ -static void -err_string(const char *message) -{ - PyErr_SetString(parser_error, message); -} - - -/* PyObject* parser_do_parse(PyObject* args, int type) - * - * Internal function to actually execute the parse and return the result if - * successful or set an exception if not. - * - */ -static PyObject* -parser_do_parse(PyObject *args, PyObject *kw, const char *argspec, int type) -{ - char* string = 0; - PyObject* res = 0; - int flags = 0; - perrdetail err; - - static char *keywords[] = {"source", NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) { - node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL, - &_PyParser_Grammar, - (type == PyST_EXPR) - ? eval_input : file_input, - &err, &flags); - - if (n) { - res = parser_newstobject(n, type); - if (res) { - ((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK; - ((PyST_Object *)res)->st_flags.cf_feature_version = PY_MINOR_VERSION; - } - } - else { - PyParser_SetError(&err); - } - PyParser_ClearError(&err); - } - return (res); -} - - -/* PyObject* parser_expr(PyObject* self, PyObject* args) - * PyObject* parser_suite(PyObject* self, PyObject* args) - * - * External interfaces to the parser itself. Which is called determines if - * the parser attempts to recognize an expression ('eval' form) or statement - * suite ('exec' form). The real work is done by parser_do_parse() above. - * - */ -static PyObject* -parser_expr(PyST_Object *self, PyObject *args, PyObject *kw) -{ - NOTE(ARGUNUSED(self)) - return (parser_do_parse(args, kw, "s:expr", PyST_EXPR)); -} - - -static PyObject* -parser_suite(PyST_Object *self, PyObject *args, PyObject *kw) -{ - NOTE(ARGUNUSED(self)) - return (parser_do_parse(args, kw, "s:suite", PyST_SUITE)); -} - - - -/* This is the messy part of the code. Conversion from a tuple to an ST - * object requires that the input tuple be valid without having to rely on - * catching an exception from the compiler. This is done to allow the - * compiler itself to remain fast, since most of its input will come from - * the parser directly, and therefore be known to be syntactically correct. - * This validation is done to ensure that we don't core dump the compile - * phase, returning an exception instead. - * - * Two aspects can be broken out in this code: creating a node tree from - * the tuple passed in, and verifying that it is indeed valid. It may be - * advantageous to expand the number of ST types to include funcdefs and - * lambdadefs to take advantage of the optimizer, recognizing those STs - * here. They are not necessary, and not quite as useful in a raw form. - * For now, let's get expressions and suites working reliably. - */ - - -static node* build_node_tree(PyObject *tuple); - -static int -validate_node(node *tree) -{ - int type = TYPE(tree); - int nch = NCH(tree); - state *dfa_state; - int pos, arc; - - assert(ISNONTERMINAL(type)); - type -= NT_OFFSET; - if (type >= _PyParser_Grammar.g_ndfas) { - PyErr_Format(parser_error, "Unrecognized node type %d.", TYPE(tree)); - return 0; - } - const dfa *nt_dfa = &_PyParser_Grammar.g_dfa[type]; - REQ(tree, nt_dfa->d_type); - - /* Run the DFA for this nonterminal. */ - dfa_state = nt_dfa->d_state; - for (pos = 0; pos < nch; ++pos) { - node *ch = CHILD(tree, pos); - int ch_type = TYPE(ch); - if ((ch_type >= NT_OFFSET + _PyParser_Grammar.g_ndfas) - || (ISTERMINAL(ch_type) && (ch_type >= N_TOKENS)) - || (ch_type < 0) - ) { - PyErr_Format(parser_error, "Unrecognized node type %d.", ch_type); - return 0; - } - if (ch_type == suite && TYPE(tree) == funcdef) { - /* This is the opposite hack of what we do in parser.c - (search for func_body_suite), except we don't ever - support type comments here. */ - ch_type = func_body_suite; - } - for (arc = 0; arc < dfa_state->s_narcs; ++arc) { - short a_label = dfa_state->s_arc[arc].a_lbl; - assert(a_label < _PyParser_Grammar.g_ll.ll_nlabels); - - const char *label_str = _PyParser_Grammar.g_ll.ll_label[a_label].lb_str; - if ((_PyParser_Grammar.g_ll.ll_label[a_label].lb_type == ch_type) - && ((ch->n_str == NULL) || (label_str == NULL) - || (strcmp(ch->n_str, label_str) == 0)) - ) { - /* The child is acceptable; if non-terminal, validate it recursively. */ - if (ISNONTERMINAL(ch_type) && !validate_node(ch)) - return 0; - - /* Update the state, and move on to the next child. */ - dfa_state = &nt_dfa->d_state[dfa_state->s_arc[arc].a_arrow]; - goto arc_found; - } - } - /* What would this state have accepted? */ - { - short a_label = dfa_state->s_arc->a_lbl; - if (!a_label) /* Wouldn't accept any more children */ - goto illegal_num_children; - - int next_type = _PyParser_Grammar.g_ll.ll_label[a_label].lb_type; - const char *expected_str = _PyParser_Grammar.g_ll.ll_label[a_label].lb_str; - - if (ISNONTERMINAL(next_type)) { - PyErr_Format(parser_error, "Expected %s, got %s.", - _PyParser_Grammar.g_dfa[next_type - NT_OFFSET].d_name, - ISTERMINAL(ch_type) ? _PyParser_TokenNames[ch_type] : - _PyParser_Grammar.g_dfa[ch_type - NT_OFFSET].d_name); - } - else if (expected_str != NULL) { - PyErr_Format(parser_error, "Illegal terminal: expected '%s'.", - expected_str); - } - else { - PyErr_Format(parser_error, "Illegal terminal: expected %s.", - _PyParser_TokenNames[next_type]); - } - return 0; - } - -arc_found: - continue; - } - /* Are we in a final state? If so, return 1 for successful validation. */ - for (arc = 0; arc < dfa_state->s_narcs; ++arc) { - if (!dfa_state->s_arc[arc].a_lbl) { - return 1; - } - } - -illegal_num_children: - PyErr_Format(parser_error, - "Illegal number of children for %s node.", nt_dfa->d_name); - return 0; -} - -/* PyObject* parser_tuple2st(PyObject* self, PyObject* args) - * - * This is the public function, called from the Python code. It receives a - * single tuple object from the caller, and creates an ST object if the - * tuple can be validated. It does this by checking the first code of the - * tuple, and, if acceptable, builds the internal representation. If this - * step succeeds, the internal representation is validated as fully as - * possible with the recursive validate_node() routine defined above. - * - * This function must be changed if support is to be added for PyST_FRAGMENT - * ST objects. - * - */ -static PyObject* -parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw) -{ - NOTE(ARGUNUSED(self)) - PyObject *st = 0; - PyObject *tuple; - node *tree; - - static char *keywords[] = {"sequence", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords, - &tuple)) - return (0); - if (!PySequence_Check(tuple)) { - PyErr_SetString(PyExc_ValueError, - "sequence2st() requires a single sequence argument"); - return (0); - } - /* - * Convert the tree to the internal form before checking it. - */ - tree = build_node_tree(tuple); - if (tree != 0) { - node *validation_root = NULL; - int tree_type = 0; - switch (TYPE(tree)) { - case eval_input: - /* Might be an eval form. */ - tree_type = PyST_EXPR; - validation_root = tree; - break; - case encoding_decl: - /* This looks like an encoding_decl so far. */ - if (NCH(tree) == 1) { - tree_type = PyST_SUITE; - validation_root = CHILD(tree, 0); - } - else { - err_string("Error Parsing encoding_decl"); - } - break; - case file_input: - /* This looks like an exec form so far. */ - tree_type = PyST_SUITE; - validation_root = tree; - break; - default: - /* This is a fragment, at best. */ - err_string("parse tree does not use a valid start symbol"); - } - - if (validation_root != NULL && validate_node(validation_root)) - st = parser_newstobject(tree, tree_type); - else - PyNode_Free(tree); - } - /* Make sure we raise an exception on all errors. We should never - * get this, but we'd do well to be sure something is done. - */ - if (st == NULL && !PyErr_Occurred()) - err_string("unspecified ST error occurred"); - - return st; -} - - -/* node* build_node_children() - * - * Iterate across the children of the current non-terminal node and build - * their structures. If successful, return the root of this portion of - * the tree, otherwise, 0. Any required exception will be specified already, - * and no memory will have been deallocated. - * - */ -static node* -build_node_children(PyObject *tuple, node *root, int *line_num) -{ - Py_ssize_t len = PyObject_Size(tuple); - Py_ssize_t i; - int err; - - if (len < 0) { - return NULL; - } - for (i = 1; i < len; ++i) { - /* elem must always be a sequence, however simple */ - PyObject* elem = PySequence_GetItem(tuple, i); - int ok = elem != NULL; - int type = 0; - char *strn = 0; - - if (ok) - ok = PySequence_Check(elem); - if (ok) { - PyObject *temp = PySequence_GetItem(elem, 0); - if (temp == NULL) - ok = 0; - else { - ok = PyLong_Check(temp); - if (ok) { - type = _PyLong_AsInt(temp); - if (type == -1 && PyErr_Occurred()) { - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - } - Py_DECREF(temp); - } - } - if (!ok) { - PyObject *err = Py_BuildValue("Os", elem, - "Illegal node construct."); - PyErr_SetObject(parser_error, err); - Py_XDECREF(err); - Py_XDECREF(elem); - return NULL; - } - if (ISTERMINAL(type)) { - Py_ssize_t len = PyObject_Size(elem); - PyObject *temp; - const char *temp_str; - - if ((len != 2) && (len != 3)) { - err_string("terminal nodes must have 2 or 3 entries"); - Py_DECREF(elem); - return NULL; - } - temp = PySequence_GetItem(elem, 1); - if (temp == NULL) { - Py_DECREF(elem); - return NULL; - } - if (!PyUnicode_Check(temp)) { - PyErr_Format(parser_error, - "second item in terminal node must be a string," - " found %s", - Py_TYPE(temp)->tp_name); - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - if (len == 3) { - PyObject *o = PySequence_GetItem(elem, 2); - if (o == NULL) { - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - if (PyLong_Check(o)) { - int num = _PyLong_AsInt(o); - if (num == -1 && PyErr_Occurred()) { - Py_DECREF(o); - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - *line_num = num; - } - else { - PyErr_Format(parser_error, - "third item in terminal node must be an" - " integer, found %s", - Py_TYPE(temp)->tp_name); - Py_DECREF(o); - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - Py_DECREF(o); - } - temp_str = PyUnicode_AsUTF8AndSize(temp, &len); - if (temp_str == NULL) { - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - strn = (char *)PyObject_MALLOC(len + 1); - if (strn == NULL) { - Py_DECREF(temp); - Py_DECREF(elem); - PyErr_NoMemory(); - return NULL; - } - (void) memcpy(strn, temp_str, len + 1); - Py_DECREF(temp); - } - else if (!ISNONTERMINAL(type)) { - /* - * It has to be one or the other; this is an error. - * Raise an exception. - */ - PyObject *err = Py_BuildValue("Os", elem, "unknown node type."); - PyErr_SetObject(parser_error, err); - Py_XDECREF(err); - Py_DECREF(elem); - return NULL; - } - err = PyNode_AddChild(root, type, strn, *line_num, 0, *line_num, 0); - if (err == E_NOMEM) { - Py_DECREF(elem); - PyObject_FREE(strn); - PyErr_NoMemory(); - return NULL; - } - if (err == E_OVERFLOW) { - Py_DECREF(elem); - PyObject_FREE(strn); - PyErr_SetString(PyExc_ValueError, - "unsupported number of child nodes"); - return NULL; - } - - if (ISNONTERMINAL(type)) { - node* new_child = CHILD(root, i - 1); - - if (new_child != build_node_children(elem, new_child, line_num)) { - Py_DECREF(elem); - return NULL; - } - } - else if (type == NEWLINE) { /* It's true: we increment the */ - ++(*line_num); /* line number *after* the newline! */ - } - Py_DECREF(elem); - } - return root; -} - - -static node* -build_node_tree(PyObject *tuple) -{ - node* res = 0; - PyObject *temp = PySequence_GetItem(tuple, 0); - long num = -1; - - if (temp != NULL) - num = PyLong_AsLong(temp); - Py_XDECREF(temp); - if (ISTERMINAL(num)) { - /* - * The tuple is simple, but it doesn't start with a start symbol. - * Raise an exception now and be done with it. - */ - tuple = Py_BuildValue("Os", tuple, - "Illegal syntax-tree; cannot start with terminal symbol."); - PyErr_SetObject(parser_error, tuple); - Py_XDECREF(tuple); - } - else if (ISNONTERMINAL(num)) { - /* - * Not efficient, but that can be handled later. - */ - int line_num = 0; - PyObject *encoding = NULL; - - if (num == encoding_decl) { - encoding = PySequence_GetItem(tuple, 2); - if (encoding == NULL) { - PyErr_SetString(parser_error, "missed encoding"); - return NULL; - } - if (!PyUnicode_Check(encoding)) { - PyErr_Format(parser_error, - "encoding must be a string, found %.200s", - Py_TYPE(encoding)->tp_name); - Py_DECREF(encoding); - return NULL; - } - /* tuple isn't borrowed anymore here, need to DECREF */ - tuple = PySequence_GetSlice(tuple, 0, 2); - if (tuple == NULL) { - Py_DECREF(encoding); - return NULL; - } - } - res = PyNode_New(num); - if (res != NULL) { - if (res != build_node_children(tuple, res, &line_num)) { - PyNode_Free(res); - res = NULL; - } - if (res && encoding) { - Py_ssize_t len; - const char *temp; - temp = PyUnicode_AsUTF8AndSize(encoding, &len); - if (temp == NULL) { - PyNode_Free(res); - Py_DECREF(encoding); - Py_DECREF(tuple); - return NULL; - } - res->n_str = (char *)PyObject_MALLOC(len + 1); - if (res->n_str == NULL) { - PyNode_Free(res); - Py_DECREF(encoding); - Py_DECREF(tuple); - PyErr_NoMemory(); - return NULL; - } - (void) memcpy(res->n_str, temp, len + 1); - } - } - if (encoding != NULL) { - Py_DECREF(encoding); - Py_DECREF(tuple); - } - } - else { - /* The tuple is illegal -- if the number is neither TERMINAL nor - * NONTERMINAL, we can't use it. Not sure the implementation - * allows this condition, but the API doesn't preclude it. - */ - PyObject *err = Py_BuildValue("Os", tuple, - "Illegal component tuple."); - PyErr_SetObject(parser_error, err); - Py_XDECREF(err); - } - - return (res); -} - - -static PyObject* -pickle_constructor = NULL; - - -static PyObject* -parser__pickler(PyObject *self, PyObject *args) -{ - NOTE(ARGUNUSED(self)) - PyObject *result = NULL; - PyObject *st = NULL; - - if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) { - PyObject *newargs; - PyObject *tuple; - - if ((newargs = PyTuple_Pack(2, st, Py_True)) == NULL) - return NULL; - tuple = parser_st2tuple((PyST_Object*)NULL, newargs, NULL); - if (tuple != NULL) { - result = Py_BuildValue("O(O)", pickle_constructor, tuple); - Py_DECREF(tuple); - } - Py_DECREF(newargs); - } - - return (result); -} - - -/* Functions exported by this module. Most of this should probably - * be converted into an ST object with methods, but that is better - * done directly in Python, allowing subclasses to be created directly. - * We'd really have to write a wrapper around it all anyway to allow - * inheritance. - */ -static PyMethodDef parser_functions[] = { - {"compilest", (PyCFunction)(void(*)(void))parser_compilest, PUBLIC_METHOD_TYPE, - PyDoc_STR("Compiles an ST object into a code object.")}, - {"expr", (PyCFunction)(void(*)(void))parser_expr, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from an expression.")}, - {"isexpr", (PyCFunction)(void(*)(void))parser_isexpr, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if an ST object was created from an expression.")}, - {"issuite", (PyCFunction)(void(*)(void))parser_issuite, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if an ST object was created from a suite.")}, - {"suite", (PyCFunction)(void(*)(void))parser_suite, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from a suite.")}, - {"sequence2st", (PyCFunction)(void(*)(void))parser_tuple2st, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from a tree representation.")}, - {"st2tuple", (PyCFunction)(void(*)(void))parser_st2tuple, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a tuple-tree representation of an ST.")}, - {"st2list", (PyCFunction)(void(*)(void))parser_st2list, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a list-tree representation of an ST.")}, - {"tuple2st", (PyCFunction)(void(*)(void))parser_tuple2st, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from a tree representation.")}, - - /* private stuff: support pickle module */ - {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS, - PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")}, - - {NULL, NULL, 0, NULL} - }; - - - -static struct PyModuleDef parsermodule = { - PyModuleDef_HEAD_INIT, - "parser", - NULL, - -1, - parser_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PyInit_parser(void); /* supply a prototype */ - -PyMODINIT_FUNC -PyInit_parser(void) -{ - PyObject *module, *copyreg; - - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "The parser module is deprecated and will be removed " - "in future versions of Python", 7) != 0) { - return NULL; - } - - if (PyType_Ready(&PyST_Type) < 0) - return NULL; - module = PyModule_Create(&parsermodule); - if (module == NULL) - return NULL; - - if (parser_error == 0) - parser_error = PyErr_NewException("parser.ParserError", NULL, NULL); - - if (parser_error == 0) - return NULL; - /* CAUTION: The code next used to skip bumping the refcount on - * parser_error. That's a disaster if PyInit_parser() gets called more - * than once. By incref'ing, we ensure that each module dict that - * gets created owns its reference to the shared parser_error object, - * and the file static parser_error vrbl owns a reference too. - */ - Py_INCREF(parser_error); - if (PyModule_AddObject(module, "ParserError", parser_error) != 0) - return NULL; - - Py_INCREF(&PyST_Type); - PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type); - - PyModule_AddStringConstant(module, "__copyright__", - parser_copyright_string); - PyModule_AddStringConstant(module, "__doc__", - parser_doc_string); - PyModule_AddStringConstant(module, "__version__", - parser_version_string); - - /* Register to support pickling. - * If this fails, the import of this module will fail because an - * exception will be raised here; should we clear the exception? - */ - copyreg = PyImport_ImportModuleNoBlock("copyreg"); - if (copyreg != NULL) { - PyObject *func, *pickler; - _Py_IDENTIFIER(pickle); - _Py_IDENTIFIER(sequence2st); - _Py_IDENTIFIER(_pickler); - - func = _PyObject_GetAttrId(copyreg, &PyId_pickle); - pickle_constructor = _PyObject_GetAttrId(module, &PyId_sequence2st); - pickler = _PyObject_GetAttrId(module, &PyId__pickler); - Py_XINCREF(pickle_constructor); - if ((func != NULL) && (pickle_constructor != NULL) - && (pickler != NULL)) { - PyObject *res; - - res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler, - pickle_constructor, NULL); - Py_XDECREF(res); - } - Py_XDECREF(func); - Py_XDECREF(pickle_constructor); - Py_XDECREF(pickler); - Py_DECREF(copyreg); - } - return module; -} diff --git a/contrib/tools/python3/src/Modules/posixmodule.c b/contrib/tools/python3/src/Modules/posixmodule.c index 09182668432..7b1b2cd2524 100644 --- a/contrib/tools/python3/src/Modules/posixmodule.c +++ b/contrib/tools/python3/src/Modules/posixmodule.c @@ -10,6 +10,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_fileutils.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() #ifdef MS_WINDOWS /* include early to avoid conflict with pycore_condvar.h: @@ -21,8 +23,12 @@ # include #endif +#ifdef __VXWORKS__ +# include "pycore_bitutils.h" // _Py_popcount32() +#endif #include "pycore_ceval.h" // _PyEval_ReInitThreads() #include "pycore_import.h" // _PyImport_ReInitLock() +#include "pycore_initconfig.h" // _PyStatus_EXCEPTION() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" // PyMemberDef #ifndef MS_WINDOWS @@ -276,6 +282,7 @@ corresponding Unix manual entries for more information on calls."); #endif #ifdef HAVE_GETRANDOM_SYSCALL # include +# include #endif #if defined(MS_WINDOWS) @@ -521,6 +528,11 @@ extern char *ctermid_r(char *); # include #endif +/* eventfd() */ +#ifdef HAVE_SYS_EVENTFD_H +# include +#endif + #ifdef _Py_MEMORY_SANITIZER # include #endif @@ -578,15 +590,45 @@ PyOS_AfterFork_Parent(void) void PyOS_AfterFork_Child(void) { + PyStatus status; _PyRuntimeState *runtime = &_PyRuntime; - _PyGILState_Reinit(runtime); - _PyEval_ReInitThreads(runtime); - _PyImport_ReInitLock(); + + status = _PyGILState_Reinit(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + + PyThreadState *tstate = _PyThreadState_GET(); + _Py_EnsureTstateNotNULL(tstate); + + status = _PyEval_ReInitThreads(tstate); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + + status = _PyImport_ReInitLock(); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + _PySignal_AfterFork(); - _PyRuntimeState_ReInitThreads(runtime); - _PyInterpreterState_DeleteExceptMain(runtime); - run_at_forkers(_PyInterpreterState_GET()->after_forkers_child, 0); + status = _PyRuntimeState_ReInitThreads(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + + status = _PyInterpreterState_DeleteExceptMain(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + assert(_PyThreadState_GET() == tstate); + + run_at_forkers(tstate->interp->after_forkers_child, 0); + return; + +fatal_error: + Py_ExitStatusException(status); } static int @@ -648,7 +690,7 @@ _Py_Uid_Converter(PyObject *obj, uid_t *p) long result; unsigned long uresult; - index = PyNumber_Index(obj); + index = _PyNumber_Index(obj); if (index == NULL) { PyErr_Format(PyExc_TypeError, "uid should be integer, not %.200s", @@ -754,7 +796,7 @@ _Py_Gid_Converter(PyObject *obj, gid_t *p) long result; unsigned long uresult; - index = PyNumber_Index(obj); + index = _PyNumber_Index(obj); if (index == NULL) { PyErr_Format(PyExc_TypeError, "gid should be integer, not %.200s", @@ -888,7 +930,7 @@ _fd_converter(PyObject *o, int *p) int overflow; long long_value; - PyObject *index = PyNumber_Index(o); + PyObject *index = _PyNumber_Index(o); if (index == NULL) { return 0; } @@ -955,7 +997,7 @@ typedef struct { static inline _posixstate* get_posix_state(PyObject *module) { - void *state = PyModule_GetState(module); + void *state = _PyModule_GetState(module); assert(state != NULL); return (_posixstate *)state; } @@ -1074,6 +1116,11 @@ 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); } @@ -1088,7 +1135,7 @@ path_converter(PyObject *o, void *p) const char *narrow; #ifdef MS_WINDOWS PyObject *wo = NULL; - const wchar_t *wide; + wchar_t *wide = NULL; #endif #define FORMAT_EXCEPTION(exc, fmt) \ @@ -1161,10 +1208,14 @@ path_converter(PyObject *o, void *p) 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; } @@ -1180,6 +1231,9 @@ _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)) { @@ -1255,10 +1309,15 @@ _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; } @@ -1272,8 +1331,12 @@ _Py_COMP_DIAG_POP } path->wide = wide; path->narrow = TRUE; - path->cleanup = wo; 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; @@ -1297,7 +1360,11 @@ _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; } @@ -1583,13 +1650,11 @@ convertenviron(void) Py_DECREF(d); return NULL; } - if (PyDict_GetItemWithError(d, k) == NULL) { - if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) { - Py_DECREF(v); - Py_DECREF(k); - Py_DECREF(d); - return NULL; - } + if (PyDict_SetDefault(d, k, v) == NULL) { + Py_DECREF(v); + Py_DECREF(k); + Py_DECREF(d); + return NULL; } Py_DECREF(k); Py_DECREF(v); @@ -1692,18 +1757,6 @@ path_error2(path_t *path, path_t *path2) /* POSIX generic methods */ -static int -fildes_converter(PyObject *o, void *p) -{ - int fd; - int *pointer = (int *)p; - fd = PyObject_AsFileDescriptor(o); - if (fd < 0) - return 0; - *pointer = fd; - return 1; -} - static PyObject * posix_fildes_fd(int fd, int (*func)(int)) { @@ -2735,10 +2788,6 @@ class dir_fd_converter(CConverter): else: self.converter = 'dir_fd_converter' -class fildes_converter(CConverter): - type = 'int' - converter = 'fildes_converter' - class uid_t_converter(CConverter): type = "uid_t" converter = '_Py_Uid_Converter' @@ -2801,7 +2850,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/ /*[clinic input] @@ -5507,7 +5556,7 @@ free_string_array(EXECV_CHAR **array, Py_ssize_t count) Py_ssize_t i; for (i = 0; i < count; i++) PyMem_Free(array[i]); - PyMem_DEL(array); + PyMem_Free(array); } static int @@ -6545,9 +6594,10 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); fail_2: - while (--envc >= 0) - PyMem_DEL(envlist[envc]); - PyMem_DEL(envlist); + while (--envc >= 0) { + PyMem_Free(envlist[envc]); + } + PyMem_Free(envlist); fail_1: free_string_array(argvlist, lastarg); fail_0: @@ -6556,7 +6606,6 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, #endif /* HAVE_SPAWNV */ - #ifdef HAVE_FORK /* Helper function to validate arguments. @@ -7146,12 +7195,11 @@ error: /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ -/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) -#define DEV_PTY_FILE "/dev/ptc" -#define HAVE_DEV_PTMX +# define DEV_PTY_FILE "/dev/ptc" +# define HAVE_DEV_PTMX #else -#define DEV_PTY_FILE "/dev/ptmx" +# define DEV_PTY_FILE "/dev/ptmx" #endif #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) @@ -7484,7 +7532,7 @@ os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid) list = PyList_New(ngroups); if (list == NULL) { - PyMem_Del(groups); + PyMem_Free(groups); return NULL; } @@ -7496,13 +7544,13 @@ os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid) #endif if (o == NULL) { Py_DECREF(list); - PyMem_Del(groups); + PyMem_Free(groups); return NULL; } PyList_SET_ITEM(list, i, o); } - PyMem_Del(groups); + PyMem_Free(groups); return list; } @@ -9169,25 +9217,6 @@ os_close_impl(PyObject *module, int fd) Py_RETURN_NONE; } - -#ifdef HAVE_FDWALK -static int -_fdwalk_close_func(void *lohi, int fd) -{ - int lo = ((int *)lohi)[0]; - int hi = ((int *)lohi)[1]; - - if (fd >= hi) { - return 1; - } - else if (fd >= lo) { - /* Ignore errors */ - (void)close(fd); - } - return 0; -} -#endif /* HAVE_FDWALK */ - /*[clinic input] os.closerange @@ -9202,32 +9231,8 @@ static PyObject * os_closerange_impl(PyObject *module, int fd_low, int fd_high) /*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/ { -#ifdef HAVE_FDWALK - int lohi[2]; -#endif Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_FDWALK - lohi[0] = Py_MAX(fd_low, 0); - lohi[1] = fd_high; - fdwalk(_fdwalk_close_func, lohi); -#else - fd_low = Py_MAX(fd_low, 0); -#ifdef __FreeBSD__ - if (fd_high >= sysconf(_SC_OPEN_MAX)) { - /* Any errors encountered while closing file descriptors are ignored */ - closefrom(fd_low); - } - else -#endif - { - for (int i = fd_low; i < fd_high; i++) { - /* Ignore errors */ - (void)close(i); - } - } -#endif - _Py_END_SUPPRESS_IPH + _Py_closerange(fd_low, fd_high - 1); Py_END_ALLOW_THREADS Py_RETURN_NONE; } @@ -9490,7 +9495,7 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, in *buf = PyMem_New(Py_buffer, cnt); if (*buf == NULL) { - PyMem_Del(*iov); + PyMem_Free(*iov); PyErr_NoMemory(); return -1; } @@ -9510,11 +9515,11 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, in return 0; fail: - PyMem_Del(*iov); + PyMem_Free(*iov); for (j = 0; j < i; j++) { PyBuffer_Release(&(*buf)[j]); } - PyMem_Del(*buf); + PyMem_Free(*buf); return -1; } @@ -9522,11 +9527,11 @@ static void iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) { int i; - PyMem_Del(iov); + PyMem_Free(iov); for (i = 0; i < cnt; i++) { PyBuffer_Release(&buf[i]); } - PyMem_Del(buf); + PyMem_Free(buf); } #endif @@ -10108,18 +10113,16 @@ os_pipe_impl(PyObject *module) attr.bInheritHandle = FALSE; Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH ok = CreatePipe(&read, &write, &attr, 0); if (ok) { - fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY); - fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY); + fds[0] = _Py_open_osfhandle_noraise(read, _O_RDONLY); + fds[1] = _Py_open_osfhandle_noraise(write, _O_WRONLY); if (fds[0] == -1 || fds[1] == -1) { CloseHandle(read); CloseHandle(write); ok = 0; } } - _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (!ok) @@ -10304,6 +10307,7 @@ The flags argument contains a bitwise OR of zero or more of the following flags: - RWF_DSYNC - RWF_SYNC +- RWF_APPEND Using non-zero flags requires Linux 4.7 or newer. [clinic start generated code]*/ @@ -10311,7 +10315,7 @@ Using non-zero flags requires Linux 4.7 or newer. static Py_ssize_t os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, int flags) -/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/ +/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/ { Py_ssize_t cnt; Py_ssize_t result; @@ -10453,6 +10457,75 @@ os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, } #endif /* HAVE_COPY_FILE_RANGE*/ +#if (defined(HAVE_SPLICE) && !defined(_AIX)) +/*[clinic input] + +os.splice + src: int + Source file descriptor. + dst: int + Destination file descriptor. + count: Py_ssize_t + Number of bytes to copy. + offset_src: object = None + Starting offset in src. + offset_dst: object = None + Starting offset in dst. + flags: unsigned_int = 0 + Flags to modify the semantics of the call. + +Transfer count bytes from one pipe to a descriptor or vice versa. + +If offset_src is None, then src is read from the current position; +respectively for offset_dst. The offset associated to the file +descriptor that refers to a pipe must be None. +[clinic start generated code]*/ + +static PyObject * +os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count, + PyObject *offset_src, PyObject *offset_dst, + unsigned int flags) +/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/ +{ + off_t offset_src_val, offset_dst_val; + off_t *p_offset_src = NULL; + off_t *p_offset_dst = NULL; + Py_ssize_t ret; + int async_err = 0; + + if (count < 0) { + PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed"); + return NULL; + } + + if (offset_src != Py_None) { + if (!Py_off_t_converter(offset_src, &offset_src_val)) { + return NULL; + } + p_offset_src = &offset_src_val; + } + + if (offset_dst != Py_None) { + if (!Py_off_t_converter(offset_dst, &offset_dst_val)) { + return NULL; + } + p_offset_dst = &offset_dst_val; + } + + do { + Py_BEGIN_ALLOW_THREADS + ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags); + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (ret < 0) { + return (!async_err) ? posix_error() : NULL; + } + + return PyLong_FromSsize_t(ret); +} +#endif /* HAVE_SPLICE*/ + #ifdef HAVE_MKFIFO /*[clinic input] os.mkfifo @@ -11489,7 +11562,7 @@ conv_path_confname(PyObject *arg, int *valuep) /*[clinic input] os.fpathconf -> long - fd: int + fd: fildes name: path_confname / @@ -11500,7 +11573,7 @@ If there is no limit, return -1. static long os_fpathconf_impl(PyObject *module, int fd, int name) -/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/ +/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/ { long limit; @@ -12425,6 +12498,9 @@ check_ShellExecute() os.startfile filepath: path_t operation: Py_UNICODE = NULL + arguments: Py_UNICODE = NULL + cwd: path_t(nullable=True) = None + show_cmd: int = 1 Start a file with its associated application. @@ -12435,6 +12511,16 @@ application (if any) its extension is associated. When another "operation" is given, it specifies what should be done with the file. A typical operation is "print". +"arguments" is passed to the application, but should be omitted if the +file is a document. + +"cwd" is the working directory for the operation. If "filepath" is +relative, it will be resolved against this directory. This argument +should usually be an absolute path. + +"show_cmd" can be used to override the recommended visibility option. +See the Windows ShellExecute documentation for values. + 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 the application's exit status. @@ -12446,8 +12532,9 @@ the underlying Win32 ShellExecute function doesn't work if it is. static PyObject * os_startfile_impl(PyObject *module, path_t *filepath, - const Py_UNICODE *operation) -/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/ + const Py_UNICODE *operation, const Py_UNICODE *arguments, + path_t *cwd, int show_cmd) +/*[clinic end generated code: output=3baa4f9795841880 input=8248997b80669622]*/ { HINSTANCE rc; @@ -12461,10 +12548,15 @@ os_startfile_impl(PyObject *module, path_t *filepath, if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) { return NULL; } + if (PySys_Audit("os.startfile/2", "OuuOi", filepath->object, operation, + arguments, cwd->object ? cwd->object : Py_None, + show_cmd) < 0) { + return NULL; + } Py_BEGIN_ALLOW_THREADS rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide, - NULL, NULL, SW_SHOWNORMAL); + arguments, cwd->wide, show_cmd); Py_END_ALLOW_THREADS if (rc <= (HINSTANCE)32) { @@ -12830,7 +12922,7 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) path_error(path); break; } - buffer = PyMem_MALLOC(buffer_size); + buffer = PyMem_Malloc(buffer_size); if (!buffer) { PyErr_NoMemory(); break; @@ -12847,7 +12939,7 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) if (length < 0) { if (errno == ERANGE) { - PyMem_FREE(buffer); + PyMem_Free(buffer); buffer = NULL; continue; } @@ -12885,7 +12977,7 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) } exit: if (buffer) - PyMem_FREE(buffer); + PyMem_Free(buffer); return result; } #endif /* USE_XATTRS */ @@ -12947,6 +13039,79 @@ os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) } #endif +#ifdef HAVE_EVENTFD +/*[clinic input] +os.eventfd + + initval: unsigned_int + flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC + +Creates and returns an event notification file descriptor. +[clinic start generated code]*/ + +static PyObject * +os_eventfd_impl(PyObject *module, unsigned int initval, int flags) +/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/ + +{ + /* initval is limited to uint32_t, internal counter is uint64_t */ + int fd; + Py_BEGIN_ALLOW_THREADS + fd = eventfd(initval, flags); + Py_END_ALLOW_THREADS + if (fd == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return PyLong_FromLong(fd); +} + +/*[clinic input] +os.eventfd_read + + fd: fildes + +Read eventfd value +[clinic start generated code]*/ + +static PyObject * +os_eventfd_read_impl(PyObject *module, int fd) +/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/ +{ + eventfd_t value; + int result; + Py_BEGIN_ALLOW_THREADS + result = eventfd_read(fd, &value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return PyLong_FromUnsignedLongLong(value); +} + +/*[clinic input] +os.eventfd_write + + fd: fildes + value: unsigned_long_long + +Write eventfd value. +[clinic start generated code]*/ + +static PyObject * +os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value) +/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/ +{ + int result; + Py_BEGIN_ALLOW_THREADS + result = eventfd_write(fd, value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + Py_RETURN_NONE; +} +#endif /* HAVE_EVENTFD */ + /* Terminal size querying */ PyDoc_STRVAR(TerminalSize_docstring, @@ -13077,6 +13242,8 @@ os_cpu_count_impl(PyObject *module) ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) ncpu = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(__VXWORKS__) + ncpu = _Py_popcount32(vxCpuEnabledGet()); #elif defined(__DragonFly__) || \ defined(__OpenBSD__) || \ defined(__FreeBSD__) || \ @@ -13263,14 +13430,6 @@ typedef struct { #endif } DirEntry; -static PyObject * -_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyErr_Format(PyExc_TypeError, - "cannot create '%.100s' instances", _PyType_Name(type)); - return NULL; -} - static void DirEntry_dealloc(DirEntry *entry) { @@ -13325,10 +13484,15 @@ 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; @@ -13355,7 +13519,11 @@ _Py_COMP_DIAG_POP else result = LSTAT(path, &st); } +#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE + PyMem_Free(path); +#else /* USE_UNICODE_WCHAR_CACHE */ Py_DECREF(ub); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (result != 0) return path_object_error(self->path); @@ -13544,18 +13712,24 @@ os_DirEntry_inode_impl(DirEntry *self) #ifdef MS_WINDOWS if (!self->got_file_index) { PyObject *unicode; - const wchar_t *path; STRUCT_STAT stat; int result; if (!PyUnicode_FSDecoder(self->path, &unicode)) return NULL; +#if USE_UNICODE_WCHAR_CACHE _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS - path = PyUnicode_AsUnicode(unicode); -_Py_COMP_DIAG_POP + 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); + PyMem_Free(path); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (result != 0) return path_object_error(self->path); @@ -13614,7 +13788,6 @@ static PyMethodDef DirEntry_methods[] = { }; static PyType_Slot DirEntryType_slots[] = { - {Py_tp_new, _disabled_new}, {Py_tp_dealloc, DirEntry_dealloc}, {Py_tp_repr, DirEntry_repr}, {Py_tp_methods, DirEntry_methods}, @@ -13626,7 +13799,7 @@ static PyType_Spec DirEntryType_spec = { MODNAME ".DirEntry", sizeof(DirEntry), 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, DirEntryType_slots }; @@ -14046,7 +14219,6 @@ static PyMethodDef ScandirIterator_methods[] = { }; static PyType_Slot ScandirIteratorType_slots[] = { - {Py_tp_new, _disabled_new}, {Py_tp_dealloc, ScandirIterator_dealloc}, {Py_tp_finalize, ScandirIterator_finalize}, {Py_tp_iter, PyObject_SelfIter}, @@ -14061,7 +14233,8 @@ static PyType_Spec ScandirIteratorType_spec = { 0, // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance. - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE + | Py_TPFLAGS_DISALLOW_INSTANTIATION), ScandirIteratorType_slots }; @@ -14109,10 +14282,9 @@ os_scandir_impl(PyObject *module, path_t *path) iterator->dirp = NULL; #endif - memcpy(&iterator->path, path, sizeof(path_t)); /* Move the ownership to iterator->path */ - path->object = NULL; - path->cleanup = NULL; + memcpy(&iterator->path, path, sizeof(path_t)); + memset(path, 0, sizeof(path_t)); #ifdef MS_WINDOWS iterator->first_time = 1; @@ -14137,7 +14309,7 @@ os_scandir_impl(PyObject *module, path_t *path) if (iterator->path.fd != -1) { if (HAVE_FDOPENDIR_RUNTIME) { /* closedir() closes the FD, so we duplicate it */ - fd = _Py_dup(path->fd); + fd = _Py_dup(iterator->path.fd); if (fd == -1) goto error; @@ -14427,7 +14599,7 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) os.waitstatus_to_exitcode() is implemented in C and not in Python, so subprocess can safely call it during late Python finalization without - risking that used os attributes were set to None by _PyImport_Cleanup(). */ + risking that used os attributes were set to None by finalize_modules(). */ #if defined(WIFEXITED) || defined(MS_WINDOWS) /*[clinic input] os.waitstatus_to_exitcode @@ -14453,11 +14625,6 @@ static PyObject * os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj) /*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/ { - if (PyFloat_Check(status_obj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - return NULL; - } #ifndef MS_WINDOWS int status = _PyLong_AsInt(status_obj); if (status == -1 && PyErr_Occurred()) { @@ -14549,6 +14716,7 @@ static PyMethodDef posix_methods[] = { OS_POSIX_SPAWNP_METHODDEF OS_READLINK_METHODDEF OS_COPY_FILE_RANGE_METHODDEF + OS_SPLICE_METHODDEF OS_RENAME_METHODDEF OS_REPLACE_METHODDEF OS_RMDIR_METHODDEF @@ -14697,6 +14865,9 @@ static PyMethodDef posix_methods[] = { OS_FSPATH_METHODDEF OS_GETRANDOM_METHODDEF OS_MEMFD_CREATE_METHODDEF + OS_EVENTFD_METHODDEF + OS_EVENTFD_READ_METHODDEF + OS_EVENTFD_WRITE_METHODDEF OS__ADD_DLL_DIRECTORY_METHODDEF OS__REMOVE_DLL_DIRECTORY_METHODDEF OS_WAITSTATUS_TO_EXITCODE_METHODDEF @@ -14822,7 +14993,15 @@ all_ins(PyObject *m) #ifdef O_ACCMODE if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1; #endif - +#ifdef O_EVTONLY + if (PyModule_AddIntMacro(m, O_EVTONLY)) return -1; +#endif +#ifdef O_FSYNC + if (PyModule_AddIntMacro(m, O_FSYNC)) return -1; +#endif +#ifdef O_SYMLINK + if (PyModule_AddIntMacro(m, O_SYMLINK)) return -1; +#endif #ifdef SEEK_HOLE if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1; @@ -14872,6 +15051,9 @@ all_ins(PyObject *m) /* Do not follow links. */ if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1; #endif +#ifdef O_NOFOLLOW_ANY + if (PyModule_AddIntMacro(m, O_NOFOLLOW_ANY)) return -1; +#endif #ifdef O_NOLINKS /* Fails if link count of the named file is greater than 1 */ if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1; @@ -15065,6 +15247,16 @@ all_ins(PyObject *m) #ifdef RWF_NOWAIT if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1; #endif +#ifdef RWF_APPEND + if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1; +#endif + +/* constants for splice */ +#if defined(HAVE_SPLICE) && defined(__linux__) + if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1; + if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1; + if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1; +#endif /* constants for posix_spawn */ #ifdef HAVE_POSIX_SPAWN @@ -15202,6 +15394,12 @@ all_ins(PyObject *m) #ifdef MFD_HUGE_16GB if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1; #endif +#endif /* HAVE_MEMFD_CREATE */ + +#ifdef HAVE_EVENTFD + if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1; + if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1; + if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1; #endif #if defined(__APPLE__) @@ -15295,6 +15493,10 @@ static const struct have_function { int (*probe)(void); } have_functions[] = { +#ifdef HAVE_EVENTFD + {"HAVE_EVENTFD", NULL}, +#endif + #ifdef HAVE_FACCESSAT { "HAVE_FACCESSAT", probe_faccessat }, #endif diff --git a/contrib/tools/python3/src/Modules/pwdmodule.c b/contrib/tools/python3/src/Modules/pwdmodule.c index 901a3ed9a2e..14d3f9dcb1c 100644 --- a/contrib/tools/python3/src/Modules/pwdmodule.c +++ b/contrib/tools/python3/src/Modules/pwdmodule.c @@ -59,8 +59,6 @@ get_pwd_state(PyObject *module) return (pwdmodulestate *)state; } -#define modulestate_global get_pwd_state(PyState_FindModule(&pwdmodule)) - static struct PyModuleDef pwdmodule; #define DEFAULT_BUFFER_SIZE 1024 @@ -79,10 +77,10 @@ sets(PyObject *v, int i, const char* val) } static PyObject * -mkpwent(struct passwd *p) +mkpwent(PyObject *module, struct passwd *p) { int setIndex = 0; - PyObject *v = PyStructSequence_New(modulestate_global->StructPwdType); + PyObject *v = PyStructSequence_New(get_pwd_state(module)->StructPwdType); if (v == NULL) return NULL; @@ -194,7 +192,7 @@ pwd_getpwuid(PyObject *module, PyObject *uidobj) Py_DECREF(uid_obj); return NULL; } - retval = mkpwent(p); + retval = mkpwent(module, p); #ifdef HAVE_GETPWUID_R PyMem_RawFree(buf); #endif @@ -274,7 +272,7 @@ pwd_getpwnam_impl(PyObject *module, PyObject *name) } goto out; } - retval = mkpwent(p); + retval = mkpwent(module, p); out: PyMem_RawFree(buf); Py_DECREF(bytes); @@ -300,7 +298,7 @@ pwd_getpwall_impl(PyObject *module) return NULL; setpwent(); while ((p = getpwent()) != NULL) { - PyObject *v = mkpwent(p); + PyObject *v = mkpwent(module, p); if (v == NULL || PyList_Append(d, v) != 0) { Py_XDECREF(v); Py_DECREF(d); @@ -323,6 +321,26 @@ static PyMethodDef pwd_methods[] = { {NULL, NULL} /* sentinel */ }; +static int +pwdmodule_exec(PyObject *module) +{ + pwdmodulestate *state = get_pwd_state(module); + + state->StructPwdType = PyStructSequence_NewType(&struct_pwd_type_desc); + if (state->StructPwdType == NULL) { + return -1; + } + if (PyModule_AddType(module, state->StructPwdType) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot pwdmodule_slots[] = { + {Py_mod_exec, pwdmodule_exec}, + {0, NULL} +}; + static int pwdmodule_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_pwd_state(m)->StructPwdType); return 0; @@ -337,34 +355,19 @@ static void pwdmodule_free(void *m) { static struct PyModuleDef pwdmodule = { PyModuleDef_HEAD_INIT, - "pwd", - pwd__doc__, - sizeof(pwdmodulestate), - pwd_methods, - NULL, - pwdmodule_traverse, - pwdmodule_clear, - pwdmodule_free, + .m_name = "pwd", + .m_doc = pwd__doc__, + .m_size = sizeof(pwdmodulestate), + .m_methods = pwd_methods, + .m_slots = pwdmodule_slots, + .m_traverse = pwdmodule_traverse, + .m_clear = pwdmodule_clear, + .m_free = pwdmodule_free, }; PyMODINIT_FUNC PyInit_pwd(void) { - PyObject *m; - if ((m = PyState_FindModule(&pwdmodule)) != NULL) { - Py_INCREF(m); - return m; - } - if ((m = PyModule_Create(&pwdmodule)) == NULL) - return NULL; - - pwdmodulestate *state = PyModule_GetState(m); - state->StructPwdType = PyStructSequence_NewType(&struct_pwd_type_desc); - if (state->StructPwdType == NULL) { - return NULL; - } - Py_INCREF(state->StructPwdType); - PyModule_AddObject(m, "struct_passwd", (PyObject *) state->StructPwdType); - return m; + return PyModuleDef_Init(&pwdmodule); } diff --git a/contrib/tools/python3/src/Modules/pyexpat.c b/contrib/tools/python3/src/Modules/pyexpat.c index 12ae66d945b..b3d9bdda7e7 100644 --- a/contrib/tools/python3/src/Modules/pyexpat.c +++ b/contrib/tools/python3/src/Modules/pyexpat.c @@ -47,7 +47,18 @@ enum HandlerTypes { _DummyDecl }; -static PyObject *ErrorObject; +typedef struct { + PyTypeObject *xml_parse_type; + PyObject *error; +} pyexpat_state; + +static inline pyexpat_state* +pyexpat_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (pyexpat_state *)state; +} /* ----------------------------------------------------- */ @@ -73,8 +84,6 @@ typedef struct { #define CHARACTER_DATA_BUFFER_SIZE 8192 -static PyTypeObject Xmlparsetype; - typedef void (*xmlhandlersetter)(XML_Parser self, void *meth); typedef void* xmlhandler; @@ -107,7 +116,7 @@ set_error_attr(PyObject *err, const char *name, int value) * information. Always returns NULL. */ static PyObject * -set_error(xmlparseobject *self, enum XML_Error code) +set_error(pyexpat_state *state, xmlparseobject *self, enum XML_Error code) { PyObject *err; PyObject *buffer; @@ -119,13 +128,13 @@ set_error(xmlparseobject *self, enum XML_Error code) XML_ErrorString(code), lineno, column); if (buffer == NULL) return NULL; - err = PyObject_CallOneArg(ErrorObject, buffer); + err = PyObject_CallOneArg(state->error, buffer); Py_DECREF(buffer); if ( err != NULL && set_error_attr(err, "code", code) && set_error_attr(err, "offset", column) && set_error_attr(err, "lineno", lineno)) { - PyErr_SetObject(ErrorObject, err); + PyErr_SetObject(state->error, err); } Py_XDECREF(err); return NULL; @@ -680,13 +689,13 @@ class pyexpat.xmlparser "xmlparseobject *" "&Xmlparsetype" static PyObject * -get_parse_result(xmlparseobject *self, int rv) +get_parse_result(pyexpat_state *state, xmlparseobject *self, int rv) { if (PyErr_Occurred()) { return NULL; } if (rv == 0) { - return set_error(self, XML_GetErrorCode(self->itself)); + return set_error(state, self, XML_GetErrorCode(self->itself)); } if (flush_character_buffer(self) < 0) { return NULL; @@ -699,6 +708,7 @@ get_parse_result(xmlparseobject *self, int rv) /*[clinic input] pyexpat.xmlparser.Parse + cls: defining_class data: object isfinal: bool(accept={int}) = False / @@ -709,14 +719,15 @@ Parse XML data. [clinic start generated code]*/ static PyObject * -pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, - int isfinal) -/*[clinic end generated code: output=f4db843dd1f4ed4b input=eb616027bfa9847f]*/ +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyTypeObject *cls, + PyObject *data, int isfinal) +/*[clinic end generated code: output=8faffe07fe1f862a input=fc97f833558ca715]*/ { const char *s; Py_ssize_t slen; Py_buffer view; int rc; + pyexpat_state *state = PyType_GetModuleState(cls); if (PyUnicode_Check(data)) { view.buf = NULL; @@ -745,9 +756,10 @@ pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, rc = XML_Parse(self->itself, s, (int)slen, isfinal); done: - if (view.buf != NULL) + if (view.buf != NULL) { PyBuffer_Release(&view); - return get_parse_result(self, rc); + } + return get_parse_result(state, self, rc); } /* File reading copied from cPickle */ @@ -796,6 +808,7 @@ error: /*[clinic input] pyexpat.xmlparser.ParseFile + cls: defining_class file: object / @@ -803,13 +816,16 @@ Parse XML data from file-like object. [clinic start generated code]*/ static PyObject * -pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) -/*[clinic end generated code: output=2adc6a13100cc42b input=fbb5a12b6038d735]*/ +pyexpat_xmlparser_ParseFile_impl(xmlparseobject *self, PyTypeObject *cls, + PyObject *file) +/*[clinic end generated code: output=34780a094c8ca3ae input=ba4bc9c541684793]*/ { int rv = 1; PyObject *readmethod = NULL; _Py_IDENTIFIER(read); + pyexpat_state *state = PyType_GetModuleState(cls); + if (_PyObject_LookupAttrId(file, &PyId_read, &readmethod) < 0) { return NULL; } @@ -823,7 +839,7 @@ pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) void *buf = XML_GetBuffer(self->itself, BUF_SIZE); if (buf == NULL) { Py_XDECREF(readmethod); - return get_parse_result(self, 0); + return get_parse_result(state, self, 0); } bytes_read = readinst(buf, BUF_SIZE, readmethod); @@ -841,7 +857,7 @@ pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) break; } Py_XDECREF(readmethod); - return get_parse_result(self, rv); + return get_parse_result(state, self, rv); } /*[clinic input] @@ -907,6 +923,7 @@ pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self) /*[clinic input] pyexpat.xmlparser.ExternalEntityParserCreate + cls: defining_class context: str(accept={str, NoneType}) encoding: str = NULL / @@ -916,16 +933,21 @@ Create a parser for parsing an external entity based on the information passed t static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, + PyTypeObject *cls, const char *context, const char *encoding) -/*[clinic end generated code: output=535cda9d7a0fbcd6 input=b906714cc122c322]*/ +/*[clinic end generated code: output=01d4472b49cb3f92 input=ec70c6b9e6e9619a]*/ { xmlparseobject *new_parser; int i; - new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype); - if (new_parser == NULL) + pyexpat_state *state = PyType_GetModuleState(cls); + + new_parser = PyObject_GC_New(xmlparseobject, state->xml_parse_type); + if (new_parser == NULL) { return NULL; + } + new_parser->buffer_size = self->buffer_size; new_parser->buffer_used = 0; new_parser->buffer = NULL; @@ -1006,6 +1028,7 @@ pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag) /*[clinic input] pyexpat.xmlparser.UseForeignDTD + cls: defining_class flag: bool = True / @@ -1017,14 +1040,16 @@ information to the parser. 'flag' defaults to True if not provided. [clinic start generated code]*/ static PyObject * -pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag) -/*[clinic end generated code: output=cfaa9aa50bb0f65c input=78144c519d116a6e]*/ +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, PyTypeObject *cls, + int flag) +/*[clinic end generated code: output=d7d98252bd25a20f input=23440ecb0573fb29]*/ { + pyexpat_state *state = PyType_GetModuleState(cls); enum XML_Error rc; rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE); if (rc != XML_ERROR_NONE) { - return set_error(self, rc); + return set_error(state, self, rc); } Py_RETURN_NONE; } @@ -1104,12 +1129,13 @@ PyUnknownEncodingHandler(void *encodingHandlerData, static PyObject * -newxmlparseobject(const char *encoding, const char *namespace_separator, PyObject *intern) +newxmlparseobject(pyexpat_state *state, const char *encoding, + const char *namespace_separator, PyObject *intern) { int i; xmlparseobject *self; - self = PyObject_GC_New(xmlparseobject, &Xmlparsetype); + self = PyObject_GC_New(xmlparseobject, state->xml_parse_type); if (self == NULL) return NULL; @@ -1156,19 +1182,34 @@ newxmlparseobject(const char *encoding, const char *namespace_separator, PyObjec return (PyObject*)self; } +static int +xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg) +{ + for (int i = 0; handler_info[i].name != NULL; i++) { + Py_VISIT(op->handlers[i]); + } + Py_VISIT(Py_TYPE(op)); + return 0; +} + +static int +xmlparse_clear(xmlparseobject *op) +{ + clear_handlers(op, 0); + Py_CLEAR(op->intern); + return 0; +} static void xmlparse_dealloc(xmlparseobject *self) { - int i; PyObject_GC_UnTrack(self); + (void)xmlparse_clear(self); if (self->itself != NULL) XML_ParserFree(self->itself); self->itself = NULL; if (self->handlers != NULL) { - for (i = 0; handler_info[i].name != NULL; i++) - Py_CLEAR(self->handlers[i]); PyMem_Free(self->handlers); self->handlers = NULL; } @@ -1176,8 +1217,9 @@ xmlparse_dealloc(xmlparseobject *self) PyMem_Free(self->buffer); self->buffer = NULL; } - Py_XDECREF(self->intern); + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_Del(self); + Py_DECREF(tp); } @@ -1445,57 +1487,25 @@ static PyGetSetDef xmlparse_getsetlist[] = { #undef XMLPARSE_GETTER_DEF #undef XMLPARSE_GETTER_SETTER_DEF -static int -xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg) -{ - int i; - for (i = 0; handler_info[i].name != NULL; i++) - Py_VISIT(op->handlers[i]); - return 0; -} - -static int -xmlparse_clear(xmlparseobject *op) -{ - clear_handlers(op, 0); - Py_CLEAR(op->intern); - return 0; -} - PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser"); -static PyTypeObject Xmlparsetype = { - PyVarObject_HEAD_INIT(NULL, 0) - "pyexpat.xmlparser", /*tp_name*/ - sizeof(xmlparseobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)xmlparse_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ - (getattrofunc)0, /* tp_getattro */ - (setattrofunc)0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - Xmlparsetype__doc__, /* tp_doc - Documentation string */ - (traverseproc)xmlparse_traverse, /* tp_traverse */ - (inquiry)xmlparse_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparse_methods, /* tp_methods */ - xmlparse_members, /* tp_members */ - xmlparse_getsetlist, /* tp_getset */ +static PyType_Slot _xml_parse_type_spec_slots[] = { + {Py_tp_dealloc, xmlparse_dealloc}, + {Py_tp_doc, (void *)Xmlparsetype__doc__}, + {Py_tp_traverse, xmlparse_traverse}, + {Py_tp_clear, xmlparse_clear}, + {Py_tp_methods, xmlparse_methods}, + {Py_tp_members, xmlparse_members}, + {Py_tp_getset, xmlparse_getsetlist}, + {0, 0} +}; + +static PyType_Spec _xml_parse_type_spec = { + .name = "pyexpat.xmlparser", + .basicsize = sizeof(xmlparseobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = _xml_parse_type_spec_slots, }; /* End of code for xmlparser objects */ @@ -1541,7 +1551,8 @@ pyexpat_ParserCreate_impl(PyObject *module, const char *encoding, return NULL; } - result = newxmlparseobject(encoding, namespace_separator, intern); + pyexpat_state *state = pyexpat_get_state(module); + result = newxmlparseobject(state, encoding, namespace_separator, intern); if (intern_decref) { Py_DECREF(intern); } @@ -1583,26 +1594,10 @@ PyDoc_STRVAR(pyexpat_module_documentation, #define MODULE_NAME "pyexpat" #endif -#ifndef MODULE_INITFUNC -#define MODULE_INITFUNC PyInit_pyexpat -#endif - -static struct PyModuleDef pyexpatmodule = { - PyModuleDef_HEAD_INIT, - MODULE_NAME, - pyexpat_module_documentation, - -1, - pyexpat_methods, - NULL, - NULL, - NULL, - NULL -}; - -static int init_handler_descrs(void) +static int init_handler_descrs(pyexpat_state *state) { int i; - assert(!PyType_HasFeature(&Xmlparsetype, Py_TPFLAGS_VALID_VERSION_TAG)); + assert(!PyType_HasFeature(state->xml_parse_type, Py_TPFLAGS_VALID_VERSION_TAG)); for (i = 0; handler_info[i].name != NULL; i++) { struct HandlerInfo *hi = &handler_info[i]; hi->getset.name = hi->name; @@ -1610,19 +1605,11 @@ static int init_handler_descrs(void) hi->getset.set = (setter)xmlparse_handler_setter; hi->getset.closure = &handler_info[i]; - PyObject *descr = PyDescr_NewGetSet(&Xmlparsetype, &hi->getset); + PyObject *descr = PyDescr_NewGetSet(state->xml_parse_type, &hi->getset); if (descr == NULL) return -1; - if (PyDict_GetItemWithError(Xmlparsetype.tp_dict, PyDescr_NAME(descr))) { - Py_DECREF(descr); - continue; - } - else if (PyErr_Occurred()) { - Py_DECREF(descr); - return -1; - } - if (PyDict_SetItem(Xmlparsetype.tp_dict, PyDescr_NAME(descr), descr) < 0) { + if (PyDict_SetDefault(state->xml_parse_type->tp_dict, PyDescr_NAME(descr), descr) == NULL) { Py_DECREF(descr); return -1; } @@ -1631,210 +1618,182 @@ static int init_handler_descrs(void) return 0; } -PyMODINIT_FUNC -MODULE_INITFUNC(void) +static PyObject * +add_submodule(PyObject *mod, const char *fullname) { - PyObject *m, *d; - PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors"); - PyObject *errors_module; - PyObject *modelmod_name; - PyObject *model_module; - PyObject *tmpnum, *tmpstr; - PyObject *codes_dict; - PyObject *rev_codes_dict; - int res; - static struct PyExpat_CAPI capi; - PyObject *capi_object; - - if (errmod_name == NULL) - return NULL; - modelmod_name = PyUnicode_FromString(MODULE_NAME ".model"); - if (modelmod_name == NULL) + const char *name = strrchr(fullname, '.') + 1; + + PyObject *submodule = PyModule_New(fullname); + if (submodule == NULL) { return NULL; + } - if (PyType_Ready(&Xmlparsetype) < 0 || init_handler_descrs() < 0) + PyObject *mod_name = PyUnicode_FromString(fullname); + if (mod_name == NULL) { + Py_DECREF(submodule); return NULL; + } - /* Create the module and add the functions */ - m = PyModule_Create(&pyexpatmodule); - if (m == NULL) + if (_PyImport_SetModule(mod_name, submodule) < 0) { + Py_DECREF(submodule); + Py_DECREF(mod_name); return NULL; + } + Py_DECREF(mod_name); - /* Add some symbolic constants to the module */ - if (ErrorObject == NULL) { - ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError", - NULL, NULL); - if (ErrorObject == NULL) - return NULL; + /* gives away the reference to the submodule */ + if (PyModule_AddObject(mod, name, submodule) < 0) { + Py_DECREF(submodule); + return NULL; } - Py_INCREF(ErrorObject); - PyModule_AddObject(m, "error", ErrorObject); - Py_INCREF(ErrorObject); - PyModule_AddObject(m, "ExpatError", ErrorObject); - Py_INCREF(&Xmlparsetype); - PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - PyModule_AddStringConstant(m, "EXPAT_VERSION", - XML_ExpatVersion()); - { - XML_Expat_Version info = XML_ExpatVersionInfo(); - PyModule_AddObject(m, "version_info", - Py_BuildValue("(iii)", info.major, - info.minor, info.micro)); + return submodule; +} + +static int +add_error(PyObject *errors_module, PyObject *codes_dict, + PyObject *rev_codes_dict, const char *name, int value) +{ + const char *error_string = XML_ErrorString(value); + if (PyModule_AddStringConstant(errors_module, name, error_string) < 0) { + return -1; } - /* XXX When Expat supports some way of figuring out how it was - compiled, this should check and set native_encoding - appropriately. - */ - PyModule_AddStringConstant(m, "native_encoding", "UTF-8"); - d = PyModule_GetDict(m); - if (d == NULL) { - Py_DECREF(m); - return NULL; + PyObject *num = PyLong_FromLong(value); + if (num == NULL) { + return -1; } - errors_module = PyDict_GetItemWithError(d, errmod_name); - if (errors_module == NULL && !PyErr_Occurred()) { - errors_module = PyModule_New(MODULE_NAME ".errors"); - if (errors_module != NULL) { - _PyImport_SetModule(errmod_name, errors_module); - /* gives away the reference to errors_module */ - PyModule_AddObject(m, "errors", errors_module); - } + + if (PyDict_SetItemString(codes_dict, error_string, num) < 0) { + Py_DECREF(num); + return -1; } - Py_DECREF(errmod_name); - model_module = PyDict_GetItemWithError(d, modelmod_name); - if (model_module == NULL && !PyErr_Occurred()) { - model_module = PyModule_New(MODULE_NAME ".model"); - if (model_module != NULL) { - _PyImport_SetModule(modelmod_name, model_module); - /* gives away the reference to model_module */ - PyModule_AddObject(m, "model", model_module); - } + + PyObject *str = PyUnicode_FromString(error_string); + if (str == NULL) { + Py_DECREF(num); + return -1; } - Py_DECREF(modelmod_name); - if (errors_module == NULL || model_module == NULL) { - /* Don't core dump later! */ - Py_DECREF(m); - return NULL; + + int res = PyDict_SetItem(rev_codes_dict, num, str); + Py_DECREF(str); + Py_DECREF(num); + if (res < 0) { + return -1; } -#if XML_COMBINED_VERSION > 19505 - { - const XML_Feature *features = XML_GetFeatureList(); - PyObject *list = PyList_New(0); - if (list == NULL) - /* just ignore it */ - PyErr_Clear(); - else { - int i = 0; - for (; features[i].feature != XML_FEATURE_END; ++i) { - int ok; - PyObject *item = Py_BuildValue("si", features[i].name, - features[i].value); - if (item == NULL) { - Py_DECREF(list); - list = NULL; - break; - } - ok = PyList_Append(list, item); - Py_DECREF(item); - if (ok < 0) { - PyErr_Clear(); - break; - } - } - if (list != NULL) - PyModule_AddObject(m, "features", list); - } + return 0; +} + +static int +add_errors_module(PyObject *mod) +{ + PyObject *errors_module = add_submodule(mod, MODULE_NAME ".errors"); + if (errors_module == NULL) { + return -1; } -#endif - codes_dict = PyDict_New(); - rev_codes_dict = PyDict_New(); + PyObject *codes_dict = PyDict_New(); + PyObject *rev_codes_dict = PyDict_New(); if (codes_dict == NULL || rev_codes_dict == NULL) { - Py_XDECREF(codes_dict); - Py_XDECREF(rev_codes_dict); - return NULL; + goto error; } -#define MYCONST(name) \ - if (PyModule_AddStringConstant(errors_module, #name, \ - XML_ErrorString(name)) < 0) \ - return NULL; \ - tmpnum = PyLong_FromLong(name); \ - if (tmpnum == NULL) return NULL; \ - res = PyDict_SetItemString(codes_dict, \ - XML_ErrorString(name), tmpnum); \ - if (res < 0) return NULL; \ - tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \ - if (tmpstr == NULL) return NULL; \ - res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \ - Py_DECREF(tmpstr); \ - Py_DECREF(tmpnum); \ - if (res < 0) return NULL; \ - - MYCONST(XML_ERROR_NO_MEMORY); - MYCONST(XML_ERROR_SYNTAX); - MYCONST(XML_ERROR_NO_ELEMENTS); - MYCONST(XML_ERROR_INVALID_TOKEN); - MYCONST(XML_ERROR_UNCLOSED_TOKEN); - MYCONST(XML_ERROR_PARTIAL_CHAR); - MYCONST(XML_ERROR_TAG_MISMATCH); - MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE); - MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT); - MYCONST(XML_ERROR_PARAM_ENTITY_REF); - MYCONST(XML_ERROR_UNDEFINED_ENTITY); - MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF); - MYCONST(XML_ERROR_ASYNC_ENTITY); - MYCONST(XML_ERROR_BAD_CHAR_REF); - MYCONST(XML_ERROR_BINARY_ENTITY_REF); - MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF); - MYCONST(XML_ERROR_MISPLACED_XML_PI); - MYCONST(XML_ERROR_UNKNOWN_ENCODING); - MYCONST(XML_ERROR_INCORRECT_ENCODING); - MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION); - MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING); - MYCONST(XML_ERROR_NOT_STANDALONE); - MYCONST(XML_ERROR_UNEXPECTED_STATE); - MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE); - MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD); - MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING); +#define ADD_CONST(name) do { \ + if (add_error(errors_module, codes_dict, rev_codes_dict, \ + #name, name) < 0) { \ + goto error; \ + } \ + } while(0) + + ADD_CONST(XML_ERROR_NO_MEMORY); + ADD_CONST(XML_ERROR_SYNTAX); + ADD_CONST(XML_ERROR_NO_ELEMENTS); + ADD_CONST(XML_ERROR_INVALID_TOKEN); + ADD_CONST(XML_ERROR_UNCLOSED_TOKEN); + ADD_CONST(XML_ERROR_PARTIAL_CHAR); + ADD_CONST(XML_ERROR_TAG_MISMATCH); + ADD_CONST(XML_ERROR_DUPLICATE_ATTRIBUTE); + ADD_CONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT); + ADD_CONST(XML_ERROR_PARAM_ENTITY_REF); + ADD_CONST(XML_ERROR_UNDEFINED_ENTITY); + ADD_CONST(XML_ERROR_RECURSIVE_ENTITY_REF); + ADD_CONST(XML_ERROR_ASYNC_ENTITY); + ADD_CONST(XML_ERROR_BAD_CHAR_REF); + ADD_CONST(XML_ERROR_BINARY_ENTITY_REF); + ADD_CONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF); + ADD_CONST(XML_ERROR_MISPLACED_XML_PI); + ADD_CONST(XML_ERROR_UNKNOWN_ENCODING); + ADD_CONST(XML_ERROR_INCORRECT_ENCODING); + ADD_CONST(XML_ERROR_UNCLOSED_CDATA_SECTION); + ADD_CONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING); + ADD_CONST(XML_ERROR_NOT_STANDALONE); + ADD_CONST(XML_ERROR_UNEXPECTED_STATE); + ADD_CONST(XML_ERROR_ENTITY_DECLARED_IN_PE); + ADD_CONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD); + ADD_CONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING); /* Added in Expat 1.95.7. */ - MYCONST(XML_ERROR_UNBOUND_PREFIX); + ADD_CONST(XML_ERROR_UNBOUND_PREFIX); /* Added in Expat 1.95.8. */ - MYCONST(XML_ERROR_UNDECLARING_PREFIX); - MYCONST(XML_ERROR_INCOMPLETE_PE); - MYCONST(XML_ERROR_XML_DECL); - MYCONST(XML_ERROR_TEXT_DECL); - MYCONST(XML_ERROR_PUBLICID); - MYCONST(XML_ERROR_SUSPENDED); - MYCONST(XML_ERROR_NOT_SUSPENDED); - MYCONST(XML_ERROR_ABORTED); - MYCONST(XML_ERROR_FINISHED); - MYCONST(XML_ERROR_SUSPEND_PE); + ADD_CONST(XML_ERROR_UNDECLARING_PREFIX); + ADD_CONST(XML_ERROR_INCOMPLETE_PE); + ADD_CONST(XML_ERROR_XML_DECL); + ADD_CONST(XML_ERROR_TEXT_DECL); + ADD_CONST(XML_ERROR_PUBLICID); + ADD_CONST(XML_ERROR_SUSPENDED); + ADD_CONST(XML_ERROR_NOT_SUSPENDED); + ADD_CONST(XML_ERROR_ABORTED); + ADD_CONST(XML_ERROR_FINISHED); + ADD_CONST(XML_ERROR_SUSPEND_PE); +#undef ADD_CONST if (PyModule_AddStringConstant(errors_module, "__doc__", "Constants used to describe " - "error conditions.") < 0) - return NULL; + "error conditions.") < 0) { + goto error; + } - if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0) - return NULL; - if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0) - return NULL; + Py_INCREF(codes_dict); + if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0) { + Py_DECREF(codes_dict); + goto error; + } + Py_CLEAR(codes_dict); -#undef MYCONST + Py_INCREF(rev_codes_dict); + if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0) { + Py_DECREF(rev_codes_dict); + goto error; + } + Py_CLEAR(rev_codes_dict); -#define MYCONST(c) PyModule_AddIntConstant(m, #c, c) - MYCONST(XML_PARAM_ENTITY_PARSING_NEVER); - MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); - MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS); -#undef MYCONST + return 0; -#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c) - PyModule_AddStringConstant(model_module, "__doc__", - "Constants used to interpret content model information."); +error: + Py_XDECREF(codes_dict); + Py_XDECREF(rev_codes_dict); + return -1; +} + +static int +add_model_module(PyObject *mod) +{ + PyObject *model_module = add_submodule(mod, MODULE_NAME ".model"); + if (model_module == NULL) { + return -1; + } + +#define MYCONST(c) do { \ + if (PyModule_AddIntConstant(model_module, #c, c) < 0) { \ + return -1; \ + } \ + } while(0) + + if (PyModule_AddStringConstant( + model_module, "__doc__", + "Constants used to interpret content model information.") < 0) { + return -1; + } MYCONST(XML_CTYPE_EMPTY); MYCONST(XML_CTYPE_ANY); @@ -1848,42 +1807,228 @@ MODULE_INITFUNC(void) MYCONST(XML_CQUANT_REP); MYCONST(XML_CQUANT_PLUS); #undef MYCONST + return 0; +} + +#if XML_COMBINED_VERSION > 19505 +static int +add_features(PyObject *mod) +{ + PyObject *list = PyList_New(0); + if (list == NULL) { + return -1; + } + + const XML_Feature *features = XML_GetFeatureList(); + for (size_t i = 0; features[i].feature != XML_FEATURE_END; ++i) { + PyObject *item = Py_BuildValue("si", features[i].name, + features[i].value); + if (item == NULL) { + goto error; + } + int ok = PyList_Append(list, item); + Py_DECREF(item); + if (ok < 0) { + goto error; + } + } + if (PyModule_AddObject(mod, "features", list) < 0) { + goto error; + } + return 0; + +error: + Py_DECREF(list); + return -1; +} +#endif + +static void +pyexpat_destructor(PyObject *op) +{ + void *p = PyCapsule_GetPointer(op, PyExpat_CAPSULE_NAME); + PyMem_Free(p); +} + +static int +pyexpat_exec(PyObject *mod) +{ + pyexpat_state *state = pyexpat_get_state(mod); + state->xml_parse_type = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &_xml_parse_type_spec, NULL); + + if (state->xml_parse_type == NULL) { + return -1; + } + + if (init_handler_descrs(state) < 0) { + return -1; + } + state->error = PyErr_NewException("xml.parsers.expat.ExpatError", + NULL, NULL); + if (state->error == NULL) { + return -1; + } + + /* Add some symbolic constants to the module */ + + if (PyModule_AddObjectRef(mod, "error", state->error) < 0) { + return -1; + } + + if (PyModule_AddObjectRef(mod, "ExpatError", state->error) < 0) { + return -1; + } + + if (PyModule_AddObjectRef(mod, "XMLParserType", + (PyObject *) state->xml_parse_type) < 0) { + return -1; + } + + if (PyModule_AddStringConstant(mod, "EXPAT_VERSION", + XML_ExpatVersion()) < 0) { + return -1; + } + { + XML_Expat_Version info = XML_ExpatVersionInfo(); + PyObject *versionInfo = Py_BuildValue("(iii)", + info.major, + info.minor, + info.micro); + if (PyModule_AddObject(mod, "version_info", versionInfo) < 0) { + Py_DECREF(versionInfo); + return -1; + } + } + /* XXX When Expat supports some way of figuring out how it was + compiled, this should check and set native_encoding + appropriately. + */ + if (PyModule_AddStringConstant(mod, "native_encoding", "UTF-8") < 0) { + return -1; + } + + if (add_errors_module(mod) < 0) { + return -1; + } + + if (add_model_module(mod) < 0) { + return -1; + } + +#if XML_COMBINED_VERSION > 19505 + if (add_features(mod) < 0) { + return -1; + } +#endif + +#define MYCONST(c) do { \ + if (PyModule_AddIntConstant(mod, #c, c) < 0) { \ + return -1; \ + } \ + } while(0) + + MYCONST(XML_PARAM_ENTITY_PARSING_NEVER); + MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); + MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS); +#undef MYCONST + struct PyExpat_CAPI *capi = PyMem_Calloc(1, sizeof(struct PyExpat_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 */ - capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL); - if (capi_object) - PyModule_AddObject(m, "expat_CAPI", capi_object); - return m; + PyObject *capi_object = PyCapsule_New(capi, PyExpat_CAPSULE_NAME, + pyexpat_destructor); + if (capi_object == NULL) { + PyMem_Free(capi); + return -1; + } + + if (PyModule_AddObject(mod, "expat_CAPI", capi_object) < 0) { + Py_DECREF(capi_object); + return -1; + } + + return 0; +} + +static int +pyexpat_traverse(PyObject *module, visitproc visit, void *arg) +{ + pyexpat_state *state = pyexpat_get_state(module); + Py_VISIT(state->xml_parse_type); + Py_VISIT(state->error); + return 0; +} + +static int +pyexpat_clear(PyObject *module) +{ + pyexpat_state *state = pyexpat_get_state(module); + Py_CLEAR(state->xml_parse_type); + Py_CLEAR(state->error); + return 0; +} + +static void +pyexpat_free(void *module) +{ + pyexpat_clear((PyObject *)module); +} + +static PyModuleDef_Slot pyexpat_slots[] = { + {Py_mod_exec, pyexpat_exec}, + {0, NULL} +}; + +static struct PyModuleDef pyexpatmodule = { + PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = pyexpat_module_documentation, + .m_size = sizeof(pyexpat_state), + .m_methods = pyexpat_methods, + .m_slots = pyexpat_slots, + .m_traverse = pyexpat_traverse, + .m_clear = pyexpat_clear, + .m_free = pyexpat_free +}; + +PyMODINIT_FUNC +PyInit_pyexpat(void) +{ + return PyModuleDef_Init(&pyexpatmodule); } static void diff --git a/contrib/tools/python3/src/Modules/resource.c b/contrib/tools/python3/src/Modules/resource.c index ddbf80be9c6..0d69c2983b4 100644 --- a/contrib/tools/python3/src/Modules/resource.c +++ b/contrib/tools/python3/src/Modules/resource.c @@ -63,8 +63,20 @@ static PyStructSequence_Desc struct_rusage_desc = { 16 /* n_in_sequence */ }; -static int initialized; -static PyTypeObject StructRUsageType; +typedef struct { + PyTypeObject *StructRUsageType; +} resourcemodulestate; + + +static inline resourcemodulestate* +get_resource_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (resourcemodulestate *)state; +} + +static struct PyModuleDef resourcemodule; /*[clinic input] resource.getrusage @@ -91,7 +103,8 @@ resource_getrusage_impl(PyObject *module, int who) return NULL; } - result = PyStructSequence_New(&StructRUsageType); + result = PyStructSequence_New( + get_resource_state(module)->StructRUsageType); if (!result) return NULL; @@ -313,13 +326,10 @@ resource_getpagesize_impl(PyObject *module) long pagesize = 0; #if defined(HAVE_GETPAGESIZE) pagesize = getpagesize(); -#elif defined(HAVE_SYSCONF) -#if defined(_SC_PAGE_SIZE) +#elif defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) pagesize = sysconf(_SC_PAGE_SIZE); #else - /* Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE */ - pagesize = sysconf(_SC_PAGESIZE); -#endif +# error "unsupported platform: resource.getpagesize()" #endif return pagesize; } @@ -339,10 +349,10 @@ resource_methods[] = { /* Module initialization */ - static int resource_exec(PyObject *module) { + resourcemodulestate *state = get_resource_state(module); #define ADD_INT(module, value) \ do { \ if (PyModule_AddIntConstant(module, #value, value) < 0) { \ @@ -356,13 +366,12 @@ resource_exec(PyObject *module) Py_DECREF(PyExc_OSError); return -1; } - if (!initialized) { - if (PyStructSequence_InitType2(&StructRUsageType, - &struct_rusage_desc) < 0) - return -1; - } - if(PyModule_AddType(module, &StructRUsageType) < 0) { + state->StructRUsageType = PyStructSequence_NewType(&struct_rusage_desc); + if (state->StructRUsageType == NULL) { + return -1; + } + if (PyModule_AddType(module, state->StructRUsageType) < 0) { return -1; } @@ -471,6 +480,10 @@ resource_exec(PyObject *module) ADD_INT(module, RLIMIT_NPTS); #endif +#ifdef RLIMIT_KQUEUES + ADD_INT(module, RLIMIT_KQUEUES); +#endif + PyObject *v; if (sizeof(RLIM_INFINITY) > sizeof(long)) { v = PyLong_FromLongLong((long long) RLIM_INFINITY); @@ -486,8 +499,6 @@ resource_exec(PyObject *module) Py_DECREF(v); return -1; } - - initialized = 1; return 0; #undef ADD_INT @@ -498,12 +509,32 @@ static struct PyModuleDef_Slot resource_slots[] = { {0, NULL} }; +static int +resourcemodule_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(get_resource_state(m)->StructRUsageType); + return 0; +} + +static int +resourcemodule_clear(PyObject *m) { + Py_CLEAR(get_resource_state(m)->StructRUsageType); + return 0; +} + +static void +resourcemodule_free(void *m) { + resourcemodule_clear((PyObject *)m); +} + static struct PyModuleDef resourcemodule = { PyModuleDef_HEAD_INIT, .m_name = "resource", - .m_size = 0, + .m_size = sizeof(resourcemodulestate), .m_methods = resource_methods, .m_slots = resource_slots, + .m_traverse = resourcemodule_traverse, + .m_clear = resourcemodule_clear, + .m_free = resourcemodule_free, }; PyMODINIT_FUNC diff --git a/contrib/tools/python3/src/Modules/selectmodule.c b/contrib/tools/python3/src/Modules/selectmodule.c index d4af4f7b52d..3afcb0e2a02 100644 --- a/contrib/tools/python3/src/Modules/selectmodule.c +++ b/contrib/tools/python3/src/Modules/selectmodule.c @@ -77,35 +77,16 @@ get_select_state(PyObject *module) return (_selectstate *)state; } -#define _selectstate_global get_select_state(PyState_FindModule(&selectmodule)) +#define _selectstate_by_type(type) get_select_state(PyType_GetModule(type)) /*[clinic input] module select -class select.poll "pollObject *" "&poll_Type" -class select.devpoll "devpollObject *" "&devpoll_Type" -class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" -class select.kqueue "kqueue_queue_Object *" "_selectstate_global->kqueue_queue_Type" +class select.poll "pollObject *" "_selectstate_by_type(type)->poll_Type" +class select.devpoll "devpollObject *" "_selectstate_by_type(type)->devpoll_Type" +class select.epoll "pyEpoll_Object *" "_selectstate_by_type(type)->pyEpoll_Type" +class select.kqueue "kqueue_queue_Object *" "_selectstate_by_type(type)->kqueue_queue_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/ - -static int -fildes_converter(PyObject *o, void *p) -{ - int fd; - int *pointer = (int *)p; - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) - return 0; - *pointer = fd; - return 1; -} - -/*[python input] -class fildes_converter(CConverter): - type = 'int' - converter = 'fildes_converter' -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8072de35824aa327]*/ /* list of Python objects and their file descriptor */ typedef struct { @@ -313,9 +294,9 @@ select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) { - if (rfd2obj) PyMem_DEL(rfd2obj); - if (wfd2obj) PyMem_DEL(wfd2obj); - if (efd2obj) PyMem_DEL(efd2obj); + if (rfd2obj) PyMem_Free(rfd2obj); + if (wfd2obj) PyMem_Free(wfd2obj); + if (efd2obj) PyMem_Free(efd2obj); return PyErr_NoMemory(); } #endif /* SELECT_USES_HEAP */ @@ -400,9 +381,9 @@ select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, reap_obj(wfd2obj); reap_obj(efd2obj); #ifdef SELECT_USES_HEAP - PyMem_DEL(rfd2obj); - PyMem_DEL(wfd2obj); - PyMem_DEL(efd2obj); + PyMem_Free(rfd2obj); + PyMem_Free(wfd2obj); + PyMem_Free(efd2obj); #endif /* SELECT_USES_HEAP */ return ret; } @@ -518,11 +499,14 @@ select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask) key = PyLong_FromLong(fd); if (key == NULL) return NULL; - if (PyDict_GetItemWithError(self->dict, key) == NULL) { - if (!PyErr_Occurred()) { - errno = ENOENT; - PyErr_SetFromErrno(PyExc_OSError); - } + err = PyDict_Contains(self->dict, key); + if (err < 0) { + Py_DECREF(key); + return NULL; + } + if (err == 0) { + errno = ENOENT; + PyErr_SetFromErrno(PyExc_OSError); Py_DECREF(key); return NULL; } @@ -727,10 +711,10 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) } static pollObject * -newPollObject(void) +newPollObject(PyObject *module) { pollObject *self; - self = PyObject_New(pollObject, _selectstate_global->poll_Type); + self = PyObject_New(pollObject, get_select_state(module)->poll_Type); if (self == NULL) return NULL; /* ufd_uptodate is a Boolean, denoting whether the @@ -746,21 +730,14 @@ newPollObject(void) return self; } -static PyObject * -poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type)); - return NULL; -} - static void poll_dealloc(pollObject *self) { PyObject* type = (PyObject *)Py_TYPE(self); if (self->ufds != NULL) - PyMem_DEL(self->ufds); + PyMem_Free(self->ufds); Py_XDECREF(self->dict); - PyObject_Del(self); + PyObject_Free(self); Py_DECREF(type); } @@ -1093,7 +1070,7 @@ static PyGetSetDef devpoll_getsetlist[] = { }; static devpollObject * -newDevPollObject(void) +newDevPollObject(PyObject *module) { devpollObject *self; int fd_devpoll, limit_result; @@ -1123,10 +1100,10 @@ newDevPollObject(void) return NULL; } - self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type); + self = PyObject_New(devpollObject, get_select_state(module)->devpoll_Type); if (self == NULL) { close(fd_devpoll); - PyMem_DEL(fds); + PyMem_Free(fds); return NULL; } self->fd_devpoll = fd_devpoll; @@ -1137,20 +1114,13 @@ newDevPollObject(void) return self; } -static PyObject * -devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type)); - return NULL; -} - static void devpoll_dealloc(devpollObject *self) { PyObject *type = (PyObject *)Py_TYPE(self); (void)devpoll_internal_close(self); - PyMem_DEL(self->fds); - PyObject_Del(self); + PyMem_Free(self->fds); + PyObject_Free(self); Py_DECREF(type); } @@ -1158,7 +1128,6 @@ static PyType_Slot devpoll_Type_slots[] = { {Py_tp_dealloc, devpoll_dealloc}, {Py_tp_getset, devpoll_getsetlist}, {Py_tp_methods, devpoll_methods}, - {Py_tp_new, devpoll_new}, {0, 0}, }; @@ -1166,7 +1135,7 @@ static PyType_Spec devpoll_Type_spec = { "select.devpoll", sizeof(devpollObject), 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, devpoll_Type_slots }; @@ -1186,7 +1155,7 @@ static PyObject * select_poll_impl(PyObject *module) /*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/ { - return (PyObject *)newPollObject(); + return (PyObject *)newPollObject(module); } #ifdef HAVE_SYS_DEVPOLL_H @@ -1204,7 +1173,7 @@ static PyObject * select_devpoll_impl(PyObject *module) /*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/ { - return (PyObject *)newDevPollObject(); + return (PyObject *)newDevPollObject(module); } #endif @@ -1258,8 +1227,6 @@ typedef struct { SOCKET epfd; /* epoll control file descriptor */ } pyEpoll_Object; -#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type)) - static PyObject * pyepoll_err_closed(void) { @@ -1687,7 +1654,8 @@ select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb) /*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/ { - return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL); + _selectstate *state = _selectstate_by_type(Py_TYPE(self)); + return PyObject_CallMethodObjArgs((PyObject *)self, state->close, NULL); } static PyGetSetDef pyepoll_getsetlist[] = { @@ -1761,15 +1729,13 @@ typedef struct { struct kevent e; } kqueue_event_Object; -#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type)) +#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type)) typedef struct { PyObject_HEAD SOCKET kqfd; /* kqueue control fd */ } kqueue_queue_Object; -#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type)) - #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) # error uintptr_t does not match void *! #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) @@ -1910,8 +1876,9 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, int op) { int result; + _selectstate *state = _selectstate_by_type(Py_TYPE(s)); - if (!kqueue_event_Check(o)) { + if (!kqueue_event_Check(o, state)) { Py_RETURN_NOTIMPLEMENTED; } @@ -2133,6 +2100,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, struct timespec timeoutspec; struct timespec *ptimeoutspec; _PyTime_t timeout, deadline = 0; + _selectstate *state = _selectstate_by_type(Py_TYPE(self)); if (self->kqfd < 0) return kqueue_queue_err_closed(); @@ -2185,9 +2153,10 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, PyErr_NoMemory(); goto error; } + _selectstate *state = _selectstate_by_type(Py_TYPE(self)); for (i = 0; i < nchanges; ++i) { ei = PySequence_Fast_GET_ITEM(seq, i); - if (!kqueue_event_Check(ei)) { + if (!kqueue_event_Check(ei, state)) { PyErr_SetString(PyExc_TypeError, "changelist must be an iterable of " "select.kevent objects"); @@ -2249,7 +2218,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, for (i = 0; i < gotevents; i++) { kqueue_event_Object *ch; - ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type); + ch = PyObject_New(kqueue_event_Object, state->kqueue_event_Type); if (ch == NULL) { goto error; } @@ -2295,16 +2264,14 @@ static PyMethodDef poll_methods[] = { static PyType_Slot poll_Type_slots[] = { {Py_tp_dealloc, poll_dealloc}, {Py_tp_methods, poll_methods}, - {Py_tp_new, poll_new}, {0, 0}, }; static PyType_Spec poll_Type_spec = { - "select.poll", - sizeof(pollObject), - 0, - Py_TPFLAGS_DEFAULT, - poll_Type_slots + .name = "select.poll", + .basicsize = sizeof(pollObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .slots = poll_Type_slots, }; #ifdef HAVE_SYS_DEVPOLL_H @@ -2412,24 +2379,28 @@ On Windows, only sockets are supported; on Unix, all file descriptors."); static int _select_traverse(PyObject *module, visitproc visit, void *arg) { - Py_VISIT(get_select_state(module)->close); - Py_VISIT(get_select_state(module)->poll_Type); - Py_VISIT(get_select_state(module)->devpoll_Type); - Py_VISIT(get_select_state(module)->pyEpoll_Type); - Py_VISIT(get_select_state(module)->kqueue_event_Type); - Py_VISIT(get_select_state(module)->kqueue_queue_Type); + _selectstate *state = get_select_state(module); + + Py_VISIT(state->close); + Py_VISIT(state->poll_Type); + Py_VISIT(state->devpoll_Type); + Py_VISIT(state->pyEpoll_Type); + Py_VISIT(state->kqueue_event_Type); + Py_VISIT(state->kqueue_queue_Type); return 0; } static int _select_clear(PyObject *module) { - Py_CLEAR(get_select_state(module)->close); - Py_CLEAR(get_select_state(module)->poll_Type); - Py_CLEAR(get_select_state(module)->devpoll_Type); - Py_CLEAR(get_select_state(module)->pyEpoll_Type); - Py_CLEAR(get_select_state(module)->kqueue_event_Type); - Py_CLEAR(get_select_state(module)->kqueue_queue_Type); + _selectstate *state = get_select_state(module); + + Py_CLEAR(state->close); + Py_CLEAR(state->poll_Type); + Py_CLEAR(state->devpoll_Type); + Py_CLEAR(state->pyEpoll_Type); + Py_CLEAR(state->kqueue_event_Type); + Py_CLEAR(state->kqueue_queue_Type); return 0; } @@ -2439,30 +2410,18 @@ _select_free(void *module) _select_clear((PyObject *)module); } -static struct PyModuleDef selectmodule = { - PyModuleDef_HEAD_INIT, - "select", - module_doc, - sizeof(_selectstate), - select_methods, - NULL, - _select_traverse, - _select_clear, - _select_free, -}; - -PyMODINIT_FUNC -PyInit_select(void) +int +_select_exec(PyObject *m) { - PyObject *m; - m = PyModule_Create(&selectmodule); - if (m == NULL) - return NULL; + _selectstate *state = get_select_state(m); - get_select_state(m)->close = PyUnicode_InternFromString("close"); - - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); + state->close = PyUnicode_InternFromString("close"); + if (state->close == NULL) { + return -1; + } + if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) { + return -1; + } #ifdef PIPE_BUF #ifdef HAVE_BROKEN_PIPE_BUF @@ -2482,11 +2441,11 @@ PyInit_select(void) #else { #endif - PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec); - if (poll_Type == NULL) - return NULL; - get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type; - Py_INCREF(poll_Type); + state->poll_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &poll_Type_spec, NULL); + if (state->poll_Type == NULL) { + return -1; + } PyModule_AddIntMacro(m, POLLIN); PyModule_AddIntMacro(m, POLLPRI); @@ -2518,20 +2477,22 @@ PyInit_select(void) #endif /* HAVE_POLL */ #ifdef HAVE_SYS_DEVPOLL_H - PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec); - if (devpoll_Type == NULL) - return NULL; - get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type; - Py_INCREF(devpoll_Type); + state->devpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &devpoll_Type_spec, NULL); + if (state->devpoll_Type == NULL) { + return -1; + } #endif #ifdef HAVE_EPOLL - PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec); - if (pyEpoll_Type == NULL) - return NULL; - get_select_state(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type; - Py_INCREF(pyEpoll_Type); - PyModule_AddObject(m, "epoll", (PyObject *)get_select_state(m)->pyEpoll_Type); + state->pyEpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &pyEpoll_Type_spec, NULL); + if (state->pyEpoll_Type == NULL) { + return -1; + } + if (PyModule_AddType(m, state->pyEpoll_Type) < 0) { + return -1; + } PyModule_AddIntMacro(m, EPOLLIN); PyModule_AddIntMacro(m, EPOLLOUT); @@ -2573,19 +2534,23 @@ PyInit_select(void) #endif /* HAVE_EPOLL */ #ifdef HAVE_KQUEUE - PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec); - if (kqueue_event_Type == NULL) - return NULL; - get_select_state(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type; - Py_INCREF(get_select_state(m)->kqueue_event_Type); - PyModule_AddObject(m, "kevent", kqueue_event_Type); + state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &kqueue_event_Type_spec, NULL); + if (state->kqueue_event_Type == NULL) { + return -1; + } + if (PyModule_AddType(m, state->kqueue_event_Type) < 0) { + return -1; + } - PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec); - if (kqueue_queue_Type == NULL) - return NULL; - get_select_state(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type; - Py_INCREF(get_select_state(m)->kqueue_queue_Type); - PyModule_AddObject(m, "kqueue", kqueue_queue_Type); + state->kqueue_queue_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &kqueue_queue_Type_spec, NULL); + if (state->kqueue_queue_Type == NULL) { + return -1; + } + if (PyModule_AddType(m, state->kqueue_queue_Type) < 0) { + return -1; + } /* event filters */ PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ); @@ -2662,5 +2627,28 @@ PyInit_select(void) #endif #endif /* HAVE_KQUEUE */ - return m; + return 0; +} + +static PyModuleDef_Slot _select_slots[] = { + {Py_mod_exec, _select_exec}, + {0, NULL} +}; + +static struct PyModuleDef selectmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "select", + .m_doc = module_doc, + .m_size = sizeof(_selectstate), + .m_methods = select_methods, + .m_slots = _select_slots, + .m_traverse = _select_traverse, + .m_clear = _select_clear, + .m_free = _select_free, +}; + +PyMODINIT_FUNC +PyInit_select(void) +{ + return PyModuleDef_Init(&selectmodule); } diff --git a/contrib/tools/python3/src/Modules/sha1module.c b/contrib/tools/python3/src/Modules/sha1module.c index 44fe8ef7b35..d186aa460a0 100644 --- a/contrib/tools/python3/src/Modules/sha1module.c +++ b/contrib/tools/python3/src/Modules/sha1module.c @@ -295,22 +295,42 @@ sha1_done(struct sha1_state *sha1, unsigned char *out) * ------------------------------------------------------------------------ */ -static PyTypeObject SHA1type; +typedef struct { + PyTypeObject* sha1_type; +} SHA1State; +static inline SHA1State* +sha1_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (SHA1State *)state; +} static SHA1object * -newSHA1object(void) +newSHA1object(SHA1State *st) { - return (SHA1object *)PyObject_New(SHA1object, &SHA1type); + SHA1object *sha = (SHA1object *)PyObject_GC_New(SHA1object, st->sha1_type); + PyObject_GC_Track(sha); + return sha; } /* Internal methods for a hash object */ +static int +SHA1_traverse(PyObject *ptr, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(ptr)); + return 0; +} static void SHA1_dealloc(PyObject *ptr) { - PyObject_Del(ptr); + PyTypeObject *tp = Py_TYPE(ptr); + PyObject_GC_UnTrack(ptr); + PyObject_GC_Del(ptr); + Py_DECREF(tp); } @@ -319,16 +339,19 @@ SHA1_dealloc(PyObject *ptr) /*[clinic input] SHA1Type.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -SHA1Type_copy_impl(SHA1object *self) -/*[clinic end generated code: output=b4e001264620f02a input=b7eae10df6f89b36]*/ +SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls) +/*[clinic end generated code: output=b32d4461ce8bc7a7 input=6c22e66fcc34c58e]*/ { - SHA1object *newobj; + SHA1State *st = PyType_GetModuleState(cls); - if ((newobj = newSHA1object()) == NULL) + SHA1object *newobj; + if ((newobj = newSHA1object(st)) == NULL) return NULL; newobj->hash_state = self->hash_state; @@ -422,7 +445,6 @@ sha1_get_digest_size(PyObject *self, void *closure) return PyLong_FromLong(SHA1_DIGESTSIZE); } - static PyGetSetDef SHA1_getseters[] = { {"block_size", (getter)SHA1_get_block_size, NULL, @@ -439,40 +461,21 @@ static PyGetSetDef SHA1_getseters[] = { {NULL} /* Sentinel */ }; -static PyTypeObject SHA1type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha1.sha1", /*tp_name*/ - sizeof(SHA1object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA1_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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA1_methods, /* tp_methods */ - NULL, /* tp_members */ - SHA1_getseters, /* tp_getset */ +static PyType_Slot sha1_type_slots[] = { + {Py_tp_dealloc, SHA1_dealloc}, + {Py_tp_methods, SHA1_methods}, + {Py_tp_getset, SHA1_getseters}, + {Py_tp_traverse, SHA1_traverse}, + {0,0} }; +static PyType_Spec sha1_type_spec = { + .name = "_sha1.sha1", + .basicsize = sizeof(SHA1object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), + .slots = sha1_type_slots +}; /* The single module-level function: new() */ @@ -496,7 +499,8 @@ _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity) if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newSHA1object()) == NULL) { + SHA1State *st = sha1_get_state(module); + if ((new = newSHA1object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -526,37 +530,72 @@ static struct PyMethodDef SHA1_functions[] = { {NULL, NULL} /* Sentinel */ }; +static int +_sha1_traverse(PyObject *module, visitproc visit, void *arg) +{ + SHA1State *state = sha1_get_state(module); + Py_VISIT(state->sha1_type); + return 0; +} + +static int +_sha1_clear(PyObject *module) +{ + SHA1State *state = sha1_get_state(module); + Py_CLEAR(state->sha1_type); + return 0; +} + +static void +_sha1_free(void *module) +{ + _sha1_clear((PyObject *)module); +} + +static int +_sha1_exec(PyObject *module) +{ + SHA1State* st = sha1_get_state(module); + + st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha1_type_spec, NULL); + + if (st->sha1_type == NULL) { + return -1; + } + + Py_INCREF(st->sha1_type); + if (PyModule_AddObject(module, + "SHA1Type", + (PyObject *)st->sha1_type) < 0) { + Py_DECREF(st->sha1_type); + return -1; + } + + return 0; +} + /* Initialize this module. */ +static PyModuleDef_Slot _sha1_slots[] = { + {Py_mod_exec, _sha1_exec}, + {0, NULL} +}; + static struct PyModuleDef _sha1module = { PyModuleDef_HEAD_INIT, - "_sha1", - NULL, - -1, - SHA1_functions, - NULL, - NULL, - NULL, - NULL + .m_name = "_sha1", + .m_size = sizeof(SHA1State), + .m_methods = SHA1_functions, + .m_slots = _sha1_slots, + .m_traverse = _sha1_traverse, + .m_clear = _sha1_clear, + .m_free = _sha1_free }; PyMODINIT_FUNC PyInit__sha1(void) { - PyObject *m; - - Py_SET_TYPE(&SHA1type, &PyType_Type); - if (PyType_Ready(&SHA1type) < 0) { - return NULL; - } - - m = PyModule_Create(&_sha1module); - if (m == NULL) { - return NULL; - } - - Py_INCREF((PyObject *)&SHA1type); - PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type); - return m; + return PyModuleDef_Init(&_sha1module); } diff --git a/contrib/tools/python3/src/Modules/sha256module.c b/contrib/tools/python3/src/Modules/sha256module.c index 9b885c72553..fac7073d951 100644 --- a/contrib/tools/python3/src/Modules/sha256module.c +++ b/contrib/tools/python3/src/Modules/sha256module.c @@ -17,7 +17,7 @@ /* SHA objects */ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() #include "structmember.h" // PyMemberDef #include "hashlib.h" #include "pystrhex.h" @@ -51,6 +51,19 @@ typedef struct { #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. */ @@ -365,28 +378,40 @@ sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) * ------------------------------------------------------------------------ */ -static PyTypeObject SHA224type; -static PyTypeObject SHA256type; - static SHAobject * -newSHA224object(void) +newSHA224object(_sha256_state *state) { - return (SHAobject *)PyObject_New(SHAobject, &SHA224type); + SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, + state->sha224_type); + PyObject_GC_Track(sha); + return sha; } static SHAobject * -newSHA256object(void) +newSHA256object(_sha256_state *state) { - return (SHAobject *)PyObject_New(SHAobject, &SHA256type); + 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) { - PyObject_Del(ptr); + PyTypeObject *tp = Py_TYPE(ptr); + PyObject_GC_UnTrack(ptr); + PyObject_GC_Del(ptr); + Py_DECREF(tp); } @@ -395,21 +420,25 @@ SHA_dealloc(PyObject *ptr) /*[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) -/*[clinic end generated code: output=1a8bbd66a0c9c168 input=f58840a618d4f2a7]*/ +SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=9273f92c382be12f input=3137146fcb88e212]*/ { SHAobject *newobj; - - if (Py_IS_TYPE(self, &SHA256type)) { - if ( (newobj = newSHA256object())==NULL) + _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())==NULL) + if ( (newobj = newSHA224object(state))==NULL) { return NULL; + } } SHAcopy(self, newobj); @@ -517,74 +546,30 @@ static PyMemberDef SHA_members[] = { {NULL} /* Sentinel */ }; -static PyTypeObject SHA224type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha256.sha224", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA_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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +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 PyTypeObject SHA256type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha256.sha256", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA_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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +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() */ @@ -602,15 +587,19 @@ static PyObject * _sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=a1de327e8e1185cf input=9be86301aeb14ea5]*/ { - SHAobject *new; Py_buffer buf; - if (string) + if (string) { GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + } - if ((new = newSHA256object()) == NULL) { - if (string) + _sha256_state *state = PyModule_GetState(module); + + SHAobject *new; + if ((new = newSHA256object(state)) == NULL) { + if (string) { PyBuffer_Release(&buf); + } return NULL; } @@ -618,8 +607,9 @@ _sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity) if (PyErr_Occurred()) { Py_DECREF(new); - if (string) + if (string) { PyBuffer_Release(&buf); + } return NULL; } if (string) { @@ -644,15 +634,17 @@ static PyObject * _sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=08be6b36569bc69c input=9fcfb46e460860ac]*/ { - SHAobject *new; Py_buffer buf; - - if (string) + if (string) { GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + } - if ((new = newSHA224object()) == NULL) { - if (string) + _sha256_state *state = PyModule_GetState(module); + SHAobject *new; + if ((new = newSHA224object(state)) == NULL) { + if (string) { PyBuffer_Release(&buf); + } return NULL; } @@ -660,8 +652,9 @@ _sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity) if (PyErr_Occurred()) { Py_DECREF(new); - if (string) + if (string) { PyBuffer_Release(&buf); + } return NULL; } if (string) { @@ -681,43 +674,80 @@ static struct PyMethodDef SHA_functions[] = { {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; +} -/* Initialize this module. */ +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 struct PyModuleDef _sha256module = { - PyModuleDef_HEAD_INIT, - "_sha256", - NULL, - -1, - SHA_functions, - NULL, - NULL, - NULL, - NULL -}; +static void +_sha256_free(void *module) +{ + _sha256_clear((PyObject *)module); +} -PyMODINIT_FUNC -PyInit__sha256(void) +static int sha256_exec(PyObject *module) { - PyObject *m; + _sha256_state *state = _sha256_get_state(module); - Py_SET_TYPE(&SHA224type, &PyType_Type); - if (PyType_Ready(&SHA224type) < 0) { - return NULL; + state->sha224_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha224_type_spec, NULL); + + if (state->sha224_type == NULL) { + return -1; } - Py_SET_TYPE(&SHA256type, &PyType_Type); - if (PyType_Ready(&SHA256type) < 0) { - return NULL; + + state->sha256_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha256_type_spec, NULL); + + if (state->sha256_type == NULL) { + return -1; } - m = PyModule_Create(&_sha256module); - if (m == NULL) - return NULL; + 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} +}; - Py_INCREF((PyObject *)&SHA224type); - PyModule_AddObject(m, "SHA224Type", (PyObject *)&SHA224type); - Py_INCREF((PyObject *)&SHA256type); - PyModule_AddObject(m, "SHA256Type", (PyObject *)&SHA256type); - return m; +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/contrib/tools/python3/src/Modules/sha512module.c b/contrib/tools/python3/src/Modules/sha512module.c index 831160c324d..4ea2fc16de0 100644 --- a/contrib/tools/python3/src/Modules/sha512module.c +++ b/contrib/tools/python3/src/Modules/sha512module.c @@ -17,7 +17,7 @@ /* SHA objects */ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap64() #include "structmember.h" // PyMemberDef #include "hashlib.h" #include "pystrhex.h" @@ -422,28 +422,50 @@ sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) * ------------------------------------------------------------------------ */ -static PyTypeObject SHA384type; -static PyTypeObject SHA512type; +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(void) +newSHA384object(SHA512State *st) { - return (SHAobject *)PyObject_New(SHAobject, &SHA384type); + SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, st->sha384_type); + PyObject_GC_Track(sha); + return sha; } static SHAobject * -newSHA512object(void) +newSHA512object(SHA512State *st) { - return (SHAobject *)PyObject_New(SHAobject, &SHA512type); + 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) { - PyObject_Del(ptr); + PyTypeObject *tp = Py_TYPE(ptr); + PyObject_GC_UnTrack(ptr); + PyObject_GC_Del(ptr); + Py_DECREF(tp); } @@ -452,21 +474,27 @@ SHA512_dealloc(PyObject *ptr) /*[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) -/*[clinic end generated code: output=adea896ed3164821 input=9f5f31e6c457776a]*/ +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, &SHA512type)) { - if ( (newobj = newSHA512object())==NULL) + if (Py_IS_TYPE((PyObject*)self, st->sha512_type)) { + if ( (newobj = newSHA512object(st))==NULL) { return NULL; - } else { - if ( (newobj = newSHA384object())==NULL) + } + } + else { + if ( (newobj = newSHA384object(st))==NULL) { return NULL; + } } SHAcopy(self, newobj); @@ -574,74 +602,41 @@ static PyMemberDef SHA_members[] = { {NULL} /* Sentinel */ }; -static PyTypeObject SHA384type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha512.sha384", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA512_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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +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 PyTypeObject SHA512type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha512.sha512", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA512_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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +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() */ @@ -662,10 +657,12 @@ _sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity) SHAobject *new; Py_buffer buf; + SHA512State *st = sha512_get_state(module); + if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newSHA512object()) == NULL) { + if ((new = newSHA512object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -704,10 +701,12 @@ _sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity) SHAobject *new; Py_buffer buf; + SHA512State *st = sha512_get_state(module); + if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newSHA384object()) == NULL) { + if ((new = newSHA384object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -738,43 +737,80 @@ static struct PyMethodDef SHA_functions[] = { {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; +} -/* Initialize this module. */ +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 struct PyModuleDef _sha512module = { - PyModuleDef_HEAD_INIT, - "_sha512", - NULL, - -1, - SHA_functions, - NULL, - NULL, - NULL, - NULL -}; +static void +_sha512_free(void *module) +{ + _sha512_clear((PyObject *)module); +} -PyMODINIT_FUNC -PyInit__sha512(void) + +/* Initialize this module. */ +static int +_sha512_exec(PyObject *m) { - PyObject *m; + SHA512State* st = sha512_get_state(m); - Py_SET_TYPE(&SHA384type, &PyType_Type); - if (PyType_Ready(&SHA384type) < 0) { - return NULL; + 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_SET_TYPE(&SHA512type, &PyType_Type); - if (PyType_Ready(&SHA512type) < 0) { - return NULL; + + Py_INCREF(st->sha384_type); + if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha384_type) < 0) { + Py_DECREF(st->sha384_type); + return -1; } - m = PyModule_Create(&_sha512module); - if (m == NULL) { - return NULL; + Py_INCREF(st->sha512_type); + if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha512_type) < 0) { + Py_DECREF(st->sha512_type); + return -1; } - Py_INCREF((PyObject *)&SHA384type); - PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type); - Py_INCREF((PyObject *)&SHA512type); - PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type); - return m; + 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/contrib/tools/python3/src/Modules/signalmodule.c b/contrib/tools/python3/src/Modules/signalmodule.c index e396a4ad8b4..c3a5237bce4 100644 --- a/contrib/tools/python3/src/Modules/signalmodule.c +++ b/contrib/tools/python3/src/Modules/signalmodule.c @@ -4,37 +4,39 @@ /* XXX Signals should be recorded per thread, now we have thread state. */ #include "Python.h" -#include "pycore_atomic.h" -#include "pycore_call.h" -#include "pycore_ceval.h" -#include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_atomic.h" // _Py_atomic_int +#include "pycore_call.h" // _PyObject_Call() +#include "pycore_ceval.h" // _PyEval_SignalReceived() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_pyerrors.h" // _PyErr_SetString() +#include "pycore_pylifecycle.h" // NSIG +#include "pycore_pystate.h" // _PyThreadState_GET() #ifndef MS_WINDOWS -#include "posixmodule.h" +# include "posixmodule.h" #endif #ifdef MS_WINDOWS -#include "socketmodule.h" /* needed for SOCKET_T */ +# include "socketmodule.h" /* needed for SOCKET_T */ #endif #ifdef MS_WINDOWS -#include -#ifdef HAVE_PROCESS_H -#include -#endif +# include +# ifdef HAVE_PROCESS_H +# include +# endif #endif #ifdef HAVE_SIGNAL_H -#include +# include #endif #ifdef HAVE_SYS_SYSCALL_H -#include +# include #endif #ifdef HAVE_SYS_STAT_H -#include +# include #endif #ifdef HAVE_SYS_TIME_H -#include +# include #endif #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) @@ -46,19 +48,7 @@ #endif #ifndef SIG_ERR -#define SIG_ERR ((PyOS_sighandler_t)(-1)) -#endif - -#ifndef NSIG -# if defined(_NSIG) -# define NSIG _NSIG /* For BSD/SysV */ -# elif defined(_SIGMAX) -# define NSIG (_SIGMAX + 1) /* For QNX */ -# elif defined(SIGMAX) -# define NSIG (SIGMAX + 1) /* For djgpp */ -# else -# define NSIG 64 /* Use a reasonable default value */ -# endif +# define SIG_ERR ((PyOS_sighandler_t)(-1)) #endif #include "clinic/signalmodule.c.h" @@ -109,7 +99,10 @@ class sigset_t_converter(CConverter): static volatile struct { _Py_atomic_int tripped; - PyObject *func; + /* 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[NSIG]; #ifdef MS_WINDOWS @@ -123,7 +116,11 @@ static volatile struct { #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 @@ -131,17 +128,64 @@ static volatile struct { /* Speed up sigcheck() when none tripped */ static _Py_atomic_int is_tripped; -static PyObject *DefaultHandler; -static PyObject *IgnoreHandler; -static PyObject *IntHandler; - +typedef struct { + PyObject *default_handler; + PyObject *ignore_handler; #ifdef MS_WINDOWS -static HANDLE sigint_event = NULL; + HANDLE sigint_event; #endif +} signal_state_t; -#ifdef HAVE_GETITIMER -static PyObject *ItimerError; +// State shared by all Python interpreters +static signal_state_t signal_global_state = {0}; + +#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER) +# define PYHAVE_ITIMER_ERROR +#endif + +typedef struct { + PyObject *default_handler; // borrowed ref (signal_global_state) + PyObject *ignore_handler; // borrowed ref (signal_global_state) +#ifdef PYHAVE_ITIMER_ERROR + PyObject *itimer_error; +#endif +} _signal_module_state; + + +Py_LOCAL_INLINE(PyObject *) +get_handler(int i) +{ + return (PyObject *)_Py_atomic_load(&Handlers[i].func); +} + +Py_LOCAL_INLINE(void) +set_handler(int i, PyObject* func) +{ + _Py_atomic_store(&Handlers[i].func, (uintptr_t)func); +} + + +static inline _signal_module_state* +get_signal_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (_signal_module_state *)state; +} + + +static inline int +compare_handler(PyObject *func, PyObject *dfl_ign_handler) +{ + assert(PyLong_CheckExact(dfl_ign_handler)); + if (!PyLong_CheckExact(func)) { + return 0; + } + // Assume that comparison of two PyLong objects will never fail. + return PyObject_RichCompareBool(func, dfl_ign_handler, Py_EQ) == 1; +} +#ifdef HAVE_GETITIMER /* auxiliary functions for setitimer */ static int timeval_from_double(PyObject *obj, struct timeval *tv) @@ -192,19 +236,26 @@ itimer_retval(struct itimerval *iv) } #endif +/*[clinic input] +signal.default_int_handler + signalnum: int + frame: object + / + +The default handler for SIGINT installed by Python. + +It raises KeyboardInterrupt. +[clinic start generated code]*/ + static PyObject * -signal_default_int_handler(PyObject *self, PyObject *args) +signal_default_int_handler_impl(PyObject *module, int signalnum, + PyObject *frame) +/*[clinic end generated code: output=bb11c2eb115ace4e input=efcd4a56a207acfd]*/ { PyErr_SetNone(PyExc_KeyboardInterrupt); return NULL; } -PyDoc_STRVAR(default_int_handler_doc, -"default_int_handler(...)\n\ -\n\ -The default handler for SIGINT installed by Python.\n\ -It raises KeyboardInterrupt."); - static int report_wakeup_write_error(void *data) @@ -243,10 +294,6 @@ report_wakeup_send_error(void* data) static void trip_signal(int sig_num) { - unsigned char byte; - int fd; - Py_ssize_t rc; - _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1); /* Set is_tripped after setting .tripped, as it gets @@ -278,6 +325,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 @@ -285,10 +333,10 @@ trip_signal(int sig_num) #endif if (fd != INVALID_FD) { - byte = (unsigned char)sig_num; + unsigned char byte = (unsigned char)sig_num; #ifdef MS_WINDOWS if (wakeup.use_send) { - rc = send(fd, &byte, 1, 0); + Py_ssize_t rc = send(fd, &byte, 1, 0); if (rc < 0) { int last_error = GetLastError(); @@ -308,7 +356,7 @@ trip_signal(int sig_num) { /* _Py_write_noraise() retries write() if write() is interrupted by a signal (fails with EINTR). */ - rc = _Py_write_noraise(fd, &byte, 1); + Py_ssize_t rc = _Py_write_noraise(fd, &byte, 1); if (rc < 0) { if (wakeup.warn_on_full_buffer || @@ -351,8 +399,10 @@ signal_handler(int sig_num) errno = save_errno; #ifdef MS_WINDOWS - if (sig_num == SIGINT) - SetEvent(sigint_event); + if (sig_num == SIGINT) { + signal_state_t *state = &signal_global_state; + SetEvent(state->sigint_event); + } #endif } @@ -451,6 +501,7 @@ static PyObject * signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) /*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/ { + _signal_module_state *modstate = get_signal_state(module); PyObject *old_handler; void (*func)(int); #ifdef MS_WINDOWS @@ -485,21 +536,18 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) "signal number out of range"); return NULL; } - if (handler == IgnoreHandler) { + if (PyCallable_Check(handler)) { + func = signal_handler; + } else if (compare_handler(handler, modstate->ignore_handler)) { func = SIG_IGN; - } - else if (handler == DefaultHandler) { + } else if (compare_handler(handler, modstate->default_handler)) { func = SIG_DFL; - } - else if (!PyCallable_Check(handler)) { + } else { _PyErr_SetString(tstate, PyExc_TypeError, "signal handler must be signal.SIG_IGN, " "signal.SIG_DFL, or a callable object"); return NULL; } - else { - func = signal_handler; - } /* Check for pending signals before changing signal handler */ if (_PyErr_CheckSignalsTstate(tstate)) { @@ -510,9 +558,8 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) return NULL; } - old_handler = Handlers[signalnum].func; - Py_INCREF(handler); - Handlers[signalnum].func = handler; + old_handler = get_handler(signalnum); + set_handler(signalnum, Py_NewRef(handler)); if (old_handler != NULL) { return old_handler; @@ -548,10 +595,9 @@ signal_getsignal_impl(PyObject *module, int signalnum) "signal number out of range"); return NULL; } - old_handler = Handlers[signalnum].func; + old_handler = get_handler(signalnum); if (old_handler != NULL) { - Py_INCREF(old_handler); - return old_handler; + return Py_NewRef(old_handler); } else { Py_RETURN_NONE; @@ -660,7 +706,19 @@ signal_siginterrupt_impl(PyObject *module, int signalnum, int flag) "signal number out of range"); return NULL; } - if (siginterrupt(signalnum, flag)<0) { +#ifdef HAVE_SIGACTION + struct sigaction act; + (void) sigaction(signalnum, NULL, &act); + if (flag) { + act.sa_flags &= ~SA_RESTART; + } + else { + act.sa_flags |= SA_RESTART; + } + if (sigaction(signalnum, &act, NULL) < 0) { +#else + if (siginterrupt(signalnum, flag) < 0) { +#endif PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -694,7 +752,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred()) return NULL; #else - int fd, old_fd; + int fd; if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|$p:set_wakeup_fd", kwlist, &fd, &warn_on_full_buffer)) @@ -776,7 +834,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) } } - old_fd = wakeup.fd; + int old_fd = wakeup.fd; wakeup.fd = fd; wakeup.warn_on_full_buffer = warn_on_full_buffer; @@ -797,14 +855,14 @@ The fd must be non-blocking."); int PySignal_SetWakeupFd(int fd) { - int old_fd; - if (fd < 0) + if (fd < 0) { fd = -1; + } #ifdef MS_WINDOWS - old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); + int old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); #else - old_fd = wakeup.fd; + int old_fd = wakeup.fd; #endif wakeup.fd = fd; wakeup.warn_on_full_buffer = 1; @@ -813,7 +871,6 @@ PySignal_SetWakeupFd(int fd) #ifdef HAVE_SETITIMER - /*[clinic input] signal.setitimer @@ -835,8 +892,9 @@ signal_setitimer_impl(PyObject *module, int which, PyObject *seconds, PyObject *interval) /*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/ { - struct itimerval new, old; + _signal_module_state *modstate = get_signal_state(module); + struct itimerval new; if (timeval_from_double(seconds, &new.it_value) < 0) { return NULL; } @@ -845,19 +903,18 @@ signal_setitimer_impl(PyObject *module, int which, PyObject *seconds, } /* Let OS check "which" value */ + struct itimerval old; if (setitimer(which, &new, &old) != 0) { - PyErr_SetFromErrno(ItimerError); + PyErr_SetFromErrno(modstate->itimer_error); return NULL; } return itimer_retval(&old); } - -#endif +#endif // HAVE_SETITIMER #ifdef HAVE_GETITIMER - /*[clinic input] signal.getitimer @@ -871,17 +928,18 @@ static PyObject * signal_getitimer_impl(PyObject *module, int which) /*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/ { - struct itimerval old; + _signal_module_state *modstate = get_signal_state(module); + struct itimerval old; if (getitimer(which, &old) != 0) { - PyErr_SetFromErrno(ItimerError); + PyErr_SetFromErrno(modstate->itimer_error); return NULL; } return itimer_retval(&old); } +#endif // HAVE_GETITIMER -#endif #ifdef HAVE_SIGSET_T #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING) @@ -1060,7 +1118,6 @@ signal_valid_signals_impl(PyObject *module) #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) -static int initialized; static PyStructSequence_Field struct_siginfo_fields[] = { {"si_signo", "signal number"}, {"si_code", "signal code"}, @@ -1304,7 +1361,7 @@ signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum, /* List of functions defined in the module -- some of the methoddefs are defined to nothing if the corresponding C function is not available. */ static PyMethodDef signal_methods[] = { - {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, + SIGNAL_DEFAULT_INT_HANDLER_METHODDEF SIGNAL_ALARM_METHODDEF SIGNAL_SETITIMER_METHODDEF SIGNAL_GETITIMER_METHODDEF @@ -1365,311 +1422,345 @@ ITIMER_PROF -- decrements both when the process is executing and\n\ A signal handler function is called with two arguments:\n\ the first is the signal number, the second is the interrupted stack frame."); -static struct PyModuleDef signalmodule = { - PyModuleDef_HEAD_INIT, - "_signal", - module_doc, - -1, - signal_methods, - NULL, - NULL, - NULL, - NULL -}; -PyMODINIT_FUNC -PyInit__signal(void) -{ - PyObject *m, *d; - int i; - /* Create the module and add the functions */ - m = PyModule_Create(&signalmodule); - if (m == NULL) - return NULL; - -#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) - if (!initialized) { - if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) - return NULL; - } - Py_INCREF((PyObject*) &SiginfoType); - PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType); - initialized = 1; -#endif - - /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - - DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); - if (!DefaultHandler || - PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) { - goto finally; - } - - IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); - if (!IgnoreHandler || - PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) { - goto finally; +static int +signal_add_constants(PyObject *module) +{ +#define ADD_INT_MACRO(macro) \ + if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \ + return -1; \ } - if (PyModule_AddIntMacro(m, NSIG)) - goto finally; + ADD_INT_MACRO(NSIG); + // SIG_xxx pthread_sigmask() constants #ifdef SIG_BLOCK - if (PyModule_AddIntMacro(m, SIG_BLOCK)) - goto finally; + ADD_INT_MACRO(SIG_BLOCK); #endif #ifdef SIG_UNBLOCK - if (PyModule_AddIntMacro(m, SIG_UNBLOCK)) - goto finally; + ADD_INT_MACRO(SIG_UNBLOCK); #endif #ifdef SIG_SETMASK - if (PyModule_AddIntMacro(m, SIG_SETMASK)) - goto finally; + ADD_INT_MACRO(SIG_SETMASK); #endif - IntHandler = PyDict_GetItemString(d, "default_int_handler"); - if (!IntHandler) - goto finally; - Py_INCREF(IntHandler); - - _Py_atomic_store_relaxed(&Handlers[0].tripped, 0); - for (i = 1; i < NSIG; i++) { - void (*t)(int); - t = PyOS_getsig(i); - _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); - if (t == SIG_DFL) - Handlers[i].func = DefaultHandler; - else if (t == SIG_IGN) - Handlers[i].func = IgnoreHandler; - else - Handlers[i].func = Py_None; /* None of our business */ - Py_INCREF(Handlers[i].func); - } - if (Handlers[SIGINT].func == DefaultHandler) { - /* Install default int handler */ - Py_INCREF(IntHandler); - Py_SETREF(Handlers[SIGINT].func, IntHandler); - PyOS_setsig(SIGINT, signal_handler); - } - + // SIGxxx signal number constants #ifdef SIGHUP - if (PyModule_AddIntMacro(m, SIGHUP)) - goto finally; + ADD_INT_MACRO(SIGHUP); #endif #ifdef SIGINT - if (PyModule_AddIntMacro(m, SIGINT)) - goto finally; + ADD_INT_MACRO(SIGINT); #endif #ifdef SIGBREAK - if (PyModule_AddIntMacro(m, SIGBREAK)) - goto finally; + ADD_INT_MACRO(SIGBREAK); #endif #ifdef SIGQUIT - if (PyModule_AddIntMacro(m, SIGQUIT)) - goto finally; + ADD_INT_MACRO(SIGQUIT); #endif #ifdef SIGILL - if (PyModule_AddIntMacro(m, SIGILL)) - goto finally; + ADD_INT_MACRO(SIGILL); #endif #ifdef SIGTRAP - if (PyModule_AddIntMacro(m, SIGTRAP)) - goto finally; + ADD_INT_MACRO(SIGTRAP); #endif #ifdef SIGIOT - if (PyModule_AddIntMacro(m, SIGIOT)) - goto finally; + ADD_INT_MACRO(SIGIOT); #endif #ifdef SIGABRT - if (PyModule_AddIntMacro(m, SIGABRT)) - goto finally; + ADD_INT_MACRO(SIGABRT); #endif #ifdef SIGEMT - if (PyModule_AddIntMacro(m, SIGEMT)) - goto finally; + ADD_INT_MACRO(SIGEMT); #endif #ifdef SIGFPE - if (PyModule_AddIntMacro(m, SIGFPE)) - goto finally; + ADD_INT_MACRO(SIGFPE); #endif #ifdef SIGKILL - if (PyModule_AddIntMacro(m, SIGKILL)) - goto finally; + ADD_INT_MACRO(SIGKILL); #endif #ifdef SIGBUS - if (PyModule_AddIntMacro(m, SIGBUS)) - goto finally; + ADD_INT_MACRO(SIGBUS); #endif #ifdef SIGSEGV - if (PyModule_AddIntMacro(m, SIGSEGV)) - goto finally; + ADD_INT_MACRO(SIGSEGV); #endif #ifdef SIGSYS - if (PyModule_AddIntMacro(m, SIGSYS)) - goto finally; + ADD_INT_MACRO(SIGSYS); #endif #ifdef SIGPIPE - if (PyModule_AddIntMacro(m, SIGPIPE)) - goto finally; + ADD_INT_MACRO(SIGPIPE); #endif #ifdef SIGALRM - if (PyModule_AddIntMacro(m, SIGALRM)) - goto finally; + ADD_INT_MACRO(SIGALRM); #endif #ifdef SIGTERM - if (PyModule_AddIntMacro(m, SIGTERM)) - goto finally; + ADD_INT_MACRO(SIGTERM); #endif #ifdef SIGUSR1 - if (PyModule_AddIntMacro(m, SIGUSR1)) - goto finally; + ADD_INT_MACRO(SIGUSR1); #endif #ifdef SIGUSR2 - if (PyModule_AddIntMacro(m, SIGUSR2)) - goto finally; + ADD_INT_MACRO(SIGUSR2); #endif #ifdef SIGCLD - if (PyModule_AddIntMacro(m, SIGCLD)) - goto finally; + ADD_INT_MACRO(SIGCLD); #endif #ifdef SIGCHLD - if (PyModule_AddIntMacro(m, SIGCHLD)) - goto finally; + ADD_INT_MACRO(SIGCHLD); #endif #ifdef SIGPWR - if (PyModule_AddIntMacro(m, SIGPWR)) - goto finally; + ADD_INT_MACRO(SIGPWR); #endif #ifdef SIGIO - if (PyModule_AddIntMacro(m, SIGIO)) - goto finally; + ADD_INT_MACRO(SIGIO); #endif #ifdef SIGURG - if (PyModule_AddIntMacro(m, SIGURG)) - goto finally; + ADD_INT_MACRO(SIGURG); #endif #ifdef SIGWINCH - if (PyModule_AddIntMacro(m, SIGWINCH)) - goto finally; + ADD_INT_MACRO(SIGWINCH); #endif #ifdef SIGPOLL - if (PyModule_AddIntMacro(m, SIGPOLL)) - goto finally; + ADD_INT_MACRO(SIGPOLL); #endif #ifdef SIGSTOP - if (PyModule_AddIntMacro(m, SIGSTOP)) - goto finally; + ADD_INT_MACRO(SIGSTOP); #endif #ifdef SIGTSTP - if (PyModule_AddIntMacro(m, SIGTSTP)) - goto finally; + ADD_INT_MACRO(SIGTSTP); #endif #ifdef SIGCONT - if (PyModule_AddIntMacro(m, SIGCONT)) - goto finally; + ADD_INT_MACRO(SIGCONT); #endif #ifdef SIGTTIN - if (PyModule_AddIntMacro(m, SIGTTIN)) - goto finally; + ADD_INT_MACRO(SIGTTIN); #endif #ifdef SIGTTOU - if (PyModule_AddIntMacro(m, SIGTTOU)) - goto finally; + ADD_INT_MACRO(SIGTTOU); #endif #ifdef SIGVTALRM - if (PyModule_AddIntMacro(m, SIGVTALRM)) - goto finally; + ADD_INT_MACRO(SIGVTALRM); #endif #ifdef SIGPROF - if (PyModule_AddIntMacro(m, SIGPROF)) - goto finally; + ADD_INT_MACRO(SIGPROF); #endif #ifdef SIGXCPU - if (PyModule_AddIntMacro(m, SIGXCPU)) - goto finally; + ADD_INT_MACRO(SIGXCPU); #endif #ifdef SIGXFSZ - if (PyModule_AddIntMacro(m, SIGXFSZ)) - goto finally; + ADD_INT_MACRO(SIGXFSZ); #endif #ifdef SIGRTMIN - if (PyModule_AddIntMacro(m, SIGRTMIN)) - goto finally; + ADD_INT_MACRO(SIGRTMIN); #endif #ifdef SIGRTMAX - if (PyModule_AddIntMacro(m, SIGRTMAX)) - goto finally; + ADD_INT_MACRO(SIGRTMAX); #endif #ifdef SIGINFO - if (PyModule_AddIntMacro(m, SIGINFO)) - goto finally; + ADD_INT_MACRO(SIGINFO); #endif + // ITIMER_xxx constants #ifdef ITIMER_REAL - if (PyModule_AddIntMacro(m, ITIMER_REAL)) - goto finally; + ADD_INT_MACRO(ITIMER_REAL); #endif #ifdef ITIMER_VIRTUAL - if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL)) - goto finally; + ADD_INT_MACRO(ITIMER_VIRTUAL); #endif #ifdef ITIMER_PROF - if (PyModule_AddIntMacro(m, ITIMER_PROF)) - goto finally; + ADD_INT_MACRO(ITIMER_PROF); #endif -#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) - ItimerError = PyErr_NewException("signal.ItimerError", - PyExc_OSError, NULL); - if (!ItimerError || - PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) { - goto finally; - } + // CTRL_xxx Windows signals +#ifdef CTRL_C_EVENT + ADD_INT_MACRO(CTRL_C_EVENT); +#endif +#ifdef CTRL_BREAK_EVENT + ADD_INT_MACRO(CTRL_BREAK_EVENT); #endif -#ifdef CTRL_C_EVENT - if (PyModule_AddIntMacro(m, CTRL_C_EVENT)) - goto finally; + return 0; + +#undef ADD_INT_MACRO +} + + +static int +signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict) +{ + // Get signal handlers + for (int signum = 1; signum < NSIG; signum++) { + void (*c_handler)(int) = PyOS_getsig(signum); + PyObject *func; + if (c_handler == SIG_DFL) { + func = state->default_handler; + } + else if (c_handler == SIG_IGN) { + func = state->ignore_handler; + } + else { + func = Py_None; // None of our business + } + // If signal_module_exec() is called more than one, we must + // clear the strong reference to the previous function. + PyObject* old_func = get_handler(signum); + set_handler(signum, Py_NewRef(func)); + Py_XDECREF(old_func); + } + + // Install Python SIGINT handler which raises KeyboardInterrupt + PyObject* sigint_func = get_handler(SIGINT); + if (sigint_func == state->default_handler) { + PyObject *int_handler = PyMapping_GetItemString(mod_dict, + "default_int_handler"); + if (!int_handler) { + return -1; + } + + set_handler(SIGINT, int_handler); + Py_DECREF(sigint_func); + PyOS_setsig(SIGINT, signal_handler); + } + return 0; +} + + +static int +signal_module_exec(PyObject *m) +{ + assert(!PyErr_Occurred()); + + signal_state_t *state = &signal_global_state; + _signal_module_state *modstate = get_signal_state(m); + + modstate->default_handler = state->default_handler; // borrowed ref + modstate->ignore_handler = state->ignore_handler; // borrowed ref + +#ifdef PYHAVE_ITIMER_ERROR + modstate->itimer_error = PyErr_NewException("signal.itimer_error", + PyExc_OSError, NULL); + if (modstate->itimer_error == NULL) { + return -1; + } #endif -#ifdef CTRL_BREAK_EVENT - if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT)) - goto finally; + if (signal_add_constants(m) < 0) { + return -1; + } + + /* Add some symbolic constants to the module */ + PyObject *d = PyModule_GetDict(m); + if (PyDict_SetItemString(d, "SIG_DFL", state->default_handler) < 0) { + return -1; + } + if (PyDict_SetItemString(d, "SIG_IGN", state->ignore_handler) < 0) { + return -1; + } +#ifdef PYHAVE_ITIMER_ERROR + if (PyDict_SetItemString(d, "ItimerError", modstate->itimer_error) < 0) { + return -1; + } +#endif +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + if (PyModule_AddType(m, &SiginfoType) < 0) { + return -1; + } #endif - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; + PyThreadState *tstate = _PyThreadState_GET(); + if (_Py_IsMainInterpreter(tstate->interp)) { + if (signal_get_set_handlers(state, d) < 0) { + return -1; + } } - finally: - return m; + assert(!PyErr_Occurred()); + return 0; +} + + +#ifdef PYHAVE_ITIMER_ERROR +static int +_signal_module_traverse(PyObject *module, visitproc visit, void *arg) +{ + _signal_module_state *modstate = get_signal_state(module); + Py_VISIT(modstate->itimer_error); + return 0; +} + +static int +_signal_module_clear(PyObject *module) +{ + _signal_module_state *modstate = get_signal_state(module); + Py_CLEAR(modstate->itimer_error); + return 0; } static void -finisignal(void) +_signal_module_free(void *module) { - int i; - PyObject *func; + _signal_module_clear((PyObject *)module); +} +#endif // PYHAVE_ITIMER_ERROR - for (i = 1; i < NSIG; i++) { - func = Handlers[i].func; - _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); - Handlers[i].func = NULL; - if (func != NULL && func != Py_None && - func != DefaultHandler && func != IgnoreHandler) - PyOS_setsig(i, SIG_DFL); + +static PyModuleDef_Slot signal_slots[] = { + {Py_mod_exec, signal_module_exec}, + {0, NULL} +}; + +static struct PyModuleDef signal_module = { + PyModuleDef_HEAD_INIT, + "_signal", + .m_doc = module_doc, + .m_size = sizeof(_signal_module_state), + .m_methods = signal_methods, + .m_slots = signal_slots, +#ifdef PYHAVE_ITIMER_ERROR + .m_traverse = _signal_module_traverse, + .m_clear = _signal_module_clear, + .m_free = _signal_module_free, +#endif +}; + + +PyMODINIT_FUNC +PyInit__signal(void) +{ + return PyModuleDef_Init(&signal_module); +} + + +void +_PySignal_Fini(void) +{ + signal_state_t *state = &signal_global_state; + + // Restore default signals and clear handlers + for (int signum = 1; signum < NSIG; signum++) { + PyObject *func = get_handler(signum); + _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0); + set_handler(signum, NULL); + if (func != NULL + && func != Py_None + && !compare_handler(func, state->default_handler) + && !compare_handler(func, state->ignore_handler)) + { + PyOS_setsig(signum, SIG_DFL); + } Py_XDECREF(func); } - Py_CLEAR(IntHandler); - Py_CLEAR(DefaultHandler); - Py_CLEAR(IgnoreHandler); -#ifdef HAVE_GETITIMER - Py_CLEAR(ItimerError); +#ifdef MS_WINDOWS + if (state->sigint_event != NULL) { + CloseHandle(state->sigint_event); + state->sigint_event = NULL; + } #endif + + Py_CLEAR(state->default_handler); + Py_CLEAR(state->ignore_handler); } @@ -1715,6 +1806,7 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) frame = Py_None; } + signal_state_t *state = &signal_global_state; for (int i = 1; i < NSIG; i++) { if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) { continue; @@ -1727,9 +1819,10 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) * signal handler for it by the time PyErr_CheckSignals() is called * (see bpo-43406). */ - PyObject *func = Handlers[i].func; - if (func == NULL || func == Py_None || func == IgnoreHandler || - func == DefaultHandler) { + PyObject *func = get_handler(i); + if (func == NULL || func == Py_None || + compare_handler(func, state->ignore_handler) || + compare_handler(func, state->default_handler)) { /* No Python signal handler due to aforementioned race condition. * We can't call raise() as it would break the assumption * that PyErr_SetInterrupt() only *simulates* an incoming @@ -1776,30 +1869,32 @@ _PyErr_CheckSignals(void) } -/* Simulate the effect of a signal.SIGINT signal arriving. The next time - PyErr_CheckSignals is called, the Python SIGINT signal handler will be - raised. +/* Simulate the effect of a signal arriving. The next time PyErr_CheckSignals + is called, the corresponding Python signal handler will be raised. - Missing signal handler for the SIGINT signal is silently ignored. */ -void -PyErr_SetInterrupt(void) + Missing signal handler for the given signal number is silently ignored. */ +int +PyErr_SetInterruptEx(int signum) { - if ((Handlers[SIGINT].func != IgnoreHandler) && - (Handlers[SIGINT].func != DefaultHandler)) { - trip_signal(SIGINT); + if (signum < 1 || signum >= NSIG) { + return -1; } + + signal_state_t *state = &signal_global_state; + PyObject *func = get_handler(signum); + if (!compare_handler(func, state->ignore_handler) + && !compare_handler(func, state->default_handler)) { + trip_signal(signum); + } + return 0; } void -PyOS_InitInterrupts(void) +PyErr_SetInterrupt(void) { - PyObject *m = PyImport_ImportModule("_signal"); - if (m) { - Py_DECREF(m); - } + (void) PyErr_SetInterruptEx(SIGINT); } - static int signal_install_handlers(void) { @@ -1824,18 +1919,65 @@ signal_install_handlers(void) } +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. + * + * All of the code in this function must only use async-signal-safe functions, + * listed at `man 7 signal` or + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + * + * If this function is updated, update also _posix_spawn() of subprocess.py. + */ +void +_Py_RestoreSignals(void) +{ +#ifdef SIGPIPE + PyOS_setsig(SIGPIPE, SIG_DFL); +#endif +#ifdef SIGXFZ + PyOS_setsig(SIGXFZ, SIG_DFL); +#endif +#ifdef SIGXFSZ + PyOS_setsig(SIGXFSZ, SIG_DFL); +#endif +} + + int _PySignal_Init(int install_signal_handlers) { + signal_state_t *state = &signal_global_state; + + state->default_handler = PyLong_FromVoidPtr((void *)SIG_DFL); + if (state->default_handler == NULL) { + return -1; + } + + state->ignore_handler = PyLong_FromVoidPtr((void *)SIG_IGN); + if (state->ignore_handler == NULL) { + return -1; + } + #ifdef MS_WINDOWS /* Create manual-reset event, initially unset */ - sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE); - if (sigint_event == NULL) { + state->sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE); + if (state->sigint_event == NULL) { PyErr_SetFromWindowsErr(0); return -1; } #endif +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + if (SiginfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) { + return -1; + } + } +#endif + + for (int signum = 1; signum < NSIG; signum++) { + _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0); + } + if (install_signal_handlers) { if (signal_install_handlers() < 0) { return -1; @@ -1846,13 +1988,6 @@ _PySignal_Init(int install_signal_handlers) } -void -PyOS_FiniInterrupts(void) -{ - finisignal(); -} - - // The caller doesn't have to hold the GIL int _PyOS_InterruptOccurred(PyThreadState *tstate) @@ -1880,14 +2015,16 @@ PyOS_InterruptOccurred(void) } +#ifdef HAVE_FORK static void _clear_pending_signals(void) { - int i; - if (!_Py_atomic_load(&is_tripped)) + if (!_Py_atomic_load(&is_tripped)) { return; + } + _Py_atomic_store(&is_tripped, 0); - for (i = 1; i < NSIG; ++i) { + for (int i = 1; i < NSIG; ++i) { _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); } } @@ -1900,6 +2037,8 @@ _PySignal_AfterFork(void) * the interpreter had an opportunity to call the handlers. issue9535. */ _clear_pending_signals(); } +#endif /* HAVE_FORK */ + int _PyOS_IsMainThread(void) @@ -1909,13 +2048,14 @@ _PyOS_IsMainThread(void) } #ifdef MS_WINDOWS +/* Returns a manual-reset event which gets tripped whenever + SIGINT is received. + + Python.h does not include windows.h so we do cannot use HANDLE + as the return type of this function. We use void* instead. */ void *_PyOS_SigintEvent(void) { - /* Returns a manual-reset event which gets tripped whenever - SIGINT is received. - - Python.h does not include windows.h so we do cannot use HANDLE - as the return type of this function. We use void* instead. */ - return sigint_event; + signal_state_t *state = &signal_global_state; + return state->sigint_event; } #endif diff --git a/contrib/tools/python3/src/Modules/socketmodule.c b/contrib/tools/python3/src/Modules/socketmodule.c index 5ac2ee510f6..e1b8b13d883 100644 --- a/contrib/tools/python3/src/Modules/socketmodule.c +++ b/contrib/tools/python3/src/Modules/socketmodule.c @@ -45,7 +45,7 @@ Module interface: - socket.if_nameindex() -> list of tuples (if_index, if_name) - socket.if_nametoindex(name) -> corresponding interface index - socket.if_indextoname(index) -> corresponding interface name -- an Internet socket address is a pair (hostname, port) +- an internet socket address is a pair (hostname, port) where hostname can be anything recognized by gethostbyname() (including the dd.dd.dd.dd notation) and port is in host byte order - where a hostname is returned, the dd.dd.dd.dd notation is used @@ -201,43 +201,6 @@ shutdown(how) -- shut down traffic in one or both directions\n\ # define USE_GETHOSTBYNAME_LOCK #endif -/* To use __FreeBSD_version, __OpenBSD__, and __NetBSD_Version__ */ -#ifdef HAVE_SYS_PARAM_H -#include -#endif -/* On systems on which getaddrinfo() is believed to not be thread-safe, - (this includes the getaddrinfo emulation) protect access with a lock. - - getaddrinfo is thread-safe on Mac OS X 10.5 and later. Originally it was - a mix of code including an unsafe implementation from an old BSD's - libresolv. In 10.5 Apple reimplemented it as a safe IPC call to the - mDNSResponder process. 10.5 is the first be UNIX '03 certified, which - includes the requirement that getaddrinfo be thread-safe. See issue #25924. - - It's thread-safe in OpenBSD starting with 5.4, released Nov 2013: - http://www.openbsd.org/plus54.html - - It's thread-safe in NetBSD starting with 4.0, released Dec 2007: - -http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&r2=1.83 - */ -#if ((defined(__APPLE__) && \ - MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || \ - (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \ - (defined(__OpenBSD__) && OpenBSD+0 < 201311) || \ - (defined(__NetBSD__) && __NetBSD_Version__+0 < 400000000) || \ - !defined(HAVE_GETADDRINFO)) -#define USE_GETADDRINFO_LOCK -#endif - -#ifdef USE_GETADDRINFO_LOCK -#define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1); -#define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock); -#else -#define ACQUIRE_GETADDRINFO_LOCK -#define RELEASE_GETADDRINFO_LOCK -#endif - #if defined(__APPLE__) || defined(__CYGWIN__) || defined(__NetBSD__) # include #endif @@ -365,7 +328,7 @@ static FlagRuntimeInfo win_runtime_flags[] = { {14393, "TCP_FASTOPEN"} }; -static void +static int remove_unusable_flags(PyObject *m) { PyObject *dict; @@ -374,7 +337,7 @@ remove_unusable_flags(PyObject *m) dict = PyModule_GetDict(m); if (dict == NULL) { - return; + return -1; } /* set to Windows 10, except BuildNumber. */ @@ -400,19 +363,19 @@ remove_unusable_flags(PyObject *m) break; } else { - if (PyDict_GetItemString( - dict, - win_runtime_flags[i].flag_name) != NULL) - { - if (PyDict_DelItemString( - dict, - win_runtime_flags[i].flag_name)) - { - PyErr_Clear(); - } + PyObject *flag_name = PyUnicode_FromString(win_runtime_flags[i].flag_name); + if (flag_name == NULL) { + return -1; + } + PyObject *v = _PyDict_Pop(dict, flag_name, Py_None); + Py_DECREF(flag_name); + if (v == NULL) { + return -1; } + Py_DECREF(v); } } + return 0; } #endif @@ -555,7 +518,6 @@ remove_unusable_flags(PyObject *m) by this module (but not argument type or memory errors, etc.). */ static PyObject *socket_herror; static PyObject *socket_gaierror; -static PyObject *socket_timeout; /* A forward reference to the socket type object. The sock_type variable contains pointers to various functions, @@ -927,7 +889,7 @@ sock_call_ex(PySocketSockObject *s, if (err) *err = SOCK_TIMEOUT_ERR; else - PyErr_SetString(socket_timeout, "timed out"); + PyErr_SetString(PyExc_TimeoutError, "timed out"); return -1; } @@ -1064,7 +1026,7 @@ new_sockobject(SOCKET_T fd, int family, int type, int proto) /* Lock to allow python interpreter to continue, but only allow one thread to be in gethostbyname or getaddrinfo */ -#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) +#if defined(USE_GETHOSTBYNAME_LOCK) static PyThread_type_lock netdb_lock; #endif @@ -1089,14 +1051,12 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int hints.ai_socktype = SOCK_DGRAM; /*dummy*/ hints.ai_flags = AI_PASSIVE; Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK error = getaddrinfo(NULL, "0", &hints, &res); Py_END_ALLOW_THREADS /* We assume that those thread-unsafe getaddrinfo() versions *are* safe regarding their return value, ie. that a subsequent call to getaddrinfo() does not destroy the outcome of the first call. */ - RELEASE_GETADDRINFO_LOCK if (error) { set_gaierror(error); return -1; @@ -1197,7 +1157,6 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int memset(&hints, 0, sizeof(hints)); hints.ai_family = af; Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK error = getaddrinfo(name, NULL, &hints, &res); #if defined(__digital__) && defined(__unix__) if (error == EAI_NONAME && af == AF_UNSPEC) { @@ -1208,7 +1167,6 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int } #endif Py_END_ALLOW_THREADS - RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ if (error) { set_gaierror(error); return -1; @@ -2925,7 +2883,7 @@ sock_settimeout(PySocketSockObject *s, PyObject *arg) /* Blocking mode for a Python socket object means that operations like :meth:`recv` or :meth:`sendall` will block the execution of the current thread until they are complete or aborted with a - `socket.timeout` or `socket.error` errors. When timeout is `None`, + `TimeoutError` or `socket.error` errors. When timeout is `None`, the underlying FD is in a blocking mode. When timeout is a positive number, the FD is in a non-blocking mode, and socket ops are implemented with a `select()` call. @@ -4252,7 +4210,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args) } if (interval <= 0) { - PyErr_SetString(socket_timeout, "timed out"); + PyErr_SetString(PyExc_TimeoutError, "timed out"); goto done; } } @@ -5200,13 +5158,6 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) else #endif { - - if (PyFloat_Check(fdobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; - } - fd = PyLong_AsSocket_t(fdobj); if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) return -1; @@ -6155,13 +6106,10 @@ socket_ntohs(PyObject *self, PyObject *args) return NULL; } if (x > 0xffff) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "ntohs: Python int too large to convert to C " - "16-bit unsigned integer (The silent truncation " - "is deprecated)", - 1)) { - return NULL; - } + PyErr_SetString(PyExc_OverflowError, + "ntohs: Python int too large to convert to C " + "16-bit unsigned integer"); + return NULL; } return PyLong_FromUnsignedLong(ntohs((unsigned short)x)); } @@ -6169,12 +6117,7 @@ socket_ntohs(PyObject *self, PyObject *args) PyDoc_STRVAR(ntohs_doc, "ntohs(integer) -> integer\n\ \n\ -Convert a 16-bit unsigned integer from network to host byte order.\n\ -Note that in case the received integer does not fit in 16-bit unsigned\n\ -integer, but does fit in a positive C int, it is silently truncated to\n\ -16-bit unsigned integer.\n\ -However, this silent truncation feature is deprecated, and will raise an\n\ -exception in future versions of Python."); +Convert a 16-bit unsigned integer from network to host byte order."); static PyObject * @@ -6226,13 +6169,10 @@ socket_htons(PyObject *self, PyObject *args) return NULL; } if (x > 0xffff) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "htons: Python int too large to convert to C " - "16-bit unsigned integer (The silent truncation " - "is deprecated)", - 1)) { - return NULL; - } + PyErr_SetString(PyExc_OverflowError, + "htons: Python int too large to convert to C " + "16-bit unsigned integer"); + return NULL; } return PyLong_FromUnsignedLong(htons((unsigned short)x)); } @@ -6240,12 +6180,7 @@ socket_htons(PyObject *self, PyObject *args) PyDoc_STRVAR(htons_doc, "htons(integer) -> integer\n\ \n\ -Convert a 16-bit unsigned integer from host to network byte order.\n\ -Note that in case the received integer does not fit in 16-bit unsigned\n\ -integer, but does fit in a positive C int, it is silently truncated to\n\ -16-bit unsigned integer.\n\ -However, this silent truncation feature is deprecated, and will raise an\n\ -exception in future versions of Python."); +Convert a 16-bit unsigned integer from host to network byte order."); static PyObject * @@ -6574,10 +6509,8 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) hints.ai_protocol = protocol; hints.ai_flags = flags; Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK error = getaddrinfo(hptr, pptr, &hints, &res0); Py_END_ALLOW_THREADS - RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ if (error) { set_gaierror(error); goto err; @@ -6670,10 +6603,8 @@ socket_getnameinfo(PyObject *self, PyObject *args) hints.ai_socktype = SOCK_DGRAM; /* make numeric port happy */ hints.ai_flags = AI_NUMERICHOST; /* don't do any name resolution */ Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK error = getaddrinfo(hostp, pbuf, &hints, &res); Py_END_ALLOW_THREADS - RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ if (error) { set_gaierror(error); goto fail; @@ -7106,16 +7037,36 @@ os_init(void) } #endif +static void +sock_free_api(PySocketModule_APIObject *capi) +{ + Py_DECREF(capi->Sock_Type); + Py_DECREF(capi->error); + Py_DECREF(capi->timeout_error); + PyMem_Free(capi); +} -/* C API table - always add new things to the end for binary - compatibility. */ -static -PySocketModule_APIObject PySocketModuleAPI = +static void +sock_destroy_api(PyObject *capsule) { - &sock_type, - NULL, - NULL -}; + void *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME); + sock_free_api(capi); +} + +static PySocketModule_APIObject * +sock_get_api(void) +{ + PySocketModule_APIObject *capi = PyMem_Malloc(sizeof(PySocketModule_APIObject)); + if (capi == NULL) { + PyErr_NoMemory(); + return NULL; + } + + capi->Sock_Type = (PyTypeObject *)Py_NewRef(&sock_type); + capi->error = Py_NewRef(PyExc_OSError); + capi->timeout_error = Py_NewRef(PyExc_TimeoutError); + return capi; +} /* Initialize the _socket module. @@ -7164,8 +7115,6 @@ PyInit__socket(void) if (m == NULL) return NULL; - Py_INCREF(PyExc_OSError); - PySocketModuleAPI.error = PyExc_OSError; Py_INCREF(PyExc_OSError); PyModule_AddObject(m, "error", PyExc_OSError); socket_herror = PyErr_NewException("socket.herror", @@ -7180,13 +7129,8 @@ PyInit__socket(void) return NULL; Py_INCREF(socket_gaierror); PyModule_AddObject(m, "gaierror", socket_gaierror); - socket_timeout = PyErr_NewException("socket.timeout", - PyExc_OSError, NULL); - if (socket_timeout == NULL) - return NULL; - PySocketModuleAPI.timeout_error = socket_timeout; - Py_INCREF(socket_timeout); - PyModule_AddObject(m, "timeout", socket_timeout); + PyModule_AddObjectRef(m, "timeout", PyExc_TimeoutError); + Py_INCREF((PyObject *)&sock_type); if (PyModule_AddObject(m, "SocketType", (PyObject *)&sock_type) != 0) @@ -7205,10 +7149,24 @@ PyInit__socket(void) PyModule_AddObject(m, "has_ipv6", has_ipv6); /* Export C API */ - if (PyModule_AddObject(m, PySocket_CAPI_NAME, - PyCapsule_New(&PySocketModuleAPI, PySocket_CAPSULE_NAME, NULL) - ) != 0) + PySocketModule_APIObject *capi = sock_get_api(); + if (capi == NULL) { + Py_DECREF(m); + return NULL; + } + PyObject *capsule = PyCapsule_New(capi, + PySocket_CAPSULE_NAME, + sock_destroy_api); + if (capsule == NULL) { + sock_free_api(capi); + Py_DECREF(m); return NULL; + } + if (PyModule_AddObject(m, PySocket_CAPI_NAME, capsule) < 0) { + Py_DECREF(capsule); + Py_DECREF(m); + return NULL; + } /* Address families (we only support AF_INET and AF_UNIX) */ #ifdef AF_UNSPEC @@ -7974,6 +7932,9 @@ PyInit__socket(void) #ifdef IPPROTO_BIP PyModule_AddIntMacro(m, IPPROTO_BIP); #endif +#ifdef IPPROTO_MPTCP + PyModule_AddIntMacro(m, IPPROTO_MPTCP); +#endif /**/ #ifdef IPPROTO_RAW PyModule_AddIntMacro(m, IPPROTO_RAW); @@ -8068,6 +8029,9 @@ PyInit__socket(void) #ifdef IP_RECVRETOPTS PyModule_AddIntMacro(m, IP_RECVRETOPTS); #endif +#ifdef IP_RECVTOS + PyModule_AddIntMacro(m, IP_RECVTOS); +#endif #ifdef IP_RECVDSTADDR PyModule_AddIntMacro(m, IP_RECVDSTADDR); #endif @@ -8199,6 +8163,10 @@ PyInit__socket(void) #endif #ifdef TCP_KEEPIDLE PyModule_AddIntMacro(m, TCP_KEEPIDLE); +#endif + /* TCP_KEEPALIVE is OSX's TCP_KEEPIDLE equivalent */ +#if defined(__APPLE__) && defined(TCP_KEEPALIVE) + PyModule_AddIntMacro(m, TCP_KEEPALIVE); #endif #ifdef TCP_KEEPINTVL PyModule_AddIntMacro(m, TCP_KEEPINTVL); @@ -8434,13 +8402,16 @@ PyInit__socket(void) #endif /* _MSTCPIP_ */ /* Initialize gethostbyname lock */ -#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) +#if defined(USE_GETHOSTBYNAME_LOCK) netdb_lock = PyThread_allocate_lock(); #endif #ifdef MS_WINDOWS /* remove some flags on older version Windows during run-time */ - remove_unusable_flags(m); + if (remove_unusable_flags(m) < 0) { + Py_DECREF(m); + return NULL; + } #endif return m; diff --git a/contrib/tools/python3/src/Modules/socketmodule.h b/contrib/tools/python3/src/Modules/socketmodule.h index ba2c9f5c31c..e4f375d5e81 100644 --- a/contrib/tools/python3/src/Modules/socketmodule.h +++ b/contrib/tools/python3/src/Modules/socketmodule.h @@ -342,7 +342,8 @@ typedef struct { */ -/* C API for usage by other Python modules */ +/* C API for usage by other Python modules. + * Always add new things to the end for binary compatibility. */ typedef struct { PyTypeObject *Sock_Type; PyObject *error; diff --git a/contrib/tools/python3/src/Modules/spwdmodule.c b/contrib/tools/python3/src/Modules/spwdmodule.c index 1601ec0f2fc..acea30679bf 100644 --- a/contrib/tools/python3/src/Modules/spwdmodule.c +++ b/contrib/tools/python3/src/Modules/spwdmodule.c @@ -59,9 +59,19 @@ static PyStructSequence_Desc struct_spwd_type_desc = { 9, }; -static int initialized; -static PyTypeObject StructSpwdType; +typedef struct { + PyTypeObject *StructSpwdType; +} spwdmodulestate; +static inline spwdmodulestate* +get_spwd_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (spwdmodulestate *)state; +} + +static struct PyModuleDef spwdmodule; static void sets(PyObject *v, int i, const char* val) @@ -75,10 +85,10 @@ sets(PyObject *v, int i, const char* val) } } -static PyObject *mkspent(struct spwd *p) +static PyObject *mkspent(PyObject *module, struct spwd *p) { int setIndex = 0; - PyObject *v = PyStructSequence_New(&StructSpwdType); + PyObject *v = PyStructSequence_New(get_spwd_state(module)->StructSpwdType); if (v == NULL) return NULL; @@ -144,7 +154,7 @@ spwd_getspnam_impl(PyObject *module, PyObject *arg) PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); goto out; } - retval = mkspent(p); + retval = mkspent(module, p); out: Py_DECREF(bytes); return retval; @@ -172,7 +182,7 @@ spwd_getspall_impl(PyObject *module) return NULL; setspent(); while ((p = getspent()) != NULL) { - PyObject *v = mkspent(p); + PyObject *v = mkspent(module, p); if (v == NULL || PyList_Append(d, v) != 0) { Py_XDECREF(v); Py_DECREF(d); @@ -197,34 +207,54 @@ static PyMethodDef spwd_methods[] = { {NULL, NULL} /* sentinel */ }; +static int +spwdmodule_exec(PyObject *module) +{ + spwdmodulestate *state = get_spwd_state(module); + + state->StructSpwdType = PyStructSequence_NewType(&struct_spwd_type_desc); + if (state->StructSpwdType == NULL) { + return -1; + } + if (PyModule_AddType(module, state->StructSpwdType) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot spwdmodule_slots[] = { + {Py_mod_exec, spwdmodule_exec}, + {0, NULL} +}; + +static int spwdmodule_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(get_spwd_state(m)->StructSpwdType); + return 0; +} +static int spwdmodule_clear(PyObject *m) { + Py_CLEAR(get_spwd_state(m)->StructSpwdType); + return 0; +} + +static void spwdmodule_free(void *m) { + spwdmodule_clear((PyObject *)m); +} static struct PyModuleDef spwdmodule = { PyModuleDef_HEAD_INIT, - "spwd", - spwd__doc__, - -1, - spwd_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "spwd", + .m_doc = spwd__doc__, + .m_size = sizeof(spwdmodulestate), + .m_methods = spwd_methods, + .m_slots = spwdmodule_slots, + .m_traverse = spwdmodule_traverse, + .m_clear = spwdmodule_clear, + .m_free = spwdmodule_free, }; PyMODINIT_FUNC PyInit_spwd(void) { - PyObject *m; - m=PyModule_Create(&spwdmodule); - if (m == NULL) - return NULL; - if (!initialized) { - if (PyStructSequence_InitType2(&StructSpwdType, - &struct_spwd_type_desc) < 0) - return NULL; - } - Py_INCREF((PyObject *) &StructSpwdType); - PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType); - initialized = 1; - return m; + return PyModuleDef_Init(&spwdmodule); } diff --git a/contrib/tools/python3/src/Modules/sre_lib.h b/contrib/tools/python3/src/Modules/sre_lib.h index 2657d8d82c6..322f66fb4da 100644 --- a/contrib/tools/python3/src/Modules/sre_lib.h +++ b/contrib/tools/python3/src/Modules/sre_lib.h @@ -323,12 +323,12 @@ SRE(count)(SRE_STATE* state, const SRE_CODE* pattern, Py_ssize_t maxcount) if (!i) break; } - TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr, + TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr, (SRE_CHAR*) state->ptr - ptr)); return (SRE_CHAR*) state->ptr - ptr; } - TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr, + TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr, ptr - (SRE_CHAR*) state->ptr)); return ptr - (SRE_CHAR*) state->ptr; } @@ -414,8 +414,7 @@ SRE(info)(SRE_STATE* state, const SRE_CODE* pattern) #define DATA_STACK_ALLOC(state, type, ptr) \ do { \ alloc_pos = state->data_stack_base; \ - TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ + TRACE(("allocating %s in %zd (%zd)\n", \ Py_STRINGIFY(type), alloc_pos, sizeof(type))); \ if (sizeof(type) > state->data_stack_size - alloc_pos) { \ int j = data_stack_grow(state, sizeof(type)); \ @@ -429,14 +428,13 @@ do { \ #define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \ do { \ - TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", Py_STRINGIFY(type), pos)); \ + TRACE(("looking up %s at %zd\n", Py_STRINGIFY(type), pos)); \ ptr = (type*)(state->data_stack+pos); \ } while (0) #define DATA_STACK_PUSH(state, data, size) \ do { \ - TRACE(("copy data in %p to %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ + TRACE(("copy data in %p to %zd (%zd)\n", \ data, state->data_stack_base, size)); \ if (size > state->data_stack_size - state->data_stack_base) { \ int j = data_stack_grow(state, size); \ @@ -453,8 +451,7 @@ do { \ safely casted to `void*`, see bpo-39943 for details. */ #define DATA_STACK_POP(state, data, size, discard) \ do { \ - TRACE(("copy data to %p from %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ + TRACE(("copy data to %p from %zd (%zd)\n", \ data, state->data_stack_base-size, size)); \ memcpy((void*) data, state->data_stack+state->data_stack_base-size, size); \ if (discard) \ @@ -463,8 +460,7 @@ do { \ #define DATA_STACK_POP_DISCARD(state, size) \ do { \ - TRACE(("discard data from %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ + TRACE(("discard data from %zd (%zd)\n", \ state->data_stack_base-size, size)); \ state->data_stack_base -= size; \ } while(0) @@ -577,8 +573,7 @@ entrance: /* optimization info block */ /* <1=skip> <2=flags> <3=min> ... */ if (ctx->pattern[3] && (uintptr_t)(end - ctx->ptr) < ctx->pattern[3]) { - TRACE(("reject (got %" PY_FORMAT_SIZE_T "d chars, " - "need %" PY_FORMAT_SIZE_T "d)\n", + TRACE(("reject (got %zd chars, need %zd)\n", end - ctx->ptr, (Py_ssize_t) ctx->pattern[3])); RETURN_FAILURE; } @@ -991,7 +986,7 @@ entrance: ctx->pattern[1], ctx->pattern[2])); /* install new repeat context */ - ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep)); + ctx->u.rep = (SRE_REPEAT*) PyObject_Malloc(sizeof(*ctx->u.rep)); if (!ctx->u.rep) { PyErr_NoMemory(); RETURN_FAILURE; @@ -1005,7 +1000,7 @@ entrance: state->ptr = ctx->ptr; DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]); state->repeat = ctx->u.rep->prev; - PyObject_FREE(ctx->u.rep); + PyObject_Free(ctx->u.rep); if (ret) { RETURN_ON_ERROR(ret); @@ -1028,7 +1023,7 @@ entrance: ctx->count = ctx->u.rep->count+1; - TRACE(("|%p|%p|MAX_UNTIL %" PY_FORMAT_SIZE_T "d\n", ctx->pattern, + TRACE(("|%p|%p|MAX_UNTIL %zd\n", ctx->pattern, ctx->ptr, ctx->count)); if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { @@ -1091,7 +1086,7 @@ entrance: ctx->count = ctx->u.rep->count+1; - TRACE(("|%p|%p|MIN_UNTIL %" PY_FORMAT_SIZE_T "d %p\n", ctx->pattern, + TRACE(("|%p|%p|MIN_UNTIL %zd %p\n", ctx->pattern, ctx->ptr, ctx->count, ctx->u.rep->pattern)); if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { @@ -1358,7 +1353,7 @@ exit: TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr)); goto jump_assert_not; case JUMP_NONE: - TRACE(("|%p|%p|RETURN %" PY_FORMAT_SIZE_T "d\n", ctx->pattern, + TRACE(("|%p|%p|RETURN %zd\n", ctx->pattern, ctx->ptr, ret)); break; } @@ -1420,7 +1415,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) pattern += 1 + pattern[1]; } - TRACE(("prefix = %p %" PY_FORMAT_SIZE_T "d %" PY_FORMAT_SIZE_T "d\n", + TRACE(("prefix = %p %zd %zd\n", prefix, prefix_len, prefix_skip)); TRACE(("charset = %p\n", charset)); diff --git a/contrib/tools/python3/src/Modules/symtablemodule.c b/contrib/tools/python3/src/Modules/symtablemodule.c index 9180f185e1e..c25ecc2b5dc 100644 --- a/contrib/tools/python3/src/Modules/symtablemodule.c +++ b/contrib/tools/python3/src/Modules/symtablemodule.c @@ -1,8 +1,5 @@ #include "Python.h" - -#include "code.h" -#include "Python-ast.h" -#include "symtable.h" +#include "pycore_symtable.h" // struct symtable #include "clinic/symtablemodule.c.h" /*[clinic input] @@ -61,8 +58,7 @@ _symtable_symtable_impl(PyObject *module, PyObject *source, } t = (PyObject *)st->st_top; Py_INCREF(t); - PyMem_Free((void *)st->st_future); - PySymtable_Free(st); + _PySymtable_Free(st); return t; } @@ -71,56 +67,60 @@ 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) +{ + if (PyModule_AddIntMacro(m, USE) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_GLOBAL) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_NONLOCAL) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_LOCAL) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_PARAM) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_FREE) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_FREE_CLASS) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_IMPORT) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_BOUND) < 0) return -1; + if (PyModule_AddIntMacro(m, DEF_ANNOT) < 0) return -1; + + if (PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock) < 0) return -1; + if (PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock) < 0) + return -1; + + if (PyModule_AddIntMacro(m, LOCAL) < 0) return -1; + if (PyModule_AddIntMacro(m, GLOBAL_EXPLICIT) < 0) return -1; + if (PyModule_AddIntMacro(m, GLOBAL_IMPLICIT) < 0) return -1; + if (PyModule_AddIntMacro(m, FREE) < 0) return -1; + if (PyModule_AddIntMacro(m, CELL) < 0) return -1; + + if (PyModule_AddIntConstant(m, "SCOPE_OFF", SCOPE_OFFSET) < 0) return -1; + if (PyModule_AddIntMacro(m, SCOPE_MASK) < 0) return -1; + + return 0; +} + +static PyModuleDef_Slot symtable_slots[] = { + {Py_mod_exec, symtable_init_stentry_type}, + {Py_mod_exec, symtable_init_constants}, + {0, NULL} +}; + static struct PyModuleDef symtablemodule = { PyModuleDef_HEAD_INIT, - "_symtable", - NULL, - -1, - symtable_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_symtable", + .m_size = 0, + .m_methods = symtable_methods, + .m_slots = symtable_slots, }; PyMODINIT_FUNC PyInit__symtable(void) { - PyObject *m; - - if (PyType_Ready(&PySTEntry_Type) < 0) - return NULL; - - m = PyModule_Create(&symtablemodule); - if (m == NULL) - return NULL; - PyModule_AddIntMacro(m, USE); - PyModule_AddIntMacro(m, DEF_GLOBAL); - PyModule_AddIntMacro(m, DEF_NONLOCAL); - PyModule_AddIntMacro(m, DEF_LOCAL); - PyModule_AddIntMacro(m, DEF_PARAM); - PyModule_AddIntMacro(m, DEF_FREE); - PyModule_AddIntMacro(m, DEF_FREE_CLASS); - PyModule_AddIntMacro(m, DEF_IMPORT); - PyModule_AddIntMacro(m, DEF_BOUND); - PyModule_AddIntMacro(m, DEF_ANNOT); - - PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock); - PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock); - PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock); - - PyModule_AddIntMacro(m, LOCAL); - PyModule_AddIntMacro(m, GLOBAL_EXPLICIT); - PyModule_AddIntMacro(m, GLOBAL_IMPLICIT); - PyModule_AddIntMacro(m, FREE); - PyModule_AddIntMacro(m, CELL); - - PyModule_AddIntConstant(m, "SCOPE_OFF", SCOPE_OFFSET); - PyModule_AddIntMacro(m, SCOPE_MASK); - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = 0; - } - return m; + return PyModuleDef_Init(&symtablemodule); } diff --git a/contrib/tools/python3/src/Modules/termios.c b/contrib/tools/python3/src/Modules/termios.c index 75e5e523206..fdfe589eb80 100644 --- a/contrib/tools/python3/src/Modules/termios.c +++ b/contrib/tools/python3/src/Modules/termios.c @@ -1,4 +1,4 @@ -/* termiosmodule.c -- POSIX terminal I/O module implementation. */ +/* termios.c -- POSIX terminal I/O module implementation. */ #include "Python.h" @@ -29,6 +29,13 @@ #include #endif +/*[clinic input] +module termios +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=01105c85d0ca7252]*/ + +#include "clinic/termios.c.h" + PyDoc_STRVAR(termios__doc__, "This module provides an interface to the Posix calls for tty I/O control.\n\ For a complete description of these calls, see the Posix or Unix manual\n\ @@ -51,59 +58,46 @@ get_termios_state(PyObject *module) return (termiosmodulestate *)state; } -#define modulestate_global get_termios_state(PyState_FindModule(&termiosmodule)) +static struct PyModuleDef termiosmodule; -static int fdconv(PyObject* obj, void* p) -{ - int fd; +/*[clinic input] +termios.tcgetattr - fd = PyObject_AsFileDescriptor(obj); - if (fd >= 0) { - *(int*)p = fd; - return 1; - } - return 0; -} + fd: fildes + / -static struct PyModuleDef termiosmodule; +Get the tty attributes for file descriptor fd. -PyDoc_STRVAR(termios_tcgetattr__doc__, -"tcgetattr(fd) -> list_of_attrs\n\ -\n\ -Get the tty attributes for file descriptor fd, as follows:\n\ -[iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\ -of the tty special characters (each a string of length 1, except the items\n\ -with indices VMIN and VTIME, which are integers when these fields are\n\ -defined). The interpretation of the flags and the speeds as well as the\n\ -indexing in the cc array must be done using the symbolic constants defined\n\ -in this module."); +Returns a list [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] +where cc is a list of the tty special characters (each a string of +length 1, except the items with indices VMIN and VTIME, which are +integers when these fields are defined). The interpretation of the +flags and the speeds as well as the indexing in the cc array must be +done using the symbolic constants defined in this module. +[clinic start generated code]*/ static PyObject * -termios_tcgetattr(PyObject *self, PyObject *args) +termios_tcgetattr_impl(PyObject *module, int fd) +/*[clinic end generated code: output=2b3da39db870e629 input=54dad9779ebe74b1]*/ { - int fd; + termiosmodulestate *state = PyModule_GetState(module); struct termios mode; - PyObject *cc; - speed_t ispeed, ospeed; - PyObject *v; - int i; - char ch; - - if (!PyArg_ParseTuple(args, "O&:tcgetattr", - fdconv, (void*)&fd)) - return NULL; - - if (tcgetattr(fd, &mode) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + if (tcgetattr(fd, &mode) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } - ispeed = cfgetispeed(&mode); - ospeed = cfgetospeed(&mode); + speed_t ispeed = cfgetispeed(&mode); + speed_t ospeed = cfgetospeed(&mode); - cc = PyList_New(NCCS); - if (cc == NULL) + PyObject *cc = PyList_New(NCCS); + if (cc == NULL) { return NULL; + } + + PyObject *v; + int i; for (i = 0; i < NCCS; i++) { - ch = (char)mode.c_cc[i]; + char ch = (char)mode.c_cc[i]; v = PyBytes_FromStringAndSize(&ch, 1); if (v == NULL) goto err; @@ -144,29 +138,28 @@ termios_tcgetattr(PyObject *self, PyObject *args) return NULL; } -PyDoc_STRVAR(termios_tcsetattr__doc__, -"tcsetattr(fd, when, attributes) -> None\n\ -\n\ -Set the tty attributes for file descriptor fd.\n\ -The attributes to be set are taken from the attributes argument, which\n\ -is a list like the one returned by tcgetattr(). The when argument\n\ -determines when the attributes are changed: termios.TCSANOW to\n\ -change immediately, termios.TCSADRAIN to change after transmitting all\n\ -queued output, or termios.TCSAFLUSH to change after transmitting all\n\ -queued output and discarding all queued input. "); +/*[clinic input] +termios.tcsetattr + + fd: fildes + when: int + attributes as term: object + / + +Set the tty attributes for file descriptor fd. + +The attributes to be set are taken from the attributes argument, which +is a list like the one returned by tcgetattr(). The when argument +determines when the attributes are changed: termios.TCSANOW to +change immediately, termios.TCSADRAIN to change after transmitting all +queued output, or termios.TCSAFLUSH to change after transmitting all +queued output and discarding all queued input. +[clinic start generated code]*/ static PyObject * -termios_tcsetattr(PyObject *self, PyObject *args) +termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term) +/*[clinic end generated code: output=bcd2b0a7b98a4bf5 input=5dafabdd5a08f018]*/ { - int fd, when; - struct termios mode; - speed_t ispeed, ospeed; - PyObject *term, *cc, *v; - int i; - - if (!PyArg_ParseTuple(args, "O&iO:tcsetattr", - fdconv, &fd, &when, &term)) - return NULL; if (!PyList_Check(term) || PyList_Size(term) != 7) { PyErr_SetString(PyExc_TypeError, "tcsetattr, arg 3: must be 7 element list"); @@ -174,18 +167,22 @@ termios_tcsetattr(PyObject *self, PyObject *args) } /* Get the old mode, in case there are any hidden fields... */ - termiosmodulestate *state = modulestate_global; - if (tcgetattr(fd, &mode) == -1) + termiosmodulestate *state = PyModule_GetState(module); + struct termios mode; + if (tcgetattr(fd, &mode) == -1) { return PyErr_SetFromErrno(state->TermiosError); + } + mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0)); mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1)); mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2)); mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3)); - ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); - ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); - cc = PyList_GetItem(term, 6); - if (PyErr_Occurred()) + speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); + speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); + PyObject *cc = PyList_GetItem(term, 6); + if (PyErr_Occurred()) { return NULL; + } if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { PyErr_Format(PyExc_TypeError, @@ -194,6 +191,8 @@ termios_tcsetattr(PyObject *self, PyObject *args) return NULL; } + int i; + PyObject *v; for (i = 0; i < NCCS; i++) { v = PyList_GetItem(cc, i); @@ -218,104 +217,112 @@ termios_tcsetattr(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(termios_tcsendbreak__doc__, -"tcsendbreak(fd, duration) -> None\n\ -\n\ -Send a break on file descriptor fd.\n\ -A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\ -has a system dependent meaning."); +/*[clinic input] +termios.tcsendbreak + + fd: fildes + duration: int + / + +Send a break on file descriptor fd. + +A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration +has a system dependent meaning. +[clinic start generated code]*/ static PyObject * -termios_tcsendbreak(PyObject *self, PyObject *args) +termios_tcsendbreak_impl(PyObject *module, int fd, int duration) +/*[clinic end generated code: output=5945f589b5d3ac66 input=dc2f32417691f8ed]*/ { - int fd, duration; - - if (!PyArg_ParseTuple(args, "O&i:tcsendbreak", - fdconv, &fd, &duration)) - return NULL; - if (tcsendbreak(fd, duration) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + termiosmodulestate *state = PyModule_GetState(module); + if (tcsendbreak(fd, duration) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } -PyDoc_STRVAR(termios_tcdrain__doc__, -"tcdrain(fd) -> None\n\ -\n\ -Wait until all output written to file descriptor fd has been transmitted."); +/*[clinic input] +termios.tcdrain + + fd: fildes + / + +Wait until all output written to file descriptor fd has been transmitted. +[clinic start generated code]*/ static PyObject * -termios_tcdrain(PyObject *self, PyObject *args) +termios_tcdrain_impl(PyObject *module, int fd) +/*[clinic end generated code: output=5fd86944c6255955 input=c99241b140b32447]*/ { - int fd; - - if (!PyArg_ParseTuple(args, "O&:tcdrain", - fdconv, &fd)) - return NULL; - if (tcdrain(fd) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + termiosmodulestate *state = PyModule_GetState(module); + if (tcdrain(fd) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } -PyDoc_STRVAR(termios_tcflush__doc__, -"tcflush(fd, queue) -> None\n\ -\n\ -Discard queued data on file descriptor fd.\n\ -The queue selector specifies which queue: termios.TCIFLUSH for the input\n\ -queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\ -both queues. "); +/*[clinic input] +termios.tcflush + + fd: fildes + queue: int + / + +Discard queued data on file descriptor fd. + +The queue selector specifies which queue: termios.TCIFLUSH for the input +queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for +both queues. +[clinic start generated code]*/ static PyObject * -termios_tcflush(PyObject *self, PyObject *args) +termios_tcflush_impl(PyObject *module, int fd, int queue) +/*[clinic end generated code: output=2424f80312ec2f21 input=0f7d08122ddc07b5]*/ { - int fd, queue; - - if (!PyArg_ParseTuple(args, "O&i:tcflush", - fdconv, &fd, &queue)) - return NULL; - if (tcflush(fd, queue) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + termiosmodulestate *state = PyModule_GetState(module); + if (tcflush(fd, queue) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } -PyDoc_STRVAR(termios_tcflow__doc__, -"tcflow(fd, action) -> None\n\ -\n\ -Suspend or resume input or output on file descriptor fd.\n\ -The action argument can be termios.TCOOFF to suspend output,\n\ -termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\ -or termios.TCION to restart input."); +/*[clinic input] +termios.tcflow + + fd: fildes + action: int + / + +Suspend or resume input or output on file descriptor fd. + +The action argument can be termios.TCOOFF to suspend output, +termios.TCOON to restart output, termios.TCIOFF to suspend input, +or termios.TCION to restart input. +[clinic start generated code]*/ static PyObject * -termios_tcflow(PyObject *self, PyObject *args) +termios_tcflow_impl(PyObject *module, int fd, int action) +/*[clinic end generated code: output=afd10928e6ea66eb input=c6aff0640b6efd9c]*/ { - int fd, action; - - if (!PyArg_ParseTuple(args, "O&i:tcflow", - fdconv, &fd, &action)) - return NULL; - if (tcflow(fd, action) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + termiosmodulestate *state = PyModule_GetState(module); + if (tcflow(fd, action) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } static PyMethodDef termios_methods[] = { - {"tcgetattr", termios_tcgetattr, - METH_VARARGS, termios_tcgetattr__doc__}, - {"tcsetattr", termios_tcsetattr, - METH_VARARGS, termios_tcsetattr__doc__}, - {"tcsendbreak", termios_tcsendbreak, - METH_VARARGS, termios_tcsendbreak__doc__}, - {"tcdrain", termios_tcdrain, - METH_VARARGS, termios_tcdrain__doc__}, - {"tcflush", termios_tcflush, - METH_VARARGS, termios_tcflush__doc__}, - {"tcflow", termios_tcflow, - METH_VARARGS, termios_tcflow__doc__}, + TERMIOS_TCGETATTR_METHODDEF + TERMIOS_TCSETATTR_METHODDEF + TERMIOS_TCSENDBREAK_METHODDEF + TERMIOS_TCDRAIN_METHODDEF + TERMIOS_TCFLUSH_METHODDEF + TERMIOS_TCFLOW_METHODDEF {NULL, NULL} }; @@ -997,44 +1004,49 @@ static void termiosmodule_free(void *m) { termiosmodule_clear((PyObject *)m); } -static struct PyModuleDef termiosmodule = { - PyModuleDef_HEAD_INIT, - "termios", - termios__doc__, - sizeof(termiosmodulestate), - termios_methods, - NULL, - termiosmodule_traverse, - termiosmodule_clear, - termiosmodule_free, -}; - -PyMODINIT_FUNC -PyInit_termios(void) +static int +termios_exec(PyObject *mod) { - PyObject *m; struct constant *constant = termios_constants; - - if ((m = PyState_FindModule(&termiosmodule)) != NULL) { - Py_INCREF(m); - return m; - } - - if ((m = PyModule_Create(&termiosmodule)) == NULL) { - return NULL; - } - - termiosmodulestate *state = get_termios_state(m); + termiosmodulestate *state = get_termios_state(mod); state->TermiosError = PyErr_NewException("termios.error", NULL, NULL); if (state->TermiosError == NULL) { - return NULL; + return -1; } Py_INCREF(state->TermiosError); - PyModule_AddObject(m, "error", state->TermiosError); + if (PyModule_AddObject(mod, "error", state->TermiosError) < 0) { + Py_DECREF(state->TermiosError); + return -1; + } while (constant->name != NULL) { - PyModule_AddIntConstant(m, constant->name, constant->value); + if (PyModule_AddIntConstant( + mod, constant->name, constant->value) < 0) { + return -1; + } ++constant; } - return m; + return 0; +} + +static PyModuleDef_Slot termios_slots[] = { + {Py_mod_exec, termios_exec}, + {0, NULL} +}; + +static struct PyModuleDef termiosmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "termios", + .m_doc = termios__doc__, + .m_size = sizeof(termiosmodulestate), + .m_methods = termios_methods, + .m_slots = termios_slots, + .m_traverse = termiosmodule_traverse, + .m_clear = termiosmodule_clear, + .m_free = termiosmodule_free, +}; + +PyMODINIT_FUNC PyInit_termios(void) +{ + return PyModuleDef_Init(&termiosmodule); } diff --git a/contrib/tools/python3/src/Modules/timemodule.c b/contrib/tools/python3/src/Modules/timemodule.c index df59f2aac5a..4caacc3b64d 100644 --- a/contrib/tools/python3/src/Modules/timemodule.c +++ b/contrib/tools/python3/src/Modules/timemodule.c @@ -74,10 +74,21 @@ _PyFloat_FromPyTime(_PyTime_t t) } +static int +get_system_time(_PyTime_t *t) +{ + // Avoid _PyTime_GetSystemClock() which silently ignores errors. + return _PyTime_GetSystemClockWithInfo(t, NULL); +} + + static PyObject * time_time(PyObject *self, PyObject *unused) { - _PyTime_t t = _PyTime_GetSystemClock(); + _PyTime_t t; + if (get_system_time(&t) < 0) { + return NULL; + } return _PyFloat_FromPyTime(t); } @@ -91,7 +102,10 @@ Fractions of a second may be present if the system clock provides them."); static PyObject * time_time_ns(PyObject *self, PyObject *unused) { - _PyTime_t t = _PyTime_GetSystemClock(); + _PyTime_t t; + if (get_system_time(&t) < 0) { + return NULL; + } return _PyTime_AsNanosecondsObject(t); } @@ -147,15 +161,6 @@ _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) } #endif /* HAVE_CLOCK */ -static PyObject* -perf_counter(_Py_clock_info_t *info) -{ - _PyTime_t t; - if (_PyTime_GetPerfCounterWithInfo(&t, info) < 0) { - return NULL; - } - return _PyFloat_FromPyTime(t); -} #ifdef HAVE_CLOCK_GETTIME @@ -1096,10 +1101,22 @@ the local timezone used by methods such as localtime, but this behaviour\n\ should not be relied on."); #endif /* HAVE_WORKING_TZSET */ + +static int +get_monotonic(_PyTime_t *t) +{ + // Avoid _PyTime_GetMonotonicClock() which silently ignores errors. + return _PyTime_GetMonotonicClockWithInfo(t, NULL); +} + + static PyObject * time_monotonic(PyObject *self, PyObject *unused) { - _PyTime_t t = _PyTime_GetMonotonicClock(); + _PyTime_t t; + if (get_monotonic(&t) < 0) { + return NULL; + } return _PyFloat_FromPyTime(t); } @@ -1111,7 +1128,10 @@ Monotonic clock, cannot go backward."); static PyObject * time_monotonic_ns(PyObject *self, PyObject *unused) { - _PyTime_t t = _PyTime_GetMonotonicClock(); + _PyTime_t t; + if (get_monotonic(&t) < 0) { + return NULL; + } return _PyTime_AsNanosecondsObject(t); } @@ -1120,10 +1140,23 @@ PyDoc_STRVAR(monotonic_ns_doc, \n\ Monotonic clock, cannot go backward, as nanoseconds."); + +static int +get_perf_counter(_PyTime_t *t) +{ + // Avoid _PyTime_GetPerfCounter() which silently ignores errors. + return _PyTime_GetPerfCounterWithInfo(t, NULL); +} + + static PyObject * time_perf_counter(PyObject *self, PyObject *unused) { - return perf_counter(NULL); + _PyTime_t t; + if (get_perf_counter(&t) < 0) { + return NULL; + } + return _PyFloat_FromPyTime(t); } PyDoc_STRVAR(perf_counter_doc, @@ -1131,10 +1164,14 @@ PyDoc_STRVAR(perf_counter_doc, \n\ Performance counter for benchmarking."); + static PyObject * time_perf_counter_ns(PyObject *self, PyObject *unused) { - _PyTime_t t = _PyTime_GetPerfCounter(); + _PyTime_t t; + if (get_perf_counter(&t) < 0) { + return NULL; + } return _PyTime_AsNanosecondsObject(t); } @@ -2025,7 +2062,10 @@ pysleep(_PyTime_t secs) HANDLE hInterruptEvent; #endif - deadline = _PyTime_GetMonotonicClock() + secs; + if (get_monotonic(&monotonic) < 0) { + return -1; + } + deadline = monotonic + secs; do { #ifndef MS_WINDOWS @@ -2077,10 +2117,13 @@ pysleep(_PyTime_t secs) if (PyErr_CheckSignals()) return -1; - monotonic = _PyTime_GetMonotonicClock(); + if (get_monotonic(&monotonic) < 0) { + return -1; + } secs = deadline - monotonic; - if (secs < 0) + if (secs < 0) { break; + } /* retry with the recomputed delay */ } while (1); diff --git a/contrib/tools/python3/src/Modules/unicodedata.c b/contrib/tools/python3/src/Modules/unicodedata.c index 8a1198a2b71..f87eb608798 100644 --- a/contrib/tools/python3/src/Modules/unicodedata.c +++ b/contrib/tools/python3/src/Modules/unicodedata.c @@ -16,7 +16,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "ucnhash.h" +#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include "structmember.h" // PyMemberDef #include @@ -28,9 +28,9 @@ _Py_IDENTIFIER(NFKD); /*[clinic input] module unicodedata -class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type' +class unicodedata.UCD 'PreviousDBVersion *' '' [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e47113e05924be43]*/ /* character properties */ @@ -90,22 +90,26 @@ static PyMemberDef DB_members[] = { {NULL} }; -/* forward declaration */ -static PyTypeObject UCD_Type; -#define UCD_Check(o) Py_IS_TYPE(o, &UCD_Type) +// Check if self is an unicodedata.UCD instance. +// If self is NULL (when the PyCapsule C API is used), return 0. +// PyModule_Check() is used to avoid having to retrieve the ucd_type. +// See unicodedata_functions comment to the rationale of this macro. +#define UCD_Check(self) (self != NULL && !PyModule_Check(self)) static PyObject* -new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), +new_previous_version(PyTypeObject *ucd_type, + const char*name, const change_record* (*getrecord)(Py_UCS4), Py_UCS4 (*normalization)(Py_UCS4)) { - PreviousDBVersion *self; - self = PyObject_New(PreviousDBVersion, &UCD_Type); - if (self == NULL) - return NULL; - self->name = name; - self->getrecord = getrecord; - self->normalization = normalization; - return (PyObject*)self; + PreviousDBVersion *self; + self = PyObject_GC_New(PreviousDBVersion, ucd_type); + if (self == NULL) + return NULL; + self->name = name; + self->getrecord = getrecord; + self->normalization = normalization; + PyObject_GC_Track(self); + return (PyObject*)self; } @@ -135,7 +139,7 @@ unicodedata_UCD_decimal_impl(PyObject *self, int chr, long rc; Py_UCS4 c = (Py_UCS4)chr; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -223,7 +227,7 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, double rc; Py_UCS4 c = (Py_UCS4)chr; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -268,7 +272,7 @@ unicodedata_UCD_category_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->category; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed != 0xFF) index = old->category_changed; @@ -295,7 +299,7 @@ unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->bidirectional; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -324,7 +328,7 @@ unicodedata_UCD_combining_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->combining; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -352,7 +356,7 @@ unicodedata_UCD_mirrored_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->mirrored; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -379,7 +383,7 @@ unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->east_asian_width; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -413,7 +417,7 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) code = (int)c; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) return PyUnicode_FromString(""); /* unassigned */ @@ -456,12 +460,14 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) } static void -get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count) +get_decomp_record(PyObject *self, Py_UCS4 code, + int *index, int *prefix, int *count) { if (code >= 0x110000) { *index = 0; - } else if (self && UCD_Check(self) && - get_old_record(self, code)->category_changed==0) { + } + else if (UCD_Check(self) + && get_old_record(self, code)->category_changed==0) { /* unassigned in old version */ *index = 0; } @@ -558,7 +564,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) continue; } /* normalization changes */ - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code); if (value != 0) { stack[stackptr++] = value; @@ -794,13 +800,13 @@ typedef enum {YES = 0, MAYBE = 1, NO = 2} QuickcheckResult; * https://www.unicode.org/reports/tr15/#Detecting_Normalization_Forms */ static QuickcheckResult -is_normalized_quickcheck(PyObject *self, PyObject *input, - bool nfc, bool k, bool yes_only) +is_normalized_quickcheck(PyObject *self, PyObject *input, bool nfc, bool k, + bool yes_only) { - /* An older version of the database is requested, quickchecks must be - disabled. */ - if (self && UCD_Check(self)) + /* UCD 3.2.0 is requested, quickchecks must be disabled. */ + if (UCD_Check(self)) { return NO; + } Py_ssize_t i, len; int kind; @@ -940,28 +946,32 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { - if (is_normalized_quickcheck(self, input, true, false, true) == YES) { + if (is_normalized_quickcheck(self, input, + true, false, true) == YES) { Py_INCREF(input); return input; } return nfc_nfkc(self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { - if (is_normalized_quickcheck(self, input, true, true, true) == YES) { + if (is_normalized_quickcheck(self, input, + true, true, true) == YES) { Py_INCREF(input); return input; } return nfc_nfkc(self, input, 1); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { - if (is_normalized_quickcheck(self, input, false, false, true) == YES) { + if (is_normalized_quickcheck(self, input, + false, false, true) == YES) { Py_INCREF(input); return input; } return nfd_nfkd(self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { - if (is_normalized_quickcheck(self, input, false, true, true) == YES) { + if (is_normalized_quickcheck(self, input, + false, true, true) == YES) { Py_INCREF(input); return input; } @@ -1048,8 +1058,8 @@ is_unified_ideograph(Py_UCS4 code) (cp < named_sequences_end)) static int -_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, - int with_alias_and_seq) +_getucname(PyObject *self, + Py_UCS4 code, char* buffer, int buflen, int with_alias_and_seq) { /* Find the name associated with the given code point. * If with_alias_and_seq is 1, check for names in the Private Use Area 15 @@ -1066,7 +1076,7 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code))) return 0; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { /* in 3.2.0 there are no aliases and named sequences */ const change_record *old; if (IS_ALIAS(code) || IS_NAMED_SEQ(code)) @@ -1149,6 +1159,15 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, return 1; } +static int +capi_getucname(Py_UCS4 code, + char* buffer, int buflen, + int with_alias_and_seq) +{ + return _getucname(NULL, code, buffer, buflen, with_alias_and_seq); + +} + static int _cmpname(PyObject *self, int code, const char* name, int namelen) { @@ -1200,8 +1219,8 @@ _check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq) } static int -_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, - int with_named_seq) +_getcode(PyObject* self, + const char* name, int namelen, Py_UCS4* code, int with_named_seq) { /* Return the code point associated with the given name. * Named aliases are resolved too (unless self != NULL (i.e. we are using @@ -1262,8 +1281,9 @@ _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, v = code_hash[i]; if (!v) return 0; - if (_cmpname(self, v, name, namelen)) + if (_cmpname(self, v, name, namelen)) { return _check_alias_and_seq(v, code, with_named_seq); + } incr = (h ^ (h >> 3)) & mask; if (!incr) incr = mask; @@ -1272,21 +1292,51 @@ _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, v = code_hash[i]; if (!v) return 0; - if (_cmpname(self, v, name, namelen)) + if (_cmpname(self, v, name, namelen)) { return _check_alias_and_seq(v, code, with_named_seq); + } incr = incr << 1; if (incr > mask) incr = incr ^ code_poly; } } -static const _PyUnicode_Name_CAPI hashAPI = +static int +capi_getcode(const char* name, int namelen, Py_UCS4* code, + int with_named_seq) +{ + return _getcode(NULL, name, namelen, code, with_named_seq); + +} + +static void +unicodedata_destroy_capi(PyObject *capsule) { - sizeof(_PyUnicode_Name_CAPI), - _getucname, - _getcode + void *capi = PyCapsule_GetPointer(capsule, PyUnicodeData_CAPSULE_NAME); + PyMem_Free(capi); +} + +static PyObject * +unicodedata_create_capi(void) +{ + _PyUnicode_Name_CAPI *capi = PyMem_Malloc(sizeof(_PyUnicode_Name_CAPI)); + if (capi == NULL) { + PyErr_NoMemory(); + return NULL; + } + capi->getname = capi_getucname; + capi->getcode = capi_getcode; + + PyObject *capsule = PyCapsule_New(capi, + PyUnicodeData_CAPSULE_NAME, + unicodedata_destroy_capi); + if (capsule == NULL) { + PyMem_Free(capi); + } + return capsule; }; + /* -------------------------------------------------------------------- */ /* Python bindings */ @@ -1365,8 +1415,10 @@ unicodedata_UCD_lookup_impl(PyObject *self, const char *name, return PyUnicode_FromOrdinal(code); } -/* XXX Add doc strings. */ - +// List of functions used to define module functions *AND* unicodedata.UCD +// methods. For module functions, self is the module. For UCD methods, self +// is an UCD instance. The UCD_Check() macro is used to check if self is +// an UCD instance. static PyMethodDef unicodedata_functions[] = { UNICODEDATA_UCD_DECIMAL_METHODDEF UNICODEDATA_UCD_DIGIT_METHODDEF @@ -1384,50 +1436,37 @@ static PyMethodDef unicodedata_functions[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject UCD_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "unicodedata.UCD", /*tp_name*/ - sizeof(PreviousDBVersion), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PyObject_Del, /*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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - unicodedata_functions, /*tp_methods*/ - DB_members, /*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*/ - 0, /*tp_is_gc*/ +static int +ucd_traverse(PreviousDBVersion *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static void +ucd_dealloc(PreviousDBVersion *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot ucd_type_slots[] = { + {Py_tp_dealloc, ucd_dealloc}, + {Py_tp_traverse, ucd_traverse}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_methods, unicodedata_functions}, + {Py_tp_members, DB_members}, + {0, 0} +}; + +static PyType_Spec ucd_type_spec = { + .name = "unicodedata.UCD", + .basicsize = sizeof(PreviousDBVersion), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = ucd_type_slots }; PyDoc_STRVAR(unicodedata_docstring, @@ -1439,45 +1478,70 @@ this database is based on the UnicodeData.txt file version\n\ The module uses the same names and symbols as defined by the\n\ UnicodeData File Format " UNIDATA_VERSION "."); -static struct PyModuleDef unicodedatamodule = { - PyModuleDef_HEAD_INIT, - "unicodedata", - unicodedata_docstring, - -1, - unicodedata_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_unicodedata(void) +static int +unicodedata_exec(PyObject *module) { - PyObject *m, *v; - - Py_SET_TYPE(&UCD_Type, &PyType_Type); + if (PyModule_AddStringConstant(module, "unidata_version", UNIDATA_VERSION) < 0) { + return -1; + } - m = PyModule_Create(&unicodedatamodule); - if (!m) - return NULL; + PyTypeObject *ucd_type = (PyTypeObject *)PyType_FromSpec(&ucd_type_spec); + if (ucd_type == NULL) { + return -1; + } - PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION); - Py_INCREF(&UCD_Type); - PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type); + if (PyModule_AddType(module, ucd_type) < 0) { + Py_DECREF(ucd_type); + return -1; + } - /* Previous versions */ - v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0); - if (v != NULL) - PyModule_AddObject(m, "ucd_3_2_0", v); + // Unicode database version 3.2.0 used by the IDNA encoding + PyObject *v; + v = new_previous_version(ucd_type, "3.2.0", + get_change_3_2_0, normalization_3_2_0); + Py_DECREF(ucd_type); + if (v == NULL) { + return -1; + } + if (PyModule_AddObject(module, "ucd_3_2_0", v) < 0) { + Py_DECREF(v); + return -1; + } /* Export C API */ - v = PyCapsule_New((void *)&hashAPI, PyUnicodeData_CAPSULE_NAME, NULL); - if (v != NULL) - PyModule_AddObject(m, "ucnhash_CAPI", v); - return m; + PyObject *capsule = unicodedata_create_capi(); + if (capsule == NULL) { + return -1; + } + int rc = PyModule_AddObjectRef(module, "_ucnhash_CAPI", capsule); + Py_DECREF(capsule); + if (rc < 0) { + return -1; + } + return 0; } +static PyModuleDef_Slot unicodedata_slots[] = { + {Py_mod_exec, unicodedata_exec}, + {0, NULL} +}; + +static struct PyModuleDef unicodedata_module = { + PyModuleDef_HEAD_INIT, + .m_name = "unicodedata", + .m_doc = unicodedata_docstring, + .m_size = 0, + .m_methods = unicodedata_functions, + .m_slots = unicodedata_slots, +}; + +PyMODINIT_FUNC +PyInit_unicodedata(void) +{ + return PyModuleDef_Init(&unicodedata_module); +} + + /* Local variables: c-basic-offset: 4 diff --git a/contrib/tools/python3/src/Modules/zlibmodule.c b/contrib/tools/python3/src/Modules/zlibmodule.c index 4dfd4ae6722..a6940f2fd43 100644 --- a/contrib/tools/python3/src/Modules/zlibmodule.c +++ b/contrib/tools/python3/src/Modules/zlibmodule.c @@ -9,11 +9,166 @@ #include "structmember.h" // PyMemberDef #include "zlib.h" +// Blocks output buffer wrappers +#include "pycore_blocks_output_buffer.h" -#define ENTER_ZLIB(obj) \ - Py_BEGIN_ALLOW_THREADS; \ - PyThread_acquire_lock((obj)->lock, 1); \ - Py_END_ALLOW_THREADS; +#if OUTPUT_BUFFER_MAX_BLOCK_SIZE > UINT32_MAX + #error "The maximum block size accepted by zlib is UINT32_MAX." +#endif + +/* On success, return value >= 0 + On failure, return -1 */ +static inline Py_ssize_t +OutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer, Py_ssize_t max_length, + Bytef **next_out, uint32_t *avail_out) +{ + Py_ssize_t allocated; + + allocated = _BlocksOutputBuffer_InitAndGrow( + buffer, max_length, (void**) next_out); + *avail_out = (uint32_t) allocated; + return allocated; +} + +/* On success, return value >= 0 + On failure, return -1 */ +static inline Py_ssize_t +OutputBuffer_Grow(_BlocksOutputBuffer *buffer, + Bytef **next_out, uint32_t *avail_out) +{ + Py_ssize_t allocated; + + allocated = _BlocksOutputBuffer_Grow( + buffer, (void**) next_out, (Py_ssize_t) *avail_out); + *avail_out = (uint32_t) allocated; + return allocated; +} + +static inline Py_ssize_t +OutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer, uint32_t avail_out) +{ + return _BlocksOutputBuffer_GetDataSize(buffer, (Py_ssize_t) avail_out); +} + +static inline PyObject * +OutputBuffer_Finish(_BlocksOutputBuffer *buffer, uint32_t avail_out) +{ + return _BlocksOutputBuffer_Finish(buffer, (Py_ssize_t) avail_out); +} + +static inline void +OutputBuffer_OnError(_BlocksOutputBuffer *buffer) +{ + _BlocksOutputBuffer_OnError(buffer); +} + +/* The max buffer size accepted by zlib is UINT32_MAX, the initial buffer size + `init_size` may > it in 64-bit build. These wrapper functions maintain an + UINT32_MAX sliding window for the first block: + 1. OutputBuffer_WindowInitWithSize() + 2. OutputBuffer_WindowGrow() + 3. OutputBuffer_WindowFinish() + 4. OutputBuffer_WindowOnError() + + ==== is the sliding window: + 1. ====------ + ^ next_posi, left_bytes is 6 + 2. ----====-- + ^ next_posi, left_bytes is 2 + 3. --------== + ^ next_posi, left_bytes is 0 */ +typedef struct { + Py_ssize_t left_bytes; + Bytef *next_posi; +} _Uint32Window; + +/* Initialize the buffer with an initial buffer size. + + On success, return value >= 0 + On failure, return value < 0 */ +static inline Py_ssize_t +OutputBuffer_WindowInitWithSize(_BlocksOutputBuffer *buffer, _Uint32Window *window, + Py_ssize_t init_size, + Bytef **next_out, uint32_t *avail_out) +{ + Py_ssize_t allocated = _BlocksOutputBuffer_InitWithSize( + buffer, init_size, (void**) next_out); + + if (allocated >= 0) { + // the UINT32_MAX sliding window + Py_ssize_t window_size = Py_MIN((size_t)allocated, UINT32_MAX); + *avail_out = (uint32_t) window_size; + + window->left_bytes = allocated - window_size; + window->next_posi = *next_out + window_size; + } + return allocated; +} + +/* Grow the buffer. + + On success, return value >= 0 + On failure, return value < 0 */ +static inline Py_ssize_t +OutputBuffer_WindowGrow(_BlocksOutputBuffer *buffer, _Uint32Window *window, + Bytef **next_out, uint32_t *avail_out) +{ + Py_ssize_t allocated; + + /* ensure no gaps in the data. + if inlined, this check could be optimized away.*/ + if (*avail_out != 0) { + PyErr_SetString(PyExc_SystemError, + "*avail_out != 0 in OutputBuffer_WindowGrow()."); + return -1; + } + + // slide the UINT32_MAX sliding window + if (window->left_bytes > 0) { + Py_ssize_t window_size = Py_MIN((size_t)window->left_bytes, UINT32_MAX); + + *next_out = window->next_posi; + *avail_out = (uint32_t) window_size; + + window->left_bytes -= window_size; + window->next_posi += window_size; + + return window_size; + } + assert(window->left_bytes == 0); + + // only the first block may > UINT32_MAX + allocated = _BlocksOutputBuffer_Grow( + buffer, (void**) next_out, (Py_ssize_t) *avail_out); + *avail_out = (uint32_t) allocated; + return allocated; +} + +/* Finish the buffer. + + On success, return a bytes object + On failure, return NULL */ +static inline PyObject * +OutputBuffer_WindowFinish(_BlocksOutputBuffer *buffer, _Uint32Window *window, + uint32_t avail_out) +{ + Py_ssize_t real_avail_out = (Py_ssize_t) avail_out + window->left_bytes; + return _BlocksOutputBuffer_Finish(buffer, real_avail_out); +} + +static inline void +OutputBuffer_WindowOnError(_BlocksOutputBuffer *buffer, _Uint32Window *window) +{ + _BlocksOutputBuffer_OnError(buffer); +} + + +#define ENTER_ZLIB(obj) do { \ + if (!PyThread_acquire_lock((obj)->lock, 0)) { \ + Py_BEGIN_ALLOW_THREADS \ + PyThread_acquire_lock((obj)->lock, 1); \ + Py_END_ALLOW_THREADS \ + } } while (0) #define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock); #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221 @@ -37,18 +192,16 @@ typedef struct { PyTypeObject *Comptype; PyTypeObject *Decomptype; PyObject *ZlibError; -} _zlibstate; +} zlibstate; -static inline _zlibstate* +static inline zlibstate* get_zlib_state(PyObject *module) { void *state = PyModule_GetState(module); assert(state != NULL); - return (_zlibstate *)state; + return (zlibstate *)state; } -#define _zlibstate_global ((_zlibstate *)PyModule_GetState(PyState_FindModule(&zlibmodule))) - typedef struct { PyObject_HEAD @@ -62,7 +215,7 @@ typedef struct } compobject; static void -zlib_error(z_stream zst, int err, const char *msg) +zlib_error(zlibstate *state, z_stream zst, int err, const char *msg) { const char *zmsg = Z_NULL; /* In case of a version mismatch, zst.msg won't be initialized. @@ -85,9 +238,9 @@ zlib_error(z_stream zst, int err, const char *msg) } } if (zmsg == Z_NULL) - PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s", err, msg); + PyErr_Format(state->ZlibError, "Error %d %s", err, msg); else - PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s: %.200s", err, msg, zmsg); + PyErr_Format(state->ZlibError, "Error %d %s: %.200s", err, msg, zmsg); } /*[clinic input] @@ -149,56 +302,6 @@ arrange_input_buffer(z_stream *zst, Py_ssize_t *remains) *remains -= zst->avail_in; } -static Py_ssize_t -arrange_output_buffer_with_maximum(z_stream *zst, 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 = zst->next_out - (Byte *)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; - } - } - - zst->avail_out = (uInt)Py_MIN((size_t)(length - occupied), UINT_MAX); - zst->next_out = (Byte *)PyBytes_AS_STRING(*buffer) + occupied; - - return length; -} - -static Py_ssize_t -arrange_output_buffer(z_stream *zst, PyObject **buffer, Py_ssize_t length) -{ - Py_ssize_t ret; - - ret = arrange_output_buffer_with_maximum(zst, buffer, length, - PY_SSIZE_T_MAX); - if (ret == -2) - PyErr_NoMemory(); - - return ret; -} - /*[clinic input] zlib.compress @@ -215,20 +318,25 @@ static PyObject * zlib_compress_impl(PyObject *module, Py_buffer *data, int level) /*[clinic end generated code: output=d80906d73f6294c8 input=638d54b6315dbed3]*/ { - PyObject *RetVal = NULL; - Byte *ibuf; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; - int err, flush; + PyObject *RetVal; + int flush; z_stream zst; + _BlocksOutputBuffer buffer = {.list = NULL}; - ibuf = data->buf; - ibuflen = data->len; + zlibstate *state = get_zlib_state(module); + + Byte *ibuf = data->buf; + Py_ssize_t ibuflen = data->len; + + if (OutputBuffer_InitAndGrow(&buffer, -1, &zst.next_out, &zst.avail_out) < 0) { + goto error; + } zst.opaque = NULL; zst.zalloc = PyZlib_Malloc; zst.zfree = PyZlib_Free; zst.next_in = ibuf; - err = deflateInit(&zst, level); + int err = deflateInit(&zst, level); switch (err) { case Z_OK: @@ -238,11 +346,11 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) "Out of memory while compressing data"); goto error; case Z_STREAM_ERROR: - PyErr_SetString(_zlibstate_global->ZlibError, "Bad compression level"); + PyErr_SetString(state->ZlibError, "Bad compression level"); goto error; default: deflateEnd(&zst); - zlib_error(zst, err, "while compressing data"); + zlib_error(state, zst, err, "while compressing data"); goto error; } @@ -251,10 +359,11 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; do { - obuflen = arrange_output_buffer(&zst, &RetVal, obuflen); - if (obuflen < 0) { - deflateEnd(&zst); - goto error; + if (zst.avail_out == 0) { + if (OutputBuffer_Grow(&buffer, &zst.next_out, &zst.avail_out) < 0) { + deflateEnd(&zst); + goto error; + } } Py_BEGIN_ALLOW_THREADS @@ -263,7 +372,7 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) if (err == Z_STREAM_ERROR) { deflateEnd(&zst); - zlib_error(zst, err, "while compressing data"); + zlib_error(state, zst, err, "while compressing data"); goto error; } @@ -275,49 +384,19 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) err = deflateEnd(&zst); if (err == Z_OK) { - if (_PyBytes_Resize(&RetVal, zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) < 0) + RetVal = OutputBuffer_Finish(&buffer, zst.avail_out); + if (RetVal == NULL) { goto error; + } return RetVal; } else - zlib_error(zst, err, "while finishing compression"); + zlib_error(state, zst, err, "while finishing compression"); error: - Py_XDECREF(RetVal); + OutputBuffer_OnError(&buffer); return NULL; } -/*[python input] - -class ssize_t_converter(CConverter): - type = 'Py_ssize_t' - converter = 'ssize_t_converter' - c_ignored_default = "0" - -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=5f34ba1b394cb8e7]*/ - -static int -ssize_t_converter(PyObject *obj, void *ptr) -{ - PyObject *long_obj; - Py_ssize_t val; - - /* XXX Should be replaced with PyNumber_AsSsize_t after the end of the - deprecation period. */ - long_obj = _PyLong_FromNbIndexOrNbInt(obj); - if (long_obj == NULL) { - return 0; - } - val = PyLong_AsSsize_t(long_obj); - Py_DECREF(long_obj); - if (val == -1 && PyErr_Occurred()) { - return 0; - } - *(Py_ssize_t *)ptr = val; - return 1; -} - /*[clinic input] zlib.decompress @@ -326,7 +405,7 @@ zlib.decompress / wbits: int(c_default="MAX_WBITS") = MAX_WBITS The window buffer size and container format. - bufsize: ssize_t(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE + bufsize: Py_ssize_t(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE The initial output buffer size. Returns a bytes object containing the uncompressed data. @@ -335,13 +414,17 @@ Returns a bytes object containing the uncompressed data. static PyObject * zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, Py_ssize_t bufsize) -/*[clinic end generated code: output=77c7e35111dc8c42 input=21960936208e9a5b]*/ +/*[clinic end generated code: output=77c7e35111dc8c42 input=a9ac17beff1f893f]*/ { - PyObject *RetVal = NULL; + PyObject *RetVal; Byte *ibuf; Py_ssize_t ibuflen; int err, flush; z_stream zst; + _BlocksOutputBuffer buffer = {.list = NULL}; + _Uint32Window window; // output buffer's UINT32_MAX sliding window + + zlibstate *state = get_zlib_state(module); if (bufsize < 0) { PyErr_SetString(PyExc_ValueError, "bufsize must be non-negative"); @@ -350,6 +433,11 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, bufsize = 1; } + if (OutputBuffer_WindowInitWithSize(&buffer, &window, bufsize, + &zst.next_out, &zst.avail_out) < 0) { + goto error; + } + ibuf = data->buf; ibuflen = data->len; @@ -369,7 +457,7 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, goto error; default: inflateEnd(&zst); - zlib_error(zst, err, "while preparing to decompress data"); + zlib_error(state, zst, err, "while preparing to decompress data"); goto error; } @@ -378,10 +466,12 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; do { - bufsize = arrange_output_buffer(&zst, &RetVal, bufsize); - if (bufsize < 0) { - inflateEnd(&zst); - goto error; + if (zst.avail_out == 0) { + if (OutputBuffer_WindowGrow(&buffer, &window, + &zst.next_out, &zst.avail_out) < 0) { + inflateEnd(&zst); + goto error; + } } Py_BEGIN_ALLOW_THREADS @@ -400,7 +490,7 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, goto error; default: inflateEnd(&zst); - zlib_error(zst, err, "while decompressing data"); + zlib_error(state, zst, err, "while decompressing data"); goto error; } @@ -411,24 +501,23 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, if (err != Z_STREAM_END) { inflateEnd(&zst); - zlib_error(zst, err, "while decompressing data"); + zlib_error(state, zst, err, "while decompressing data"); goto error; } err = inflateEnd(&zst); if (err != Z_OK) { - zlib_error(zst, err, "while finishing decompression"); + zlib_error(state, zst, err, "while finishing decompression"); goto error; } - if (_PyBytes_Resize(&RetVal, zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) < 0) - goto error; - - return RetVal; + RetVal = OutputBuffer_WindowFinish(&buffer, &window, zst.avail_out); + if (RetVal != NULL) { + return RetVal; + } error: - Py_XDECREF(RetVal); + OutputBuffer_WindowOnError(&buffer, &window); return NULL; } @@ -465,16 +554,14 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict) /*[clinic end generated code: output=8b5bed9c8fc3814d input=2fa3d026f90ab8d5]*/ { - compobject *self = NULL; - int err; - + zlibstate *state = get_zlib_state(module); if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "zdict length does not fit in an unsigned int"); - goto error; + return NULL; } - self = newcompobject(_zlibstate_global->Comptype); + compobject *self = newcompobject(state->Comptype); if (self == NULL) goto error; self->zst.opaque = NULL; @@ -482,7 +569,7 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, self->zst.zfree = PyZlib_Free; self->zst.next_in = NULL; self->zst.avail_in = 0; - err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); + int err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); switch (err) { case Z_OK: self->is_initialised = 1; @@ -510,7 +597,7 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); goto error; default: - zlib_error(self->zst, err, "while creating compression object"); + zlib_error(state, self->zst, err, "while creating compression object"); goto error; } @@ -521,11 +608,9 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, } static int -set_inflate_zdict(compobject *self) +set_inflate_zdict(zlibstate *state, compobject *self) { Py_buffer zdict_buf; - int err; - if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) { return -1; } @@ -535,11 +620,12 @@ set_inflate_zdict(compobject *self) 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(self->zst, err, "while setting zdict"); + zlib_error(state, self->zst, err, "while setting zdict"); return -1; } return 0; @@ -561,8 +647,7 @@ static PyObject * zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) /*[clinic end generated code: output=3069b99994f36906 input=d3832b8511fc977b]*/ { - int err; - compobject *self; + zlibstate *state = get_zlib_state(module); if (zdict != NULL && !PyObject_CheckBuffer(zdict)) { PyErr_SetString(PyExc_TypeError, @@ -570,7 +655,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) return NULL; } - self = newcompobject(_zlibstate_global->Decomptype); + compobject *self = newcompobject(state->Decomptype); if (self == NULL) return NULL; self->zst.opaque = NULL; @@ -582,18 +667,18 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) Py_INCREF(zdict); self->zdict = zdict; } - err = inflateInit2(&self->zst, wbits); + 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(self) < 0) { + if (set_inflate_zdict(state, self) < 0) { Py_DECREF(self); return NULL; } #else - PyErr_Format(_zlibstate_global->ZlibError, + PyErr_Format(state->ZlibError, "zlib version %s does not allow raw inflate with dictionary", ZLIB_VERSION); Py_DECREF(self); @@ -611,7 +696,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) "Can't allocate memory for decompression object"); return NULL; default: - zlib_error(self->zst, err, "while creating decompression object"); + zlib_error(state, self->zst, err, "while creating decompression object"); Py_DECREF(self); return NULL; } @@ -625,7 +710,7 @@ Dealloc(compobject *self) Py_XDECREF(self->unused_data); Py_XDECREF(self->unconsumed_tail); Py_XDECREF(self->zdict); - PyObject_Del(self); + PyObject_Free(self); Py_DECREF(type); } @@ -648,6 +733,7 @@ Decomp_dealloc(compobject *self) /*[clinic input] zlib.Compress.compress + cls: defining_class data: Py_buffer Binary data to be compressed. / @@ -660,32 +746,40 @@ Call the flush() method to clear these buffers. [clinic start generated code]*/ static PyObject * -zlib_Compress_compress_impl(compobject *self, Py_buffer *data) -/*[clinic end generated code: output=5d5cd791cbc6a7f4 input=0d95908d6e64fab8]*/ +zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data) +/*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ { - PyObject *RetVal = NULL; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; + PyObject *RetVal; int err; + _BlocksOutputBuffer buffer = {.list = NULL}; + zlibstate *state = PyType_GetModuleState(cls); ENTER_ZLIB(self); self->zst.next_in = data->buf; - ibuflen = data->len; + Py_ssize_t ibuflen = data->len; + + if (OutputBuffer_InitAndGrow(&buffer, -1, &self->zst.next_out, &self->zst.avail_out) < 0) { + goto error; + } do { arrange_input_buffer(&self->zst, &ibuflen); do { - obuflen = arrange_output_buffer(&self->zst, &RetVal, obuflen); - if (obuflen < 0) - goto error; + if (self->zst.avail_out == 0) { + if (OutputBuffer_Grow(&buffer, &self->zst.next_out, &self->zst.avail_out) < 0) { + goto error; + } + } Py_BEGIN_ALLOW_THREADS err = deflate(&self->zst, Z_NO_FLUSH); Py_END_ALLOW_THREADS if (err == Z_STREAM_ERROR) { - zlib_error(self->zst, err, "while compressing data"); + zlib_error(state, self->zst, err, "while compressing data"); goto error; } @@ -694,12 +788,14 @@ zlib_Compress_compress_impl(compobject *self, Py_buffer *data) } while (ibuflen != 0); - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) == 0) + RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (RetVal != NULL) { goto success; + } error: - Py_CLEAR(RetVal); + OutputBuffer_OnError(&buffer); + RetVal = NULL; success: LEAVE_ZLIB(self); return RetVal; @@ -753,10 +849,11 @@ save_unconsumed_input(compobject *self, Py_buffer *data, int err) /*[clinic input] zlib.Decompress.decompress + cls: defining_class data: Py_buffer The binary data to decompress. / - max_length: ssize_t = 0 + max_length: Py_ssize_t = 0 The maximum allowable length of the decompressed data. Unconsumed input data will be stored in the unconsumed_tail attribute. @@ -769,45 +866,47 @@ Call the flush() method to clear these buffers. [clinic start generated code]*/ static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, - Py_ssize_t max_length) -/*[clinic end generated code: output=6e5173c74e710352 input=b85a212a012b770a]*/ +zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data, Py_ssize_t max_length) +/*[clinic end generated code: output=b024a93c2c922d57 input=bfb37b3864cfb606]*/ { int err = Z_OK; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE, hard_limit; - PyObject *RetVal = NULL; + Py_ssize_t ibuflen; + PyObject *RetVal; + _BlocksOutputBuffer buffer = {.list = NULL}; + PyObject *module = PyType_GetModule(cls); + if (module == NULL) + return NULL; + + zlibstate *state = get_zlib_state(module); if (max_length < 0) { PyErr_SetString(PyExc_ValueError, "max_length must be non-negative"); return NULL; - } else if (max_length == 0) - hard_limit = PY_SSIZE_T_MAX; - else - hard_limit = max_length; + } else if (max_length == 0) { + max_length = -1; + } ENTER_ZLIB(self); self->zst.next_in = data->buf; ibuflen = data->len; - /* limit amount of data allocated to max_length */ - if (max_length && obuflen > max_length) - obuflen = max_length; + if (OutputBuffer_InitAndGrow(&buffer, max_length, &self->zst.next_out, &self->zst.avail_out) < 0) { + goto abort; + } do { arrange_input_buffer(&self->zst, &ibuflen); do { - obuflen = arrange_output_buffer_with_maximum(&self->zst, &RetVal, - obuflen, hard_limit); - if (obuflen == -2) { - if (max_length > 0) { + if (self->zst.avail_out == 0) { + if (OutputBuffer_GetDataSize(&buffer, self->zst.avail_out) == max_length) { goto save; } - PyErr_NoMemory(); - } - if (obuflen < 0) { - goto abort; + if (OutputBuffer_Grow(&buffer, &self->zst.next_out, &self->zst.avail_out) < 0) { + goto abort; + } } Py_BEGIN_ALLOW_THREADS @@ -821,8 +920,9 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, break; default: if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(self) < 0) + if (set_inflate_zdict(state, self) < 0) { goto abort; + } else break; } @@ -846,16 +946,18 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, but there wasn't more output when we tried again, so it is not an error condition. */ - zlib_error(self->zst, err, "while decompressing data"); + zlib_error(state, self->zst, err, "while decompressing data"); goto abort; } - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) == 0) + RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (RetVal != NULL) { goto success; + } abort: - Py_CLEAR(RetVal); + OutputBuffer_OnError(&buffer); + RetVal = NULL; success: LEAVE_ZLIB(self); return RetVal; @@ -864,6 +966,7 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, /*[clinic input] zlib.Compress.flush + cls: defining_class mode: int(c_default="Z_FINISH") = zlib.Z_FINISH One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH. If mode == Z_FINISH, the compressor object can no longer be @@ -875,13 +978,14 @@ Return a bytes object containing any remaining compressed data. [clinic start generated code]*/ static PyObject * -zlib_Compress_flush_impl(compobject *self, int mode) -/*[clinic end generated code: output=a203f4cefc9de727 input=73ed066794bd15bc]*/ +zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode) +/*[clinic end generated code: output=c7efd13efd62add2 input=286146e29442eb6c]*/ { int err; - Py_ssize_t length = DEF_BUF_SIZE; - PyObject *RetVal = NULL; + PyObject *RetVal; + _BlocksOutputBuffer buffer = {.list = NULL}; + zlibstate *state = PyType_GetModuleState(cls); /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in doing any work at all; just return an empty string. */ if (mode == Z_NO_FLUSH) { @@ -892,11 +996,15 @@ zlib_Compress_flush_impl(compobject *self, int mode) self->zst.avail_in = 0; + if (OutputBuffer_InitAndGrow(&buffer, -1, &self->zst.next_out, &self->zst.avail_out) < 0) { + goto error; + } + do { - length = arrange_output_buffer(&self->zst, &RetVal, length); - if (length < 0) { - Py_CLEAR(RetVal); - goto error; + if (self->zst.avail_out == 0) { + if (OutputBuffer_Grow(&buffer, &self->zst.next_out, &self->zst.avail_out) < 0) { + goto error; + } } Py_BEGIN_ALLOW_THREADS @@ -904,8 +1012,7 @@ zlib_Compress_flush_impl(compobject *self, int mode) Py_END_ALLOW_THREADS if (err == Z_STREAM_ERROR) { - zlib_error(self->zst, err, "while flushing"); - Py_CLEAR(RetVal); + zlib_error(state, self->zst, err, "while flushing"); goto error; } } while (self->zst.avail_out == 0); @@ -917,8 +1024,7 @@ zlib_Compress_flush_impl(compobject *self, int mode) if (err == Z_STREAM_END && mode == Z_FINISH) { err = deflateEnd(&self->zst); if (err != Z_OK) { - zlib_error(self->zst, err, "while finishing compression"); - Py_CLEAR(RetVal); + zlib_error(state, self->zst, err, "while finishing compression"); goto error; } else @@ -929,16 +1035,19 @@ zlib_Compress_flush_impl(compobject *self, int mode) not an error condition. */ } else if (err != Z_OK && err != Z_BUF_ERROR) { - zlib_error(self->zst, err, "while flushing"); - Py_CLEAR(RetVal); + zlib_error(state, self->zst, err, "while flushing"); goto error; } - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) < 0) - Py_CLEAR(RetVal); + RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (RetVal != NULL) { + goto success; + } - error: +error: + OutputBuffer_OnError(&buffer); + RetVal = NULL; +success: LEAVE_ZLIB(self); return RetVal; } @@ -948,24 +1057,25 @@ zlib_Compress_flush_impl(compobject *self, int mode) /*[clinic input] zlib.Compress.copy + cls: defining_class + Return a copy of the compression object. [clinic start generated code]*/ static PyObject * -zlib_Compress_copy_impl(compobject *self) -/*[clinic end generated code: output=5144aa153c21e805 input=c656351f94b82718]*/ +zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=c4d2cfb4b0d7350b input=235497e482d40986]*/ { - compobject *retval = NULL; - int err; + zlibstate *state = PyType_GetModuleState(cls); - retval = newcompobject(_zlibstate_global->Comptype); + compobject *retval = newcompobject(state->Comptype); if (!retval) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - err = deflateCopy(&retval->zst, &self->zst); + int err = deflateCopy(&retval->zst, &self->zst); switch (err) { case Z_OK: break; @@ -977,7 +1087,7 @@ zlib_Compress_copy_impl(compobject *self) "Can't allocate memory for compression object"); goto error; default: - zlib_error(self->zst, err, "while copying compression object"); + zlib_error(state, self->zst, err, "while copying compression object"); goto error; } Py_INCREF(self->unused_data); @@ -1002,51 +1112,57 @@ error: /*[clinic input] zlib.Compress.__copy__ + + cls: defining_class + [clinic start generated code]*/ static PyObject * -zlib_Compress___copy___impl(compobject *self) -/*[clinic end generated code: output=1875e6791975442e input=be97a05a788dfd83]*/ +zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=074613db332cb668 input=5c0188367ab0fe64]*/ { - return zlib_Compress_copy_impl(self); + return zlib_Compress_copy_impl(self, cls); } /*[clinic input] zlib.Compress.__deepcopy__ + cls: defining_class memo: object / [clinic start generated code]*/ static PyObject * -zlib_Compress___deepcopy__(compobject *self, PyObject *memo) -/*[clinic end generated code: output=f47a2213282c9eb0 input=a9a8b0b40d83388e]*/ +zlib_Compress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo) +/*[clinic end generated code: output=24b3aed785f54033 input=c90347319a514430]*/ { - return zlib_Compress_copy_impl(self); + return zlib_Compress_copy_impl(self, cls); } /*[clinic input] zlib.Decompress.copy + cls: defining_class + Return a copy of the decompression object. [clinic start generated code]*/ static PyObject * -zlib_Decompress_copy_impl(compobject *self) -/*[clinic end generated code: output=02a883a2a510c8cc input=ba6c3e96712a596b]*/ +zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=a7ddc016e1d0a781 input=20ef3aa208282ff2]*/ { - compobject *retval = NULL; - int err; + zlibstate *state = PyType_GetModuleState(cls); - retval = newcompobject(_zlibstate_global->Decomptype); + compobject *retval = newcompobject(state->Decomptype); if (!retval) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - err = inflateCopy(&retval->zst, &self->zst); + int err = inflateCopy(&retval->zst, &self->zst); switch (err) { case Z_OK: break; @@ -1058,7 +1174,7 @@ zlib_Decompress_copy_impl(compobject *self) "Can't allocate memory for decompression object"); goto error; default: - zlib_error(self->zst, err, "while copying decompression object"); + zlib_error(state, self->zst, err, "while copying decompression object"); goto error; } @@ -1084,28 +1200,33 @@ error: /*[clinic input] zlib.Decompress.__copy__ + + cls: defining_class + [clinic start generated code]*/ static PyObject * -zlib_Decompress___copy___impl(compobject *self) -/*[clinic end generated code: output=80bae8bc43498ad4 input=efcb98b5472c13d2]*/ +zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=cf1e6473744f53fa input=cc3143067b622bdf]*/ { - return zlib_Decompress_copy_impl(self); + return zlib_Decompress_copy_impl(self, cls); } /*[clinic input] zlib.Decompress.__deepcopy__ + cls: defining_class memo: object / [clinic start generated code]*/ static PyObject * -zlib_Decompress___deepcopy__(compobject *self, PyObject *memo) -/*[clinic end generated code: output=1f77286ab490124b input=6e99bd0ac4b9cd8b]*/ +zlib_Decompress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo) +/*[clinic end generated code: output=34f7b719a0c0d51b input=fc13b9c58622544e]*/ { - return zlib_Decompress_copy_impl(self); + return zlib_Decompress_copy_impl(self, cls); } #endif @@ -1113,7 +1234,8 @@ zlib_Decompress___deepcopy__(compobject *self, PyObject *memo) /*[clinic input] zlib.Decompress.flush - length: ssize_t(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE + cls: defining_class + length: Py_ssize_t(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE the initial size of the output buffer. / @@ -1121,13 +1243,23 @@ Return a bytes object containing any remaining decompressed data. [clinic start generated code]*/ static PyObject * -zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) -/*[clinic end generated code: output=68c75ea127cbe654 input=aa4ec37f3aef4da0]*/ +zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, + Py_ssize_t length) +/*[clinic end generated code: output=4532fc280bd0f8f2 input=42f1f4b75230e2cd]*/ { int err, flush; Py_buffer data; - PyObject *RetVal = NULL; + PyObject *RetVal; Py_ssize_t ibuflen; + _BlocksOutputBuffer buffer = {.list = NULL}; + _Uint32Window window; // output buffer's UINT32_MAX sliding window + + PyObject *module = PyType_GetModule(cls); + if (module == NULL) { + return NULL; + } + + zlibstate *state = get_zlib_state(module); if (length <= 0) { PyErr_SetString(PyExc_ValueError, "length must be greater than zero"); @@ -1144,14 +1276,22 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) self->zst.next_in = data.buf; ibuflen = data.len; + if (OutputBuffer_WindowInitWithSize(&buffer, &window, length, + &self->zst.next_out, &self->zst.avail_out) < 0) { + goto abort; + } + do { arrange_input_buffer(&self->zst, &ibuflen); flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; do { - length = arrange_output_buffer(&self->zst, &RetVal, length); - if (length < 0) - goto abort; + if (self->zst.avail_out == 0) { + if (OutputBuffer_WindowGrow(&buffer, &window, + &self->zst.next_out, &self->zst.avail_out) < 0) { + goto abort; + } + } Py_BEGIN_ALLOW_THREADS err = inflate(&self->zst, flush); @@ -1164,8 +1304,9 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) break; default: if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(self) < 0) + if (set_inflate_zdict(state, self) < 0) { goto abort; + } else break; } @@ -1177,8 +1318,9 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) } while (err != Z_STREAM_END && ibuflen != 0); save: - if (save_unconsumed_input(self, &data, err) < 0) + if (save_unconsumed_input(self, &data, err) < 0) { goto abort; + } /* If at end of stream, clean up any memory allocated by zlib. */ if (err == Z_STREAM_END) { @@ -1186,17 +1328,19 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) self->is_initialised = 0; err = inflateEnd(&self->zst); if (err != Z_OK) { - zlib_error(self->zst, err, "while finishing decompression"); + zlib_error(state, self->zst, err, "while finishing decompression"); goto abort; } } - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) == 0) + RetVal = OutputBuffer_WindowFinish(&buffer, &window, self->zst.avail_out); + if (RetVal != NULL) { goto success; + } abort: - Py_CLEAR(RetVal); + OutputBuffer_WindowOnError(&buffer, &window); + RetVal = NULL; success: PyBuffer_Release(&data); LEAVE_ZLIB(self); @@ -1332,11 +1476,10 @@ static PyType_Slot Comptype_slots[] = { }; static PyType_Spec Comptype_spec = { - "zlib.Compress", - sizeof(compobject), - 0, - Py_TPFLAGS_DEFAULT, - Comptype_slots + .name = "zlib.Compress", + .basicsize = sizeof(compobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .slots= Comptype_slots, }; static PyType_Slot Decomptype_slots[] = { @@ -1347,11 +1490,10 @@ static PyType_Slot Decomptype_slots[] = { }; static PyType_Spec Decomptype_spec = { - "zlib.Decompress", - sizeof(compobject), - 0, - Py_TPFLAGS_DEFAULT, - Decomptype_slots + .name = "zlib.Decompress", + .basicsize = sizeof(compobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .slots = Decomptype_slots, }; PyDoc_STRVAR(zlib_module_documentation, @@ -1370,9 +1512,9 @@ PyDoc_STRVAR(zlib_module_documentation, "objects support decompress() and flush()."); static int -zlib_clear(PyObject *m) +zlib_clear(PyObject *mod) { - _zlibstate *state = get_zlib_state(m); + zlibstate *state = get_zlib_state(mod); Py_CLEAR(state->Comptype); Py_CLEAR(state->Decomptype); Py_CLEAR(state->ZlibError); @@ -1380,9 +1522,9 @@ zlib_clear(PyObject *m) } static int -zlib_traverse(PyObject *m, visitproc visit, void *arg) +zlib_traverse(PyObject *mod, visitproc visit, void *arg) { - _zlibstate *state = get_zlib_state(m); + zlibstate *state = get_zlib_state(mod); Py_VISIT(state->Comptype); Py_VISIT(state->Decomptype); Py_VISIT(state->ZlibError); @@ -1390,93 +1532,122 @@ zlib_traverse(PyObject *m, visitproc visit, void *arg) } static void -zlib_free(void *m) +zlib_free(void *mod) { - zlib_clear((PyObject *)m); + zlib_clear((PyObject *)mod); } -static struct PyModuleDef zlibmodule = { - PyModuleDef_HEAD_INIT, - "zlib", - zlib_module_documentation, - sizeof(_zlibstate), - zlib_methods, - NULL, - zlib_traverse, - zlib_clear, - zlib_free, -}; - -PyMODINIT_FUNC -PyInit_zlib(void) +static int +zlib_exec(PyObject *mod) { - PyObject *m, *ver; - m = PyState_FindModule(&zlibmodule); - if (m != NULL) { - Py_INCREF(m); - return m; + zlibstate *state = get_zlib_state(mod); + + state->Comptype = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &Comptype_spec, NULL); + if (state->Comptype == NULL) { + return -1; } - m = PyModule_Create(&zlibmodule); - if (m == NULL) - return NULL; - PyTypeObject *Comptype = (PyTypeObject *)PyType_FromSpec(&Comptype_spec); - if (Comptype == NULL) - return NULL; - get_zlib_state(m)->Comptype = Comptype; + state->Decomptype = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &Decomptype_spec, NULL); + if (state->Decomptype == NULL) { + return -1; + } - PyTypeObject *Decomptype = (PyTypeObject *)PyType_FromSpec(&Decomptype_spec); - if (Decomptype == NULL) - return NULL; - get_zlib_state(m)->Decomptype = Decomptype; + state->ZlibError = PyErr_NewException("zlib.error", NULL, NULL); + if (state->ZlibError == NULL) { + return -1; + } - PyObject *ZlibError = PyErr_NewException("zlib.error", NULL, NULL); - if (ZlibError != NULL) { - Py_INCREF(ZlibError); - PyModule_AddObject(m, "error", ZlibError); - get_zlib_state(m)->ZlibError = ZlibError; + Py_INCREF(state->ZlibError); + if (PyModule_AddObject(mod, "error", state->ZlibError) < 0) { + Py_DECREF(state->ZlibError); + return -1; } - PyModule_AddIntMacro(m, MAX_WBITS); - PyModule_AddIntMacro(m, DEFLATED); - PyModule_AddIntMacro(m, DEF_MEM_LEVEL); - PyModule_AddIntMacro(m, DEF_BUF_SIZE); + +#define ZLIB_ADD_INT_MACRO(c) \ + do { \ + if ((PyModule_AddIntConstant(mod, #c, c)) < 0) { \ + return -1; \ + } \ + } while(0) + + ZLIB_ADD_INT_MACRO(MAX_WBITS); + ZLIB_ADD_INT_MACRO(DEFLATED); + ZLIB_ADD_INT_MACRO(DEF_MEM_LEVEL); + ZLIB_ADD_INT_MACRO(DEF_BUF_SIZE); // compression levels - PyModule_AddIntMacro(m, Z_NO_COMPRESSION); - PyModule_AddIntMacro(m, Z_BEST_SPEED); - PyModule_AddIntMacro(m, Z_BEST_COMPRESSION); - PyModule_AddIntMacro(m, Z_DEFAULT_COMPRESSION); + ZLIB_ADD_INT_MACRO(Z_NO_COMPRESSION); + ZLIB_ADD_INT_MACRO(Z_BEST_SPEED); + ZLIB_ADD_INT_MACRO(Z_BEST_COMPRESSION); + ZLIB_ADD_INT_MACRO(Z_DEFAULT_COMPRESSION); // compression strategies - PyModule_AddIntMacro(m, Z_FILTERED); - PyModule_AddIntMacro(m, Z_HUFFMAN_ONLY); + ZLIB_ADD_INT_MACRO(Z_FILTERED); + ZLIB_ADD_INT_MACRO(Z_HUFFMAN_ONLY); #ifdef Z_RLE // 1.2.0.1 - PyModule_AddIntMacro(m, Z_RLE); + ZLIB_ADD_INT_MACRO(Z_RLE); #endif #ifdef Z_FIXED // 1.2.2.2 - PyModule_AddIntMacro(m, Z_FIXED); + ZLIB_ADD_INT_MACRO(Z_FIXED); #endif - PyModule_AddIntMacro(m, Z_DEFAULT_STRATEGY); + ZLIB_ADD_INT_MACRO(Z_DEFAULT_STRATEGY); // allowed flush values - PyModule_AddIntMacro(m, Z_NO_FLUSH); - PyModule_AddIntMacro(m, Z_PARTIAL_FLUSH); - PyModule_AddIntMacro(m, Z_SYNC_FLUSH); - PyModule_AddIntMacro(m, Z_FULL_FLUSH); - PyModule_AddIntMacro(m, Z_FINISH); + ZLIB_ADD_INT_MACRO(Z_NO_FLUSH); + ZLIB_ADD_INT_MACRO(Z_PARTIAL_FLUSH); + ZLIB_ADD_INT_MACRO(Z_SYNC_FLUSH); + ZLIB_ADD_INT_MACRO(Z_FULL_FLUSH); + ZLIB_ADD_INT_MACRO(Z_FINISH); #ifdef Z_BLOCK // 1.2.0.5 for inflate, 1.2.3.4 for deflate - PyModule_AddIntMacro(m, Z_BLOCK); + ZLIB_ADD_INT_MACRO(Z_BLOCK); #endif #ifdef Z_TREES // 1.2.3.4, only for inflate - PyModule_AddIntMacro(m, Z_TREES); + ZLIB_ADD_INT_MACRO(Z_TREES); #endif - ver = PyUnicode_FromString(ZLIB_VERSION); - if (ver != NULL) - PyModule_AddObject(m, "ZLIB_VERSION", ver); + PyObject *ver = PyUnicode_FromString(ZLIB_VERSION); + if (ver == NULL) { + return -1; + } + + if (PyModule_AddObject(mod, "ZLIB_VERSION", ver) < 0) { + Py_DECREF(ver); + return -1; + } ver = PyUnicode_FromString(zlibVersion()); - if (ver != NULL) - PyModule_AddObject(m, "ZLIB_RUNTIME_VERSION", ver); + if (ver == NULL) { + return -1; + } + + if (PyModule_AddObject(mod, "ZLIB_RUNTIME_VERSION", ver) < 0) { + Py_DECREF(ver); + return -1; + } - PyModule_AddStringConstant(m, "__version__", "1.0"); + if (PyModule_AddStringConstant(mod, "__version__", "1.0") < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot zlib_slots[] = { + {Py_mod_exec, zlib_exec}, + {0, NULL} +}; - PyState_AddModule(m, &zlibmodule); - return m; +static struct PyModuleDef zlibmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "zlib", + .m_doc = zlib_module_documentation, + .m_size = sizeof(zlibstate), + .m_methods = zlib_methods, + .m_slots = zlib_slots, + .m_traverse = zlib_traverse, + .m_clear = zlib_clear, + .m_free = zlib_free, +}; + +PyMODINIT_FUNC +PyInit_zlib(void) +{ + return PyModuleDef_Init(&zlibmodule); } diff --git a/contrib/tools/python3/src/Objects/abstract.c b/contrib/tools/python3/src/Objects/abstract.c index a5cbb12ff87..3ac85544def 100644 --- a/contrib/tools/python3/src/Objects/abstract.c +++ b/contrib/tools/python3/src/Objects/abstract.c @@ -3,8 +3,10 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_ceval.h" // _Py_EnterRecursiveCall() -#include "pycore_pyerrors.h" +#include "pycore_object.h" // _Py_CheckSlotResult() +#include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_unionobject.h" // _PyUnion_Check() #include #include // offsetof() #include "longintrepr.h" @@ -23,9 +25,11 @@ type_error(const char *msg, PyObject *obj) static PyObject * null_error(void) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_SystemError, - "null argument to internal routine"); + PyThreadState *tstate = _PyThreadState_GET(); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_SystemError, + "null argument to internal routine"); + } return NULL; } @@ -48,17 +52,15 @@ PyObject_Type(PyObject *o) Py_ssize_t PyObject_Size(PyObject *o) { - PySequenceMethods *m; - if (o == NULL) { null_error(); return -1; } - m = Py_TYPE(o)->tp_as_sequence; + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; if (m && m->sq_length) { Py_ssize_t len = m->sq_length(o); - assert(len >= 0 || PyErr_Occurred()); + assert(_Py_CheckSlotResult(o, "__len__", len >= 0)); return len; } @@ -94,11 +96,12 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) if (_PyObject_HasLen(o)) { res = PyObject_Length(o); if (res < 0) { - assert(PyErr_Occurred()); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) { + PyThreadState *tstate = _PyThreadState_GET(); + assert(_PyErr_Occurred(tstate)); + if (!_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { return -1; } - PyErr_Clear(); + _PyErr_Clear(tstate); } else { return res; @@ -114,8 +117,9 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) result = _PyObject_CallNoArg(hint); Py_DECREF(hint); if (result == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Clear(); + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { + _PyErr_Clear(tstate); return defaultvalue; } return -1; @@ -145,21 +149,18 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) PyObject * PyObject_GetItem(PyObject *o, PyObject *key) { - PyMappingMethods *m; - PySequenceMethods *ms; - if (o == NULL || key == NULL) { return null_error(); } - m = Py_TYPE(o)->tp_as_mapping; + PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; if (m && m->mp_subscript) { PyObject *item = m->mp_subscript(o, key); - assert((item != NULL) ^ (PyErr_Occurred() != NULL)); + assert(_Py_CheckSlotResult(o, "__getitem__", item != NULL)); return item; } - ms = Py_TYPE(o)->tp_as_sequence; + PySequenceMethods *ms = Py_TYPE(o)->tp_as_sequence; if (ms && ms->sq_item) { if (_PyIndex_Check(key)) { Py_ssize_t key_value; @@ -199,15 +200,17 @@ PyObject_GetItem(PyObject *o, PyObject *key) int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) { - PyMappingMethods *m; - if (o == NULL || key == NULL || value == NULL) { null_error(); return -1; } - m = Py_TYPE(o)->tp_as_mapping; - if (m && m->mp_ass_subscript) - return m->mp_ass_subscript(o, key, value); + + PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; + if (m && m->mp_ass_subscript) { + int res = m->mp_ass_subscript(o, key, value); + assert(_Py_CheckSlotResult(o, "__setitem__", res >= 0)); + return res; + } if (Py_TYPE(o)->tp_as_sequence) { if (_PyIndex_Check(key)) { @@ -231,15 +234,17 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) int PyObject_DelItem(PyObject *o, PyObject *key) { - PyMappingMethods *m; - if (o == NULL || key == NULL) { null_error(); return -1; } - m = Py_TYPE(o)->tp_as_mapping; - if (m && m->mp_ass_subscript) - return m->mp_ass_subscript(o, key, (PyObject*)NULL); + + PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; + if (m && m->mp_ass_subscript) { + int res = m->mp_ass_subscript(o, key, (PyObject*)NULL); + assert(_Py_CheckSlotResult(o, "__delitem__", res >= 0)); + return res; + } if (Py_TYPE(o)->tp_as_sequence) { if (_PyIndex_Check(key)) { @@ -380,7 +385,9 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) Py_TYPE(obj)->tp_name); return -1; } - return (*pb->bf_getbuffer)(obj, view, flags); + int res = (*pb->bf_getbuffer)(obj, view, flags); + assert(_Py_CheckSlotResult(obj, "getbuffer", res >= 0)); + return res; } static int @@ -708,7 +715,7 @@ PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, { if (view == NULL) { PyErr_SetString(PyExc_BufferError, - "PyBuffer_FillInfo: view==NULL argument is obsolete"); + "PyBuffer_FillInfo: view==NULL argument is obsolete"); return -1; } @@ -749,8 +756,9 @@ PyBuffer_Release(Py_buffer *view) if (obj == NULL) return; pb = Py_TYPE(obj)->tp_as_buffer; - if (pb && pb->bf_releasebuffer) + if (pb && pb->bf_releasebuffer) { pb->bf_releasebuffer(obj, view); + } view->obj = NULL; Py_DECREF(obj); } @@ -790,10 +798,12 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) /* Find the (unbound!) __format__ method */ meth = _PyObject_LookupSpecial(obj, &PyId___format__); if (meth == NULL) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); + PyThreadState *tstate = _PyThreadState_GET(); + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); + } goto done; } @@ -803,8 +813,8 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) if (result && !PyUnicode_Check(result)) { PyErr_Format(PyExc_TypeError, - "__format__ must return a str, not %.200s", - Py_TYPE(result)->tp_name); + "__format__ must return a str, not %.200s", + Py_TYPE(result)->tp_name); Py_DECREF(result); result = NULL; goto done; @@ -819,10 +829,10 @@ done: int PyNumber_Check(PyObject *o) { - return o && Py_TYPE(o)->tp_as_number && - (Py_TYPE(o)->tp_as_number->nb_index || - Py_TYPE(o)->tp_as_number->nb_int || - Py_TYPE(o)->tp_as_number->nb_float); + if (o == NULL) + return 0; + PyNumberMethods *nb = Py_TYPE(o)->tp_as_number; + return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o)); } /* Binary operators */ @@ -844,21 +854,33 @@ PyNumber_Check(PyObject *o) */ static PyObject * -binary_op1(PyObject *v, PyObject *w, const int op_slot) -{ - PyObject *x; - binaryfunc slotv = NULL; - binaryfunc slotw = NULL; - - if (Py_TYPE(v)->tp_as_number != NULL) +binary_op1(PyObject *v, PyObject *w, const int op_slot +#ifndef NDEBUG + , const char *op_name +#endif + ) +{ + binaryfunc slotv; + if (Py_TYPE(v)->tp_as_number != NULL) { slotv = NB_BINOP(Py_TYPE(v)->tp_as_number, op_slot); - if (!Py_IS_TYPE(w, Py_TYPE(v)) && - Py_TYPE(w)->tp_as_number != NULL) { + } + else { + slotv = NULL; + } + + binaryfunc slotw; + if (!Py_IS_TYPE(w, Py_TYPE(v)) && Py_TYPE(w)->tp_as_number != NULL) { slotw = NB_BINOP(Py_TYPE(w)->tp_as_number, op_slot); - if (slotw == slotv) + if (slotw == slotv) { slotw = NULL; + } + } + else { + slotw = NULL; } + if (slotv) { + PyObject *x; if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) { x = slotw(v, w); if (x != Py_NotImplemented) @@ -867,19 +889,29 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot) slotw = NULL; } x = slotv(v, w); - if (x != Py_NotImplemented) + assert(_Py_CheckSlotResult(v, op_name, x != NULL)); + if (x != Py_NotImplemented) { return x; + } Py_DECREF(x); /* can't do it */ } if (slotw) { - x = slotw(v, w); - if (x != Py_NotImplemented) + PyObject *x = slotw(v, w); + assert(_Py_CheckSlotResult(w, op_name, x != NULL)); + if (x != Py_NotImplemented) { return x; + } Py_DECREF(x); /* can't do it */ } Py_RETURN_NOTIMPLEMENTED; } +#ifdef NDEBUG +# define BINARY_OP1(v, w, op_slot, op_name) binary_op1(v, w, op_slot) +#else +# define BINARY_OP1(v, w, op_slot, op_name) binary_op1(v, w, op_slot, op_name) +#endif + static PyObject * binop_type_error(PyObject *v, PyObject *w, const char *op_name) { @@ -895,7 +927,7 @@ binop_type_error(PyObject *v, PyObject *w, const char *op_name) static PyObject * binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) { - PyObject *result = binary_op1(v, w, op_slot); + PyObject *result = BINARY_OP1(v, w, op_slot, op_name); if (result == Py_NotImplemented) { Py_DECREF(result); @@ -912,7 +944,6 @@ binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) Py_TYPE(w)->tp_name); return NULL; } - return binop_type_error(v, w, op_name); } return result; @@ -931,70 +962,92 @@ ternary_op(PyObject *v, PyObject *w, PyObject *z, const int op_slot, - const char *op_name) + const char *op_name + ) { - PyNumberMethods *mv, *mw, *mz; - PyObject *x = NULL; - ternaryfunc slotv = NULL; - ternaryfunc slotw = NULL; - ternaryfunc slotz = NULL; + PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; + PyNumberMethods *mw = Py_TYPE(w)->tp_as_number; - mv = Py_TYPE(v)->tp_as_number; - mw = Py_TYPE(w)->tp_as_number; - if (mv != NULL) + ternaryfunc slotv; + if (mv != NULL) { slotv = NB_TERNOP(mv, op_slot); + } + else { + slotv = NULL; + } + + ternaryfunc slotw; if (!Py_IS_TYPE(w, Py_TYPE(v)) && mw != NULL) { slotw = NB_TERNOP(mw, op_slot); - if (slotw == slotv) + if (slotw == slotv) { slotw = NULL; + } + } + else { + slotw = NULL; } + if (slotv) { + PyObject *x; if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) { x = slotw(v, w, z); - if (x != Py_NotImplemented) + if (x != Py_NotImplemented) { return x; + } Py_DECREF(x); /* can't do it */ slotw = NULL; } x = slotv(v, w, z); - if (x != Py_NotImplemented) + assert(_Py_CheckSlotResult(v, op_name, x != NULL)); + if (x != Py_NotImplemented) { return x; + } Py_DECREF(x); /* can't do it */ } if (slotw) { - x = slotw(v, w, z); - if (x != Py_NotImplemented) + PyObject *x = slotw(v, w, z); + assert(_Py_CheckSlotResult(w, op_name, x != NULL)); + if (x != Py_NotImplemented) { return x; + } Py_DECREF(x); /* can't do it */ } - mz = Py_TYPE(z)->tp_as_number; + + PyNumberMethods *mz = Py_TYPE(z)->tp_as_number; if (mz != NULL) { - slotz = NB_TERNOP(mz, op_slot); - if (slotz == slotv || slotz == slotw) + ternaryfunc slotz = NB_TERNOP(mz, op_slot); + if (slotz == slotv || slotz == slotw) { slotz = NULL; + } if (slotz) { - x = slotz(v, w, z); - if (x != Py_NotImplemented) + PyObject *x = slotz(v, w, z); + assert(_Py_CheckSlotResult(z, op_name, x != NULL)); + if (x != Py_NotImplemented) { return x; + } Py_DECREF(x); /* can't do it */ } } - if (z == Py_None) + if (z == Py_None) { PyErr_Format( PyExc_TypeError, - "unsupported operand type(s) for ** or pow(): " + "unsupported operand type(s) for %.100s: " "'%.100s' and '%.100s'", + op_name, Py_TYPE(v)->tp_name, Py_TYPE(w)->tp_name); - else + } + else { PyErr_Format( PyExc_TypeError, - "unsupported operand type(s) for pow(): " + "unsupported operand type(s) for %.100s: " "'%.100s', '%.100s', '%.100s'", + op_name, Py_TYPE(v)->tp_name, Py_TYPE(w)->tp_name, Py_TYPE(z)->tp_name); + } return NULL; } @@ -1015,16 +1068,20 @@ BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()") PyObject * PyNumber_Add(PyObject *v, PyObject *w) { - PyObject *result = binary_op1(v, w, NB_SLOT(nb_add)); - if (result == Py_NotImplemented) { - PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; - Py_DECREF(result); - if (m && m->sq_concat) { - return (*m->sq_concat)(v, w); - } - result = binop_type_error(v, w, "+"); + PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_add), "+"); + if (result != Py_NotImplemented) { + return result; } - return result; + Py_DECREF(result); + + PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; + if (m && m->sq_concat) { + result = (*m->sq_concat)(v, w); + assert(_Py_CheckSlotResult(v, "+", result != NULL)); + return result; + } + + return binop_type_error(v, w, "+"); } static PyObject * @@ -1033,20 +1090,23 @@ sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) Py_ssize_t count; if (_PyIndex_Check(n)) { count = PyNumber_AsSsize_t(n, PyExc_OverflowError); - if (count == -1 && PyErr_Occurred()) + if (count == -1 && PyErr_Occurred()) { return NULL; + } } else { return type_error("can't multiply sequence by " "non-int of type '%.200s'", n); } - return (*repeatfunc)(seq, count); + PyObject *res = (*repeatfunc)(seq, count); + assert(_Py_CheckSlotResult(seq, "*", res != NULL)); + return res; } PyObject * PyNumber_Multiply(PyObject *v, PyObject *w) { - PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply)); + PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_multiply), "*"); if (result == Py_NotImplemented) { PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; @@ -1109,27 +1169,42 @@ PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) */ static PyObject * -binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot) +binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot +#ifndef NDEBUG + , const char *op_name +#endif + ) { PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; if (mv != NULL) { binaryfunc slot = NB_BINOP(mv, iop_slot); if (slot) { PyObject *x = (slot)(v, w); + assert(_Py_CheckSlotResult(v, op_name, x != NULL)); if (x != Py_NotImplemented) { return x; } Py_DECREF(x); } } +#ifdef NDEBUG return binary_op1(v, w, op_slot); +#else + return binary_op1(v, w, op_slot, op_name); +#endif } +#ifdef NDEBUG +# define BINARY_IOP1(v, w, iop_slot, op_slot, op_name) binary_iop1(v, w, iop_slot, op_slot) +#else +# define BINARY_IOP1(v, w, iop_slot, op_slot, op_name) binary_iop1(v, w, iop_slot, op_slot, op_name) +#endif + static PyObject * binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot, const char *op_name) { - PyObject *result = binary_iop1(v, w, iop_slot, op_slot); + PyObject *result = BINARY_IOP1(v, w, iop_slot, op_slot, op_name); if (result == Py_NotImplemented) { Py_DECREF(result); return binop_type_error(v, w, op_name); @@ -1137,6 +1212,24 @@ binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot, return result; } +static PyObject * +ternary_iop(PyObject *v, PyObject *w, PyObject *z, const int iop_slot, const int op_slot, + const char *op_name) +{ + PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; + if (mv != NULL) { + ternaryfunc slot = NB_TERNOP(mv, iop_slot); + if (slot) { + PyObject *x = (slot)(v, w, z); + if (x != Py_NotImplemented) { + return x; + } + Py_DECREF(x); + } + } + return ternary_op(v, w, z, op_slot, op_name); +} + #define INPLACE_BINOP(func, iop, op, op_name) \ PyObject * \ func(PyObject *v, PyObject *w) { \ @@ -1168,18 +1261,20 @@ PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w) PyObject * PyNumber_InPlaceAdd(PyObject *v, PyObject *w) { - PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), - NB_SLOT(nb_add)); + PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_add), + NB_SLOT(nb_add), "+="); if (result == Py_NotImplemented) { PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; Py_DECREF(result); if (m != NULL) { - binaryfunc f = NULL; - f = m->sq_inplace_concat; - if (f == NULL) - f = m->sq_concat; - if (f != NULL) - return (*f)(v, w); + binaryfunc func = m->sq_inplace_concat; + if (func == NULL) + func = m->sq_concat; + if (func != NULL) { + result = func(v, w); + assert(_Py_CheckSlotResult(v, "+=", result != NULL)); + return result; + } } result = binop_type_error(v, w, "+="); } @@ -1189,8 +1284,8 @@ PyNumber_InPlaceAdd(PyObject *v, PyObject *w) PyObject * PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) { - PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply), - NB_SLOT(nb_multiply)); + PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_multiply), + NB_SLOT(nb_multiply), "*="); if (result == Py_NotImplemented) { ssizeargfunc f = NULL; PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; @@ -1232,13 +1327,8 @@ PyNumber_InPlaceRemainder(PyObject *v, PyObject *w) PyObject * PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) { - if (Py_TYPE(v)->tp_as_number && - Py_TYPE(v)->tp_as_number->nb_inplace_power != NULL) { - return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**="); - } - else { - return ternary_op(v, w, z, NB_SLOT(nb_power), "**="); - } + return ternary_iop(v, w, z, NB_SLOT(nb_inplace_power), + NB_SLOT(nb_power), "**="); } @@ -1247,15 +1337,16 @@ PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) PyObject * PyNumber_Negative(PyObject *o) { - PyNumberMethods *m; - if (o == NULL) { return null_error(); } - m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_negative) - return (*m->nb_negative)(o); + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; + if (m && m->nb_negative) { + PyObject *res = (*m->nb_negative)(o); + assert(_Py_CheckSlotResult(o, "__neg__", res != NULL)); + return res; + } return type_error("bad operand type for unary -: '%.200s'", o); } @@ -1263,15 +1354,16 @@ PyNumber_Negative(PyObject *o) PyObject * PyNumber_Positive(PyObject *o) { - PyNumberMethods *m; - if (o == NULL) { return null_error(); } - m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_positive) - return (*m->nb_positive)(o); + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; + if (m && m->nb_positive) { + PyObject *res = (*m->nb_positive)(o); + assert(_Py_CheckSlotResult(o, "__pos__", res != NULL)); + return res; + } return type_error("bad operand type for unary +: '%.200s'", o); } @@ -1279,15 +1371,16 @@ PyNumber_Positive(PyObject *o) PyObject * PyNumber_Invert(PyObject *o) { - PyNumberMethods *m; - if (o == NULL) { return null_error(); } - m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_invert) - return (*m->nb_invert)(o); + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; + if (m && m->nb_invert) { + PyObject *res = (*m->nb_invert)(o); + assert(_Py_CheckSlotResult(o, "__invert__", res != NULL)); + return res; + } return type_error("bad operand type for unary ~: '%.200s'", o); } @@ -1295,15 +1388,16 @@ PyNumber_Invert(PyObject *o) PyObject * PyNumber_Absolute(PyObject *o) { - PyNumberMethods *m; - if (o == NULL) { return null_error(); } - m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_absolute) - return m->nb_absolute(o); + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; + if (m && m->nb_absolute) { + PyObject *res = m->nb_absolute(o); + assert(_Py_CheckSlotResult(o, "__abs__", res != NULL)); + return res; + } return type_error("bad operand type for abs(): '%.200s'", o); } @@ -1317,13 +1411,13 @@ PyIndex_Check(PyObject *obj) /* Return a Python int from the object item. + Can return an instance of int subclass. Raise TypeError if the result is not an int or if the object cannot be interpreted as an index. */ PyObject * -PyNumber_Index(PyObject *item) +_PyNumber_Index(PyObject *item) { - PyObject *result = NULL; if (item == NULL) { return null_error(); } @@ -1338,9 +1432,13 @@ PyNumber_Index(PyObject *item) "as an integer", Py_TYPE(item)->tp_name); return NULL; } - result = Py_TYPE(item)->tp_as_number->nb_index(item); - if (!result || PyLong_CheckExact(result)) + + PyObject *result = Py_TYPE(item)->tp_as_number->nb_index(item); + assert(_Py_CheckSlotResult(item, "__index__", result != NULL)); + if (!result || PyLong_CheckExact(result)) { return result; + } + if (!PyLong_Check(result)) { PyErr_Format(PyExc_TypeError, "__index__ returned non-int (type %.200s)", @@ -1360,6 +1458,20 @@ PyNumber_Index(PyObject *item) return result; } +/* Return an exact Python int from the object item. + Raise TypeError if the result is not an int + or if the object cannot be interpreted as an index. +*/ +PyObject * +PyNumber_Index(PyObject *item) +{ + PyObject *result = _PyNumber_Index(item); + if (result != NULL && !PyLong_CheckExact(result)) { + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + } + return result; +} + /* Return an error on Overflow only if err is not NULL*/ Py_ssize_t @@ -1367,23 +1479,29 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) { Py_ssize_t result; PyObject *runerr; - PyObject *value = PyNumber_Index(item); + PyObject *value = _PyNumber_Index(item); if (value == NULL) return -1; /* We're done if PyLong_AsSsize_t() returns without error. */ result = PyLong_AsSsize_t(value); - if (result != -1 || !(runerr = PyErr_Occurred())) + if (result != -1) goto finish; + PyThreadState *tstate = _PyThreadState_GET(); + runerr = _PyErr_Occurred(tstate); + if (!runerr) { + goto finish; + } + /* Error handling code -- only manage OverflowError differently */ - if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) + if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { goto finish; + } + _PyErr_Clear(tstate); - PyErr_Clear(); /* If no error-handling desired then the default clipping - is sufficient. - */ + is sufficient. */ if (!err) { assert(PyLong_Check(value)); /* Whether or not it is less than or equal to @@ -1396,9 +1514,9 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) } else { /* Otherwise replace the error with caller's error object. */ - PyErr_Format(err, - "cannot fit '%.200s' into an index-sized integer", - Py_TYPE(item)->tp_name); + _PyErr_Format(tstate, err, + "cannot fit '%.200s' into an index-sized integer", + Py_TYPE(item)->tp_name); } finish: @@ -1426,18 +1544,35 @@ PyNumber_Long(PyObject *o) } m = Py_TYPE(o)->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ - result = _PyLong_FromNbInt(o); - if (result != NULL && !PyLong_CheckExact(result)) { - Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + /* Convert using the nb_int slot, which should return something + of exact type int. */ + result = m->nb_int(o); + assert(_Py_CheckSlotResult(o, "__int__", result != NULL)); + if (!result || PyLong_CheckExact(result)) { + return result; } + + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type %.200s)", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); return result; } if (m && m->nb_index) { - result = _PyLong_FromNbIndexOrNbInt(o); - if (result != NULL && !PyLong_CheckExact(result)) { - Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); - } - return result; + return PyNumber_Index(o); } trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__); if (trunc_func) { @@ -1452,8 +1587,7 @@ PyNumber_Long(PyObject *o) } /* __trunc__ is specified to return an Integral type, but int() needs to return an int. */ - m = Py_TYPE(result)->tp_as_number; - if (m == NULL || (m->nb_index == NULL && m->nb_int == NULL)) { + if (!PyIndex_Check(result)) { PyErr_Format( PyExc_TypeError, "__trunc__ returned non-Integral (type %.200s)", @@ -1461,17 +1595,14 @@ PyNumber_Long(PyObject *o) Py_DECREF(result); return NULL; } - Py_SETREF(result, _PyLong_FromNbIndexOrNbInt(result)); - if (result != NULL && !PyLong_CheckExact(result)) { - Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); - } + Py_SETREF(result, PyNumber_Index(result)); return result; } if (PyErr_Occurred()) return NULL; if (PyUnicode_Check(o)) - /* The below check is done in PyLong_FromUnicode(). */ + /* The below check is done in PyLong_FromUnicodeObject(). */ return PyLong_FromUnicodeObject(o, 10); if (PyBytes_Check(o)) @@ -1503,29 +1634,28 @@ PyNumber_Long(PyObject *o) } return type_error("int() argument must be a string, a bytes-like object " - "or a number, not '%.200s'", o); + "or a real number, not '%.200s'", o); } PyObject * PyNumber_Float(PyObject *o) { - PyNumberMethods *m; - if (o == NULL) { return null_error(); } if (PyFloat_CheckExact(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } - m = Py_TYPE(o)->tp_as_number; + + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; if (m && m->nb_float) { /* This should include subclasses of float */ PyObject *res = m->nb_float(o); - double val; + assert(_Py_CheckSlotResult(o, "__float__", res != NULL)); if (!res || PyFloat_CheckExact(res)) { return res; } + if (!PyFloat_Check(res)) { PyErr_Format(PyExc_TypeError, "%.50s.__float__ returned non-float (type %.50s)", @@ -1542,12 +1672,13 @@ PyNumber_Float(PyObject *o) Py_DECREF(res); return NULL; } - val = PyFloat_AS_DOUBLE(res); + double val = PyFloat_AS_DOUBLE(res); Py_DECREF(res); return PyFloat_FromDouble(val); } + if (m && m->nb_index) { - PyObject *res = PyNumber_Index(o); + PyObject *res = _PyNumber_Index(o); if (!res) { return NULL; } @@ -1558,7 +1689,9 @@ PyNumber_Float(PyObject *o) } return PyFloat_FromDouble(val); } - if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */ + + /* A float subclass with nb_float == NULL */ + if (PyFloat_Check(o)) { return PyFloat_FromDouble(PyFloat_AS_DOUBLE(o)); } return PyFloat_FromString(o); @@ -1573,7 +1706,7 @@ PyNumber_ToBase(PyObject *n, int base) "PyNumber_ToBase: base must be 2, 8, 10 or 16"); return NULL; } - PyObject *index = PyNumber_Index(n); + PyObject *index = _PyNumber_Index(n); if (!index) return NULL; PyObject *res = _PyLong_Format(index, base); @@ -1596,17 +1729,15 @@ PySequence_Check(PyObject *s) Py_ssize_t PySequence_Size(PyObject *s) { - PySequenceMethods *m; - if (s == NULL) { null_error(); return -1; } - m = Py_TYPE(s)->tp_as_sequence; + PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_length) { Py_ssize_t len = m->sq_length(s); - assert(len >= 0 || PyErr_Occurred()); + assert(_Py_CheckSlotResult(s, "__len__", len >= 0)); return len; } @@ -1629,21 +1760,22 @@ PySequence_Length(PyObject *s) PyObject * PySequence_Concat(PyObject *s, PyObject *o) { - PySequenceMethods *m; - if (s == NULL || o == NULL) { return null_error(); } - m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_concat) - return m->sq_concat(s, o); + PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; + if (m && m->sq_concat) { + PyObject *res = m->sq_concat(s, o); + assert(_Py_CheckSlotResult(s, "+", res != NULL)); + return res; + } /* Instances of user classes defining an __add__() method only have an nb_add slot, not an sq_concat slot. So we fall back to nb_add if both arguments appear to be sequences. */ if (PySequence_Check(s) && PySequence_Check(o)) { - PyObject *result = binary_op1(s, o, NB_SLOT(nb_add)); + PyObject *result = BINARY_OP1(s, o, NB_SLOT(nb_add), "+"); if (result != Py_NotImplemented) return result; Py_DECREF(result); @@ -1654,15 +1786,16 @@ PySequence_Concat(PyObject *s, PyObject *o) PyObject * PySequence_Repeat(PyObject *o, Py_ssize_t count) { - PySequenceMethods *m; - if (o == NULL) { return null_error(); } - m = Py_TYPE(o)->tp_as_sequence; - if (m && m->sq_repeat) - return m->sq_repeat(o, count); + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (m && m->sq_repeat) { + PyObject *res = m->sq_repeat(o, count); + assert(_Py_CheckSlotResult(o, "*", res != NULL)); + return res; + } /* Instances of user classes defining a __mul__() method only have an nb_multiply slot, not an sq_repeat slot. so we fall back @@ -1672,7 +1805,7 @@ PySequence_Repeat(PyObject *o, Py_ssize_t count) n = PyLong_FromSsize_t(count); if (n == NULL) return NULL; - result = binary_op1(o, n, NB_SLOT(nb_multiply)); + result = BINARY_OP1(o, n, NB_SLOT(nb_multiply), "*"); Py_DECREF(n); if (result != Py_NotImplemented) return result; @@ -1684,21 +1817,25 @@ PySequence_Repeat(PyObject *o, Py_ssize_t count) PyObject * PySequence_InPlaceConcat(PyObject *s, PyObject *o) { - PySequenceMethods *m; - if (s == NULL || o == NULL) { return null_error(); } - m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_inplace_concat) - return m->sq_inplace_concat(s, o); - if (m && m->sq_concat) - return m->sq_concat(s, o); + PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; + if (m && m->sq_inplace_concat) { + PyObject *res = m->sq_inplace_concat(s, o); + assert(_Py_CheckSlotResult(s, "+=", res != NULL)); + return res; + } + if (m && m->sq_concat) { + PyObject *res = m->sq_concat(s, o); + assert(_Py_CheckSlotResult(s, "+", res != NULL)); + return res; + } if (PySequence_Check(s) && PySequence_Check(o)) { - PyObject *result = binary_iop1(s, o, NB_SLOT(nb_inplace_add), - NB_SLOT(nb_add)); + PyObject *result = BINARY_IOP1(s, o, NB_SLOT(nb_inplace_add), + NB_SLOT(nb_add), "+="); if (result != Py_NotImplemented) return result; Py_DECREF(result); @@ -1709,25 +1846,29 @@ PySequence_InPlaceConcat(PyObject *s, PyObject *o) PyObject * PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) { - PySequenceMethods *m; - if (o == NULL) { return null_error(); } - m = Py_TYPE(o)->tp_as_sequence; - if (m && m->sq_inplace_repeat) - return m->sq_inplace_repeat(o, count); - if (m && m->sq_repeat) - return m->sq_repeat(o, count); + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (m && m->sq_inplace_repeat) { + PyObject *res = m->sq_inplace_repeat(o, count); + assert(_Py_CheckSlotResult(o, "*=", res != NULL)); + return res; + } + if (m && m->sq_repeat) { + PyObject *res = m->sq_repeat(o, count); + assert(_Py_CheckSlotResult(o, "*", res != NULL)); + return res; + } if (PySequence_Check(o)) { PyObject *n, *result; n = PyLong_FromSsize_t(count); if (n == NULL) return NULL; - result = binary_iop1(o, n, NB_SLOT(nb_inplace_multiply), - NB_SLOT(nb_multiply)); + result = BINARY_IOP1(o, n, NB_SLOT(nb_inplace_multiply), + NB_SLOT(nb_multiply), "*="); Py_DECREF(n); if (result != Py_NotImplemented) return result; @@ -1739,25 +1880,25 @@ PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) PyObject * PySequence_GetItem(PyObject *s, Py_ssize_t i) { - PySequenceMethods *m; - if (s == NULL) { return null_error(); } - m = Py_TYPE(s)->tp_as_sequence; + PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_item) { if (i < 0) { if (m->sq_length) { Py_ssize_t l = (*m->sq_length)(s); + assert(_Py_CheckSlotResult(s, "__len__", l >= 0)); if (l < 0) { - assert(PyErr_Occurred()); return NULL; } i += l; } } - return m->sq_item(s, i); + PyObject *res = m->sq_item(s, i); + assert(_Py_CheckSlotResult(s, "__getitem__", res != NULL)); + return res; } if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_subscript) { @@ -1769,19 +1910,18 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i) PyObject * PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) { - PyMappingMethods *mp; - if (!s) { return null_error(); } - mp = Py_TYPE(s)->tp_as_mapping; + PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; if (mp && mp->mp_subscript) { - PyObject *res; PyObject *slice = _PySlice_FromIndices(i1, i2); - if (!slice) + if (!slice) { return NULL; - res = mp->mp_subscript(s, slice); + } + PyObject *res = mp->mp_subscript(s, slice); + assert(_Py_CheckSlotResult(s, "__getitem__", res != NULL)); Py_DECREF(slice); return res; } @@ -1792,26 +1932,26 @@ PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) int PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) { - PySequenceMethods *m; - if (s == NULL) { null_error(); return -1; } - m = Py_TYPE(s)->tp_as_sequence; + PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_ass_item) { if (i < 0) { if (m->sq_length) { Py_ssize_t l = (*m->sq_length)(s); + assert(_Py_CheckSlotResult(s, "__len__", l >= 0)); if (l < 0) { - assert(PyErr_Occurred()); return -1; } i += l; } } - return m->sq_ass_item(s, i, o); + int res = m->sq_ass_item(s, i, o); + assert(_Py_CheckSlotResult(s, "__setitem__", res >= 0)); + return res; } if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { @@ -1825,26 +1965,26 @@ PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) int PySequence_DelItem(PyObject *s, Py_ssize_t i) { - PySequenceMethods *m; - if (s == NULL) { null_error(); return -1; } - m = Py_TYPE(s)->tp_as_sequence; + PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_ass_item) { if (i < 0) { if (m->sq_length) { Py_ssize_t l = (*m->sq_length)(s); + assert(_Py_CheckSlotResult(s, "__len__", l >= 0)); if (l < 0) { - assert(PyErr_Occurred()); return -1; } i += l; } } - return m->sq_ass_item(s, i, (PyObject *)NULL); + int res = m->sq_ass_item(s, i, (PyObject *)NULL); + assert(_Py_CheckSlotResult(s, "__delitem__", res >= 0)); + return res; } if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { @@ -1858,20 +1998,18 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i) int PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) { - PyMappingMethods *mp; - if (s == NULL) { null_error(); return -1; } - mp = Py_TYPE(s)->tp_as_mapping; + PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; if (mp && mp->mp_ass_subscript) { - int res; PyObject *slice = _PySlice_FromIndices(i1, i2); if (!slice) return -1; - res = mp->mp_ass_subscript(s, slice, o); + int res = mp->mp_ass_subscript(s, slice, o); + assert(_Py_CheckSlotResult(s, "__setitem__", res >= 0)); Py_DECREF(slice); return res; } @@ -1883,20 +2021,19 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) int PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) { - PyMappingMethods *mp; - if (s == NULL) { null_error(); return -1; } - mp = Py_TYPE(s)->tp_as_mapping; + PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; if (mp && mp->mp_ass_subscript) { - int res; PyObject *slice = _PySlice_FromIndices(i1, i2); - if (!slice) + if (!slice) { return -1; - res = mp->mp_ass_subscript(s, slice, NULL); + } + int res = mp->mp_ass_subscript(s, slice, NULL); + assert(_Py_CheckSlotResult(s, "__delitem__", res >= 0)); Py_DECREF(slice); return res; } @@ -2027,8 +2164,10 @@ PySequence_Fast(PyObject *v, const char *m) it = PyObject_GetIter(v); if (it == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_SetString(PyExc_TypeError, m); + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { + _PyErr_SetString(tstate, PyExc_TypeError, m); + } return NULL; } @@ -2141,11 +2280,13 @@ PySequence_Count(PyObject *s, PyObject *o) int PySequence_Contains(PyObject *seq, PyObject *ob) { - Py_ssize_t result; PySequenceMethods *sqm = Py_TYPE(seq)->tp_as_sequence; - if (sqm != NULL && sqm->sq_contains != NULL) - return (*sqm->sq_contains)(seq, ob); - result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); + if (sqm != NULL && sqm->sq_contains != NULL) { + int res = (*sqm->sq_contains)(seq, ob); + assert(_Py_CheckSlotResult(seq, "__contains__", res >= 0)); + return res; + } + Py_ssize_t result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); } @@ -2175,17 +2316,15 @@ PyMapping_Check(PyObject *o) Py_ssize_t PyMapping_Size(PyObject *o) { - PyMappingMethods *m; - if (o == NULL) { null_error(); return -1; } - m = Py_TYPE(o)->tp_as_mapping; + PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; if (m && m->mp_length) { Py_ssize_t len = m->mp_length(o); - assert(len >= 0 || PyErr_Occurred()); + assert(_Py_CheckSlotResult(o, "__len__", len >= 0)); return len; } @@ -2285,12 +2424,13 @@ method_output_as_list(PyObject *o, _Py_Identifier *meth_id) } it = PyObject_GetIter(meth_output); if (it == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%U() returned a non-iterable (type %.200s)", - Py_TYPE(o)->tp_name, - _PyUnicode_FromId(meth_id), - Py_TYPE(meth_output)->tp_name); + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s.%U() returned a non-iterable (type %.200s)", + Py_TYPE(o)->tp_name, + _PyUnicode_FromId(meth_id), + Py_TYPE(meth_output)->tp_name); } Py_DECREF(meth_output); return NULL; @@ -2441,8 +2581,10 @@ check_class(PyObject *cls, const char *error) PyObject *bases = abstract_get_bases(cls); if (bases == NULL) { /* Do not mask errors. */ - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, error); + PyThreadState *tstate = _PyThreadState_GET(); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_TypeError, error); + } return 0; } Py_DECREF(bases); @@ -2455,7 +2597,6 @@ object_isinstance(PyObject *inst, PyObject *cls) PyObject *icls; int retval; _Py_IDENTIFIER(__class__); - if (PyType_Check(cls)) { retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); if (retval == 0) { @@ -2475,7 +2616,7 @@ object_isinstance(PyObject *inst, PyObject *cls) } else { if (!check_class(cls, - "isinstance() arg 2 must be a type or tuple of types")) + "isinstance() arg 2 must be a type, a tuple of types, or a union")) return -1; retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls); if (icls != NULL) { @@ -2568,10 +2709,12 @@ recursive_issubclass(PyObject *derived, PyObject *cls) if (!check_class(derived, "issubclass() arg 1 must be a class")) return -1; - if (!check_class(cls, - "issubclass() arg 2 must be a class" - " or tuple of classes")) + + if (!_PyUnion_Check(cls) && !check_class(cls, + "issubclass() arg 2 must be a class," + " a tuple of classes, or a union")) { return -1; + } return abstract_issubclass(derived, cls); } @@ -2680,12 +2823,41 @@ PyObject_GetIter(PyObject *o) } } -#undef PyIter_Check +PyObject * +PyObject_GetAIter(PyObject *o) { + PyTypeObject *t = Py_TYPE(o); + unaryfunc f; + + if (t->tp_as_async == NULL || t->tp_as_async->am_aiter == NULL) { + return type_error("'%.200s' object is not an async iterable", o); + } + f = t->tp_as_async->am_aiter; + PyObject *it = (*f)(o); + if (it != NULL && !PyAIter_Check(it)) { + PyErr_Format(PyExc_TypeError, + "aiter() returned not an async iterator of type '%.100s'", + Py_TYPE(it)->tp_name); + Py_DECREF(it); + it = NULL; + } + return it; +} + +int +PyIter_Check(PyObject *obj) +{ + PyTypeObject *tp = Py_TYPE(obj); + return (tp->tp_iternext != NULL && + tp->tp_iternext != &_PyObject_NextNotImplemented); +} -int PyIter_Check(PyObject *obj) +int +PyAIter_Check(PyObject *obj) { - return Py_TYPE(obj)->tp_iternext != NULL && - Py_TYPE(obj)->tp_iternext != &_PyObject_NextNotImplemented; + PyTypeObject *tp = Py_TYPE(obj); + return (tp->tp_as_async != NULL && + tp->tp_as_async->am_anext != NULL && + tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented); } /* Return next item. @@ -2700,13 +2872,42 @@ PyIter_Next(PyObject *iter) { PyObject *result; result = (*Py_TYPE(iter)->tp_iternext)(iter); - if (result == NULL && - PyErr_Occurred() && - PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); + if (result == NULL) { + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyErr_Occurred(tstate) + && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) + { + _PyErr_Clear(tstate); + } + } return result; } +PySendResult +PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) +{ + _Py_IDENTIFIER(send); + assert(arg != NULL); + assert(result != NULL); + if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) { + PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result); + assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR)); + return res; + } + if (arg == Py_None && PyIter_Check(iter)) { + *result = Py_TYPE(iter)->tp_iternext(iter); + } + else { + *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); + } + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + return PYGEN_ERROR; +} /* * Flatten a sequence of bytes() objects into a C array of diff --git a/contrib/tools/python3/src/Objects/boolobject.c b/contrib/tools/python3/src/Objects/boolobject.c index 720835b98aa..b786966533e 100644 --- a/contrib/tools/python3/src/Objects/boolobject.c +++ b/contrib/tools/python3/src/Objects/boolobject.c @@ -55,6 +55,30 @@ bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return PyBool_FromLong(ok); } +static PyObject * +bool_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + long ok = 0; + if (!_PyArg_NoKwnames("bool", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("bool", nargs, 0, 1)) { + return NULL; + } + + assert(PyType_Check(type)); + if (nargs) { + ok = PyObject_IsTrue(args[0]); + if (ok < 0) { + return NULL; + } + } + return PyBool_FromLong(ok); +} + /* Arithmetic operations redefined to return bool if both args are bool. */ static PyObject * @@ -170,6 +194,7 @@ PyTypeObject PyBool_Type = { 0, /* tp_init */ 0, /* tp_alloc */ bool_new, /* tp_new */ + .tp_vectorcall = bool_vectorcall, }; /* The objects representing bool values False and True */ diff --git a/contrib/tools/python3/src/Objects/bytearrayobject.c b/contrib/tools/python3/src/Objects/bytearrayobject.c index a1aa88086e8..1ab9621b1f2 100644 --- a/contrib/tools/python3/src/Objects/bytearrayobject.c +++ b/contrib/tools/python3/src/Objects/bytearrayobject.c @@ -13,31 +13,23 @@ class bytearray "PyByteArrayObject *" "&PyByteArray_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/ +/* For PyByteArray_AS_STRING(). */ char _PyByteArray_empty_string[] = ""; -/* end nullbytes support */ - /* Helpers */ static int _getbytevalue(PyObject* arg, int *value) { - long face_value; + int overflow; + long face_value = PyLong_AsLongAndOverflow(arg, &overflow); - if (PyLong_Check(arg)) { - face_value = PyLong_AsLong(arg); - } else { - PyObject *index = PyNumber_Index(arg); - if (index == NULL) { - *value = -1; - return 0; - } - face_value = PyLong_AsLong(index); - Py_DECREF(index); + if (face_value == -1 && PyErr_Occurred()) { + *value = -1; + return 0; } - if (face_value < 0 || face_value >= 256) { - /* this includes the OverflowError in case the long is too large */ + /* this includes an overflow in converting to C long */ PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); *value = -1; return 0; @@ -273,7 +265,7 @@ PyByteArray_Concat(PyObject *a, PyObject *b) result = (PyByteArrayObject *) \ PyByteArray_FromStringAndSize(NULL, va.len + vb.len); - // result->ob_bytes is NULL if result is an empty string: + // result->ob_bytes is NULL if result is an empty bytearray: // if va.len + vb.len equals zero. if (result != NULL && result->ob_bytes != NULL) { memcpy(result->ob_bytes, va.buf, va.len); @@ -747,13 +739,20 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu } } +/*[clinic input] +bytearray.__init__ + + source as arg: object = NULL + encoding: str = NULL + errors: str = NULL + +[clinic start generated code]*/ + static int -bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, + const char *encoding, const char *errors) +/*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/ { - static char *kwlist[] = {"source", "encoding", "errors", 0}; - PyObject *arg = NULL; - const char *encoding = NULL; - const char *errors = NULL; Py_ssize_t count; PyObject *it; PyObject *(*iternext)(PyObject *); @@ -764,11 +763,6 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) return -1; } - /* Parse arguments */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist, - &arg, &encoding, &errors)) - return -1; - /* Make a quick exit if no first argument */ if (arg == NULL) { if (encoding != NULL || errors != NULL) { @@ -1012,26 +1006,20 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) { Py_ssize_t self_size, other_size; Py_buffer self_bytes, other_bytes; - int cmp, rc; - - /* Bytes can be compared to anything that supports the (binary) - buffer API. Except that a comparison with Unicode is always an - error, even if the comparison is for equality. */ - rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); - if (!rc) - rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type); - if (rc < 0) - return NULL; - if (rc) { - if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "Comparison between bytearray and string", 1)) - return NULL; + int cmp; + + if (!PyObject_CheckBuffer(self) || !PyObject_CheckBuffer(other)) { + if (PyUnicode_Check(self) || PyUnicode_Check(other)) { + if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytearray and string", 1)) + return NULL; + } } - Py_RETURN_NOTIMPLEMENTED; } + /* Bytearrays can be compared to anything that supports the buffer API. */ if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; @@ -1339,7 +1327,7 @@ bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, if (trans_table[c] != -1) *output++ = (char)trans_table[c]; } - /* Fix the size of the resulting string */ + /* Fix the size of the resulting bytearray */ if (inlen > 0) if (PyByteArray_Resize(result, output - output_start) < 0) { Py_CLEAR(result); @@ -1748,6 +1736,11 @@ bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) } Py_DECREF(it); + if (PyErr_Occurred()) { + Py_DECREF(bytearray_obj); + return NULL; + } + /* Resize down to exact size. */ if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) { Py_DECREF(bytearray_obj); @@ -1760,10 +1753,7 @@ bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) } Py_DECREF(bytearray_obj); - if (PyErr_Occurred()) { - return NULL; - } - + assert(!PyErr_Occurred()); Py_RETURN_NONE; } @@ -2094,7 +2084,7 @@ bytearray.hex How many bytes between separators. Positive values count from the right, negative values count from the left. -Create a str of hexadecimal numbers from a bytearray object. +Create a string of hexadecimal numbers from a bytearray object. Example: >>> value = bytearray([0xb9, 0x01, 0xef]) @@ -2110,7 +2100,7 @@ Example: static PyObject * bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep) -/*[clinic end generated code: output=29c4e5ef72c565a0 input=814c15830ac8c4b5]*/ +/*[clinic end generated code: output=29c4e5ef72c565a0 input=808667e49bcccb54]*/ { char* argbuf = PyByteArray_AS_STRING(self); Py_ssize_t arglen = PyByteArray_GET_SIZE(self); @@ -2347,7 +2337,8 @@ PyTypeObject PyByteArray_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &bytearray_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ bytearray_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -2363,13 +2354,13 @@ PyTypeObject PyByteArray_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)bytearray_init, /* tp_init */ + (initproc)bytearray___init__, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_Del, /* tp_free */ }; -/*********************** Bytes Iterator ****************************/ +/*********************** Bytearray Iterator ****************************/ typedef struct { PyObject_HEAD diff --git a/contrib/tools/python3/src/Objects/bytes_methods.c b/contrib/tools/python3/src/Objects/bytes_methods.c index 72daa1fdd55..994fb8a73c6 100644 --- a/contrib/tools/python3/src/Objects/bytes_methods.c +++ b/contrib/tools/python3/src/Objects/bytes_methods.c @@ -100,14 +100,14 @@ Return True if B is empty or all characters in B are ASCII,\n\ False otherwise."); // Optimization is copied from ascii_decode in unicodeobject.c -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif PyObject* @@ -115,20 +115,19 @@ _Py_bytes_isascii(const char *cptr, Py_ssize_t len) { const char *p = cptr; const char *end = p + len; - const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); while (p < end) { /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h for an explanation. */ - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(p, ALIGNOF_SIZE_T)) { /* Help allocation */ const char *_p = p; - while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + while (_p + SIZEOF_SIZE_T <= end) { + size_t value = *(const size_t *) _p; if (value & ASCII_CHAR_MASK) { Py_RETURN_FALSE; } - _p += SIZEOF_LONG; + _p += SIZEOF_SIZE_T; } p = _p; if (_p == end) diff --git a/contrib/tools/python3/src/Objects/bytesobject.c b/contrib/tools/python3/src/Objects/bytesobject.c index 25d9814dd6d..eaedb0b5689 100644 --- a/contrib/tools/python3/src/Objects/bytesobject.c +++ b/contrib/tools/python3/src/Objects/bytesobject.c @@ -4,8 +4,10 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_bytes_methods.h" -#include "pycore_object.h" +#include "pycore_bytes_methods.h" // _Py_bytes_startswith() +#include "pycore_format.h" // F_LJUST +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_object.h" // _PyObject_GC_TRACK #include "pycore_pymem.h" // PYMEM_CLEANBYTE #include "pystrhex.h" @@ -18,16 +20,13 @@ class bytes "PyBytesObject *" "&PyBytes_Type" #include "clinic/bytesobject.c.h" -static PyBytesObject *characters[UCHAR_MAX + 1]; -static PyBytesObject *nullstring; - _Py_IDENTIFIER(__bytes__); -/* PyBytesObject_SIZE gives the basic size of a string; any memory allocation - for a string of length n should request PyBytesObject_SIZE + n bytes. +/* PyBytesObject_SIZE gives the basic size of a bytes object; any memory allocation + for a bytes object of length n should request PyBytesObject_SIZE + n bytes. Using PyBytesObject_SIZE instead of sizeof(PyBytesObject) saves - 3 bytes per string allocation on a typical system. + 3 or 7 bytes per bytes object allocation on a typical system. */ #define PyBytesObject_SIZE (offsetof(PyBytesObject, ob_sval) + 1) @@ -35,6 +34,53 @@ _Py_IDENTIFIER(__bytes__); Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer, char *str); + +static struct _Py_bytes_state* +get_bytes_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->bytes; +} + + +// Return a borrowed reference to the empty bytes string singleton. +static inline PyObject* bytes_get_empty(void) +{ + struct _Py_bytes_state *state = get_bytes_state(); + // bytes_get_empty() must not be called before _PyBytes_Init() + // or after _PyBytes_Fini() + assert(state->empty_string != NULL); + return state->empty_string; +} + + +// Return a strong reference to the empty bytes string singleton. +static inline PyObject* bytes_new_empty(void) +{ + PyObject *empty = bytes_get_empty(); + Py_INCREF(empty); + return (PyObject *)empty; +} + + +static int +bytes_create_empty_string_singleton(struct _Py_bytes_state *state) +{ + // Create the empty bytes string singleton + PyBytesObject *op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE); + if (op == NULL) { + return -1; + } + _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, 0); + op->ob_shash = -1; + op->ob_sval[0] = '\0'; + + assert(state->empty_string == NULL); + state->empty_string = (PyObject *)op; + return 0; +} + + /* For PyBytes_FromString(), the parameter `str' points to a null-terminated string containing exactly `size' bytes. @@ -63,9 +109,8 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) PyBytesObject *op; assert(size >= 0); - if (size == 0 && (op = nullstring) != NULL) { - Py_INCREF(op); - return (PyObject *)op; + if (size == 0) { + return bytes_new_empty(); } if ((size_t)size > (size_t)PY_SSIZE_T_MAX - PyBytesObject_SIZE) { @@ -79,16 +124,13 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) op = (PyBytesObject *)PyObject_Calloc(1, PyBytesObject_SIZE + size); else op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); - if (op == NULL) + if (op == NULL) { return PyErr_NoMemory(); - (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + } + _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); op->ob_shash = -1; - if (!use_calloc) + if (!use_calloc) { op->ob_sval[size] = '\0'; - /* empty byte string singleton */ - if (size == 0) { - nullstring = op; - Py_INCREF(op); } return (PyObject *) op; } @@ -102,11 +144,16 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) "Negative size passed to PyBytes_FromStringAndSize"); return NULL; } - if (size == 1 && str != NULL && - (op = characters[*str & UCHAR_MAX]) != NULL) - { - Py_INCREF(op); - return (PyObject *)op; + if (size == 1 && str != NULL) { + struct _Py_bytes_state *state = get_bytes_state(); + op = state->characters[*str & UCHAR_MAX]; + if (op != NULL) { + Py_INCREF(op); + return (PyObject *)op; + } + } + if (size == 0) { + return bytes_new_empty(); } op = (PyBytesObject *)_PyBytes_FromSize(size, 0); @@ -118,8 +165,9 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) memcpy(op->ob_sval, str, size); /* share short strings */ if (size == 1) { - characters[*str & UCHAR_MAX] = op; + struct _Py_bytes_state *state = get_bytes_state(); Py_INCREF(op); + state->characters[*str & UCHAR_MAX] = op; } return (PyObject *) op; } @@ -137,29 +185,32 @@ PyBytes_FromString(const char *str) "byte string is too long"); return NULL; } - if (size == 0 && (op = nullstring) != NULL) { - Py_INCREF(op); - return (PyObject *)op; + + struct _Py_bytes_state *state = get_bytes_state(); + if (size == 0) { + return bytes_new_empty(); } - if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) { - Py_INCREF(op); - return (PyObject *)op; + else if (size == 1) { + op = state->characters[*str & UCHAR_MAX]; + if (op != NULL) { + Py_INCREF(op); + return (PyObject *)op; + } } /* Inline PyObject_NewVar */ - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); - if (op == NULL) + op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); + if (op == NULL) { return PyErr_NoMemory(); - (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + } + _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); op->ob_shash = -1; memcpy(op->ob_sval, str, size+1); /* share short strings */ - if (size == 0) { - nullstring = op; - Py_INCREF(op); - } else if (size == 1) { - characters[*str & UCHAR_MAX] = op; + if (size == 1) { + assert(state->characters[*str & UCHAR_MAX] == NULL); Py_INCREF(op); + state->characters[*str & UCHAR_MAX] = op; } return (PyObject *) op; } @@ -256,27 +307,29 @@ PyBytes_FromFormatV(const char *format, va_list vargs) } case 'd': - if (longflag) + if (longflag) { sprintf(buffer, "%ld", va_arg(vargs, long)); - else if (size_tflag) - sprintf(buffer, "%" PY_FORMAT_SIZE_T "d", - va_arg(vargs, Py_ssize_t)); - else + } + else if (size_tflag) { + sprintf(buffer, "%zd", va_arg(vargs, Py_ssize_t)); + } + else { sprintf(buffer, "%d", va_arg(vargs, int)); + } assert(strlen(buffer) < sizeof(buffer)); WRITE_BYTES(buffer); break; case 'u': - if (longflag) - sprintf(buffer, "%lu", - va_arg(vargs, unsigned long)); - else if (size_tflag) - sprintf(buffer, "%" PY_FORMAT_SIZE_T "u", - va_arg(vargs, size_t)); - else - sprintf(buffer, "%u", - va_arg(vargs, unsigned int)); + if (longflag) { + sprintf(buffer, "%lu", va_arg(vargs, unsigned long)); + } + else if (size_tflag) { + sprintf(buffer, "%zu", va_arg(vargs, size_t)); + } + else { + sprintf(buffer, "%u", va_arg(vargs, unsigned int)); + } assert(strlen(buffer) < sizeof(buffer)); WRITE_BYTES(buffer); break; @@ -387,19 +440,6 @@ getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx) return NULL; } -/* Format codes - * F_LJUST '-' - * F_SIGN '+' - * F_BLANK ' ' - * F_ALT '#' - * F_ZERO '0' - */ -#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) - /* Returns a new reference to a PyBytes object, or NULL on failure. */ static char* @@ -455,25 +495,22 @@ formatlong(PyObject *v, int flags, int prec, int type) if (PyNumber_Check(v)) { /* make sure number is a type of integer for o, x, and X */ if (type == 'o' || type == 'x' || type == 'X') - iobj = PyNumber_Index(v); + iobj = _PyNumber_Index(v); else iobj = PyNumber_Long(v); - if (iobj == NULL) { - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return NULL; - } - else if (!PyLong_Check(iobj)) - Py_CLEAR(iobj); if (iobj != NULL) { + assert(PyLong_Check(iobj)); result = _PyUnicode_FormatLong(iobj, flags & F_ALT, prec, type); Py_DECREF(iobj); return result; } + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return NULL; } PyErr_Format(PyExc_TypeError, "%%%c format: %s is required, not %.200s", type, (type == 'o' || type == 'x' || type == 'X') ? "an integer" - : "a number", + : "a real number", Py_TYPE(v)->tp_name); return NULL; } @@ -490,26 +527,16 @@ byte_converter(PyObject *arg, char *p) return 1; } else { - PyObject *iobj; - long ival; int overflow; - /* make sure number is a type of integer */ - if (PyLong_Check(arg)) { - ival = PyLong_AsLongAndOverflow(arg, &overflow); - } - else { - iobj = PyNumber_Index(arg); - if (iobj == NULL) { - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return 0; + long ival = PyLong_AsLongAndOverflow(arg, &overflow); + if (ival == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { goto onError; } - ival = PyLong_AsLongAndOverflow(iobj, &overflow); - Py_DECREF(iobj); + return 0; } - if (!overflow && ival == -1 && PyErr_Occurred()) - goto onError; - if (overflow || !(0 <= ival && ival <= 255)) { + if (!(0 <= ival && ival <= 255)) { + /* this includes an overflow in converting to C long */ PyErr_SetString(PyExc_OverflowError, "%c arg not in range(256)"); return 0; @@ -1245,6 +1272,8 @@ PyBytes_AsStringAndSize(PyObject *obj, /* -------------------------------------------------------------------- */ /* Methods */ +#define STRINGLIB_GET_EMPTY() bytes_get_empty() + #include "stringlib/stringdefs.h" #include "stringlib/fastsearch.h" @@ -1257,6 +1286,8 @@ PyBytes_AsStringAndSize(PyObject *obj, #include "stringlib/transmogrify.h" +#undef STRINGLIB_GET_EMPTY + PyObject * PyBytes_Repr(PyObject *obj, int smartquotes) { @@ -1432,10 +1463,11 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) "repeated bytes are too long"); return NULL; } - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes); - if (op == NULL) + op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + nbytes); + if (op == NULL) { return PyErr_NoMemory(); - (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + } + _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); op->ob_shash = -1; op->ob_sval[size] = '\0'; if (Py_SIZE(a) == 1 && n > 0) { @@ -1494,36 +1526,19 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) int c; Py_ssize_t len_a, len_b; Py_ssize_t min_len; - int rc; /* Make sure both arguments are strings. */ if (!(PyBytes_Check(a) && PyBytes_Check(b))) { if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { - rc = PyObject_IsInstance((PyObject*)a, - (PyObject*)&PyUnicode_Type); - if (!rc) - rc = PyObject_IsInstance((PyObject*)b, - (PyObject*)&PyUnicode_Type); - if (rc < 0) - return NULL; - if (rc) { + if (PyUnicode_Check(a) || PyUnicode_Check(b)) { if (PyErr_WarnEx(PyExc_BytesWarning, "Comparison between bytes and string", 1)) return NULL; } - else { - rc = PyObject_IsInstance((PyObject*)a, - (PyObject*)&PyLong_Type); - if (!rc) - rc = PyObject_IsInstance((PyObject*)b, - (PyObject*)&PyLong_Type); - if (rc < 0) + if (PyLong_Check(a) || PyLong_Check(b)) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytes and int", 1)) return NULL; - if (rc) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "Comparison between bytes and int", 1)) - return NULL; - } } } Py_RETURN_NOTIMPLEMENTED; @@ -1533,7 +1548,7 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) case Py_EQ: case Py_LE: case Py_GE: - /* a string is equal to itself */ + /* a byte string is equal to itself */ Py_RETURN_TRUE; case Py_NE: case Py_LT: @@ -2122,7 +2137,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, Py_INCREF(input_obj); return input_obj; } - /* Fix the size of the resulting string */ + /* Fix the size of the resulting byte string */ if (inlen > 0) _PyBytes_Resize(&result, output - output_start); return result; @@ -2426,7 +2441,7 @@ bytes.hex How many bytes between separators. Positive values count from the right, negative values count from the left. -Create a str of hexadecimal numbers from a bytes object. +Create a string of hexadecimal numbers from a bytes object. Example: >>> value = b'\xb9\x01\xef' @@ -2442,7 +2457,7 @@ Example: static PyObject * bytes_hex_impl(PyBytesObject *self, PyObject *sep, int bytes_per_sep) -/*[clinic end generated code: output=1f134da504064139 input=f1238d3455990218]*/ +/*[clinic end generated code: output=1f134da504064139 input=1a21282b1f1ae595]*/ { const char *argbuf = PyBytes_AS_STRING(self); Py_ssize_t arglen = PyBytes_GET_SIZE(self); @@ -2536,24 +2551,27 @@ static PyNumberMethods bytes_as_number = { }; static PyObject * -bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +bytes_subtype_new(PyTypeObject *, PyObject *); + +/*[clinic input] +@classmethod +bytes.__new__ as bytes_new + + source as x: object = NULL + encoding: str = NULL + errors: str = NULL + +[clinic start generated code]*/ static PyObject * -bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, + const char *errors) +/*[clinic end generated code: output=1e0c471be311a425 input=f0a966d19b7262b4]*/ { - PyObject *x = NULL; - const char *encoding = NULL; - const char *errors = NULL; - PyObject *new = NULL; + PyObject *bytes; PyObject *func; Py_ssize_t size; - static char *kwlist[] = {"source", "encoding", "errors", 0}; - if (type != &PyBytes_Type) - return bytes_subtype_new(type, args, kwds); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, - &encoding, &errors)) - return NULL; if (x == NULL) { if (encoding != NULL || errors != NULL) { PyErr_SetString(PyExc_TypeError, @@ -2562,78 +2580,73 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) "errors without a string argument"); return NULL; } - return PyBytes_FromStringAndSize(NULL, 0); + bytes = PyBytes_FromStringAndSize(NULL, 0); } - - if (encoding != NULL) { + else if (encoding != NULL) { /* Encode via the codec registry */ if (!PyUnicode_Check(x)) { PyErr_SetString(PyExc_TypeError, "encoding without a string argument"); return NULL; } - new = PyUnicode_AsEncodedString(x, encoding, errors); - if (new == NULL) - return NULL; - assert(PyBytes_Check(new)); - return new; + bytes = PyUnicode_AsEncodedString(x, encoding, errors); } - - if (errors != NULL) { + else if (errors != NULL) { PyErr_SetString(PyExc_TypeError, PyUnicode_Check(x) ? "string argument without an encoding" : "errors without a string argument"); return NULL; } - /* We'd like to call PyObject_Bytes here, but we need to check for an integer argument before deferring to PyBytes_FromObject, something PyObject_Bytes doesn't do. */ - func = _PyObject_LookupSpecial(x, &PyId___bytes__); - if (func != NULL) { - new = _PyObject_CallNoArg(func); + else if ((func = _PyObject_LookupSpecial(x, &PyId___bytes__)) != NULL) { + bytes = _PyObject_CallNoArg(func); Py_DECREF(func); - if (new == NULL) + if (bytes == NULL) return NULL; - if (!PyBytes_Check(new)) { + if (!PyBytes_Check(bytes)) { PyErr_Format(PyExc_TypeError, - "__bytes__ returned non-bytes (type %.200s)", - Py_TYPE(new)->tp_name); - Py_DECREF(new); + "__bytes__ returned non-bytes (type %.200s)", + Py_TYPE(bytes)->tp_name); + Py_DECREF(bytes); return NULL; } - return new; } else if (PyErr_Occurred()) return NULL; - - if (PyUnicode_Check(x)) { + else if (PyUnicode_Check(x)) { PyErr_SetString(PyExc_TypeError, "string argument without an encoding"); return NULL; } /* Is it an integer? */ - if (_PyIndex_Check(x)) { + else if (_PyIndex_Check(x)) { size = PyNumber_AsSsize_t(x, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) { if (!PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; PyErr_Clear(); /* fall through */ + bytes = PyBytes_FromObject(x); } else { if (size < 0) { PyErr_SetString(PyExc_ValueError, "negative count"); return NULL; } - new = _PyBytes_FromSize(size, 1); - if (new == NULL) - return NULL; - return new; + bytes = _PyBytes_FromSize(size, 1); } } + else { + bytes = PyBytes_FromObject(x); + } + + if (bytes != NULL && type != &PyBytes_Type) { + Py_SETREF(bytes, bytes_subtype_new(type, bytes)); + } - return PyBytes_FromObject(x); + return bytes; } static PyObject* @@ -2746,7 +2759,7 @@ _PyBytes_FromIterator(PyObject *it, PyObject *x) Py_ssize_t i, size; _PyBytesWriter writer; - /* For iterator version, create a string object and resize as needed */ + /* For iterator version, create a bytes object and resize as needed */ size = PyObject_LengthHint(x, 64); if (size == -1 && PyErr_Occurred()) return NULL; @@ -2845,15 +2858,12 @@ PyBytes_FromObject(PyObject *x) } static PyObject * -bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +bytes_subtype_new(PyTypeObject *type, PyObject *tmp) { - PyObject *tmp, *pnew; + PyObject *pnew; Py_ssize_t n; assert(PyType_IsSubtype(type, &PyBytes_Type)); - tmp = bytes_new(&PyBytes_Type, args, kwds); - if (tmp == NULL) - return NULL; assert(PyBytes_Check(tmp)); n = PyBytes_GET_SIZE(tmp); pnew = type->tp_alloc(type, n); @@ -2863,7 +2873,6 @@ bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ((PyBytesObject *)pnew)->ob_shash = ((PyBytesObject *)tmp)->ob_shash; } - Py_DECREF(tmp); return pnew; } @@ -2903,7 +2912,8 @@ PyTypeObject PyBytes_Type = { 0, /* tp_setattro */ &bytes_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_BYTES_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_BYTES_SUBCLASS | + _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ bytes_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -3021,9 +3031,9 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) goto error; } if (newsize == 0) { - *pv = _PyBytes_FromSize(0, 0); + *pv = bytes_new_empty(); Py_DECREF(v); - return (*pv == NULL) ? -1 : 0; + return 0; } /* XXX UNREF/NEWREF interface should be more symmetrical */ #ifdef Py_REF_DEBUG @@ -3033,9 +3043,9 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) _Py_ForgetReference(v); #endif *pv = (PyObject *) - PyObject_REALLOC(v, PyBytesObject_SIZE + newsize); + PyObject_Realloc(v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { - PyObject_Del(v); + PyObject_Free(v); PyErr_NoMemory(); return -1; } @@ -3052,13 +3062,26 @@ error: return -1; } + +PyStatus +_PyBytes_Init(PyInterpreterState *interp) +{ + struct _Py_bytes_state *state = &interp->bytes; + if (bytes_create_empty_string_singleton(state) < 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} + + void -_PyBytes_Fini(void) +_PyBytes_Fini(PyInterpreterState *interp) { - int i; - for (i = 0; i < UCHAR_MAX + 1; i++) - Py_CLEAR(characters[i]); - Py_CLEAR(nullstring); + struct _Py_bytes_state* state = &interp->bytes; + for (int i = 0; i < UCHAR_MAX + 1; i++) { + Py_CLEAR(state->characters[i]); + } + Py_CLEAR(state->empty_string); } /*********************** Bytes Iterator ****************************/ @@ -3088,7 +3111,6 @@ static PyObject * striter_next(striterobject *it) { PyBytesObject *seq; - PyObject *item; assert(it != NULL); seq = it->it_seq; @@ -3097,11 +3119,8 @@ striter_next(striterobject *it) assert(PyBytes_Check(seq)); if (it->it_index < PyBytes_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)seq->ob_sval[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; + return PyLong_FromLong( + (unsigned char)seq->ob_sval[it->it_index++]); } it->it_seq = NULL; diff --git a/contrib/tools/python3/src/Objects/call.c b/contrib/tools/python3/src/Objects/call.c index 87dc0dbbdb5..960c37e1961 100644 --- a/contrib/tools/python3/src/Objects/call.c +++ b/contrib/tools/python3/src/Objects/call.c @@ -1,11 +1,11 @@ #include "Python.h" -#include "pycore_call.h" -#include "pycore_ceval.h" // _PyEval_EvalFrame() -#include "pycore_object.h" -#include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tupleobject.h" -#include "frameobject.h" +#include "pycore_call.h" // _PyObject_CallNoArgTstate() +#include "pycore_ceval.h" // _PyEval_EvalFrame() +#include "pycore_object.h" // _PyObject_GC_TRACK() +#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 * @@ -39,16 +39,16 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, if (!_PyErr_Occurred(tstate)) { if (callable) _PyErr_Format(tstate, PyExc_SystemError, - "%R returned NULL without setting an error", + "%R returned NULL without setting an exception", callable); else _PyErr_Format(tstate, PyExc_SystemError, - "%s returned NULL without setting an error", + "%s returned NULL without setting an exception", where); #ifdef Py_DEBUG /* Ensure that the bug is caught in debug mode. Py_FatalError() logs the SystemError exception raised above. */ - Py_FatalError("a function returned NULL without setting an error"); + Py_FatalError("a function returned NULL without setting an exception"); #endif return NULL; } @@ -60,17 +60,17 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, if (callable) { _PyErr_FormatFromCauseTstate( tstate, PyExc_SystemError, - "%R returned a result with an error set", callable); + "%R returned a result with an exception set", callable); } else { _PyErr_FormatFromCauseTstate( tstate, PyExc_SystemError, - "%s returned a result with an error set", where); + "%s returned a result with an exception set", where); } #ifdef Py_DEBUG /* Ensure that the bug is caught in debug mode. Py_FatalError() logs the SystemError exception raised above. */ - Py_FatalError("a function returned a result with an error set"); + Py_FatalError("a function returned a result with an exception set"); #endif return NULL; } @@ -79,6 +79,30 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, } +int +_Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (!success) { + if (!_PyErr_Occurred(tstate)) { + _Py_FatalErrorFormat(__func__, + "Slot %s of type %s failed " + "without setting an exception", + slot_name, Py_TYPE(obj)->tp_name); + } + } + else { + if (_PyErr_Occurred(tstate)) { + _Py_FatalErrorFormat(__func__, + "Slot %s of type %s succeeded " + "with an exception set", + slot_name, Py_TYPE(obj)->tp_name); + } + } + return 1; +} + + /* --- Core PyObject call functions ------------------------------- */ /* Call a callable Python object without any arguments */ @@ -304,106 +328,24 @@ PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) /* --- PyFunction call functions ---------------------------------- */ -static PyObject* _Py_HOT_FUNCTION -function_code_fastcall(PyThreadState *tstate, PyCodeObject *co, - PyObject *const *args, Py_ssize_t nargs, - PyObject *globals) -{ - assert(tstate != NULL); - assert(globals != NULL); - - /* XXX Perhaps we should create a specialized - _PyFrame_New_NoTrack() that doesn't take locals, but does - take builtins without sanity checking them. - */ - PyFrameObject *f = _PyFrame_New_NoTrack(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - - PyObject **fastlocals = f->f_localsplus; - - for (Py_ssize_t i = 0; i < nargs; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - PyObject *result = _PyEval_EvalFrame(tstate, f, 0); - - if (Py_REFCNT(f) > 1) { - Py_DECREF(f); - _PyObject_GC_TRACK(f); - } - else { - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - } - return result; -} - - PyObject * _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, size_t nargsf, PyObject *kwnames) { assert(PyFunction_Check(func)); - assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); - + PyFrameConstructor *f = PyFunction_AS_FRAME_CONSTRUCTOR(func); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); assert(nargs >= 0); - Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); - assert((nargs == 0 && nkwargs == 0) || stack != NULL); - /* kwnames must only contain strings and all keys must be unique */ - PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - - if (co->co_kwonlyargcount == 0 && nkwargs == 0 && - (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) - { - if (argdefs == NULL && co->co_argcount == nargs) { - return function_code_fastcall(tstate, co, stack, nargs, globals); - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - stack = _PyTuple_ITEMS(argdefs); - return function_code_fastcall(tstate, co, - stack, PyTuple_GET_SIZE(argdefs), - globals); - } - } - - PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func); - PyObject *closure = PyFunction_GET_CLOSURE(func); - PyObject *name = ((PyFunctionObject *)func) -> func_name; - PyObject *qualname = ((PyFunctionObject *)func) -> func_qualname; - - PyObject **d; - Py_ssize_t nd; - if (argdefs != NULL) { - d = _PyTuple_ITEMS(argdefs); - nd = PyTuple_GET_SIZE(argdefs); - assert(nd <= INT_MAX); + assert(nargs == 0 || stack != NULL); + if (((PyCodeObject *)f->fc_code)->co_flags & CO_OPTIMIZED) { + return _PyEval_Vector(tstate, f, NULL, stack, nargs, kwnames); } else { - d = NULL; - nd = 0; - } - return _PyEval_EvalCode(tstate, - (PyObject*)co, globals, (PyObject *)NULL, - stack, nargs, - nkwargs ? _PyTuple_ITEMS(kwnames) : NULL, - stack + nargs, - nkwargs, 1, - d, (int)nd, kwdefs, - closure, name, qualname); + return _PyEval_Vector(tstate, f, f->fc_globals, stack, nargs, kwnames); + } } - /* --- More complex call functions -------------------------------- */ /* External interface to call any callable object. diff --git a/contrib/tools/python3/src/Objects/capsule.c b/contrib/tools/python3/src/Objects/capsule.c index ed24cc1d6a2..800a6c4b25c 100644 --- a/contrib/tools/python3/src/Objects/capsule.c +++ b/contrib/tools/python3/src/Objects/capsule.c @@ -198,7 +198,7 @@ PyCapsule_Import(const char *name, int no_block) void *return_value = NULL; char *trace; size_t name_length = (strlen(name) + 1) * sizeof(char); - char *name_dup = (char *)PyMem_MALLOC(name_length); + char *name_dup = (char *)PyMem_Malloc(name_length); if (!name_dup) { return PyErr_NoMemory(); @@ -247,7 +247,7 @@ PyCapsule_Import(const char *name, int no_block) EXIT: Py_XDECREF(object); if (name_dup) { - PyMem_FREE(name_dup); + PyMem_Free(name_dup); } return return_value; } @@ -260,7 +260,7 @@ capsule_dealloc(PyObject *o) if (capsule->destructor) { capsule->destructor(o); } - PyObject_DEL(o); + PyObject_Free(o); } diff --git a/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h b/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h index 35ba1ff3d57..1e3f1975615 100644 --- a/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h @@ -2,6 +2,75 @@ preserve [clinic start generated code]*/ +static int +bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, + const char *encoding, const char *errors); + +static int +bytearray___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "bytearray", 0}; + 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) - 0; + PyObject *arg = NULL; + const char *encoding = NULL; + const char *errors = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 3, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + arg = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[1]) { + if (!PyUnicode_Check(fastargs[1])) { + _PyArg_BadArgument("bytearray", "argument 'encoding'", "str", fastargs[1]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(fastargs[2])) { + _PyArg_BadArgument("bytearray", "argument 'errors'", "str", fastargs[2]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(fastargs[2], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_pos: + return_value = bytearray___init___impl((PyByteArrayObject *)self, arg, encoding, errors); + +exit: + return return_value; +} + PyDoc_STRVAR(bytearray_clear__doc__, "clear($self, /)\n" "--\n" @@ -268,14 +337,9 @@ bytearray_replace(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -346,14 +410,9 @@ bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -450,14 +509,9 @@ bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t narg goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -519,14 +573,9 @@ bytearray_insert(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t narg if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -617,14 +666,9 @@ bytearray_pop(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -896,11 +940,6 @@ bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } keepends = _PyLong_AsInt(args[0]); if (keepends == -1 && PyErr_Occurred()) { goto exit; @@ -951,7 +990,7 @@ PyDoc_STRVAR(bytearray_hex__doc__, "hex($self, /, sep=, bytes_per_sep=1)\n" "--\n" "\n" -"Create a str of hexadecimal numbers from a bytearray object.\n" +"Create a string of hexadecimal numbers from a bytearray object.\n" "\n" " sep\n" " An optional single character or byte to separate hex bytes.\n" @@ -1000,11 +1039,6 @@ bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } bytes_per_sep = _PyLong_AsInt(args[1]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; @@ -1058,11 +1092,6 @@ bytearray_reduce_ex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t n if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } proto = _PyLong_AsInt(args[0]); if (proto == -1 && PyErr_Occurred()) { goto exit; @@ -1091,4 +1120,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=b2919f76709e48dc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a82659f581e55629 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h b/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h index 063a3777b49..9e365ce1a08 100644 --- a/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h @@ -46,14 +46,9 @@ bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -202,14 +197,9 @@ bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -493,14 +483,9 @@ bytes_replace(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -715,11 +700,6 @@ bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } keepends = _PyLong_AsInt(args[0]); if (keepends == -1 && PyErr_Occurred()) { goto exit; @@ -770,7 +750,7 @@ PyDoc_STRVAR(bytes_hex__doc__, "hex($self, /, sep=, bytes_per_sep=1)\n" "--\n" "\n" -"Create a str of hexadecimal numbers from a bytes object.\n" +"Create a string of hexadecimal numbers from a bytes object.\n" "\n" " sep\n" " An optional single character or byte to separate hex bytes.\n" @@ -819,11 +799,6 @@ bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } bytes_per_sep = _PyLong_AsInt(args[1]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; @@ -834,4 +809,73 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=220388917d7bf751 input=a9049054013a1b77]*/ + +static PyObject * +bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, + const char *errors); + +static PyObject * +bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "bytes", 0}; + 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) - 0; + PyObject *x = NULL; + const char *encoding = NULL; + const char *errors = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 3, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + x = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[1]) { + if (!PyUnicode_Check(fastargs[1])) { + _PyArg_BadArgument("bytes", "argument 'encoding'", "str", fastargs[1]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(fastargs[2])) { + _PyArg_BadArgument("bytes", "argument 'errors'", "str", fastargs[2]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(fastargs[2], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_pos: + return_value = bytes_new_impl(type, x, encoding, errors); + +exit: + return return_value; +} +/*[clinic end generated code: output=b3f0ec2753246b9c input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/codeobject.c.h b/contrib/tools/python3/src/Objects/clinic/codeobject.c.h index 1dd82278cf3..bae2ab07644 100644 --- a/contrib/tools/python3/src/Objects/clinic/codeobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/codeobject.c.h @@ -2,13 +2,149 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(code_new__doc__, +"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" +" flags, codestring, constants, names, varnames, filename, name,\n" +" firstlineno, linetable, freevars=(), cellvars=(), /)\n" +"--\n" +"\n" +"Create a code object. Not for the faint of heart."); + +static PyObject * +code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, + int kwonlyargcount, int nlocals, int stacksize, int flags, + PyObject *code, PyObject *consts, PyObject *names, + PyObject *varnames, PyObject *filename, PyObject *name, + int firstlineno, PyObject *linetable, PyObject *freevars, + PyObject *cellvars); + +static PyObject * +code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + int argcount; + int posonlyargcount; + int kwonlyargcount; + int nlocals; + int stacksize; + int flags; + PyObject *code; + PyObject *consts; + PyObject *names; + PyObject *varnames; + PyObject *filename; + PyObject *name; + int firstlineno; + PyObject *linetable; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + + if ((type == &PyCode_Type) && + !_PyArg_NoKeywords("code", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("code", PyTuple_GET_SIZE(args), 14, 16)) { + goto exit; + } + argcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + if (argcount == -1 && PyErr_Occurred()) { + goto exit; + } + posonlyargcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 1)); + if (posonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + kwonlyargcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 2)); + if (kwonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + nlocals = _PyLong_AsInt(PyTuple_GET_ITEM(args, 3)); + if (nlocals == -1 && PyErr_Occurred()) { + goto exit; + } + stacksize = _PyLong_AsInt(PyTuple_GET_ITEM(args, 4)); + if (stacksize == -1 && PyErr_Occurred()) { + goto exit; + } + flags = _PyLong_AsInt(PyTuple_GET_ITEM(args, 5)); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyBytes_Check(PyTuple_GET_ITEM(args, 6))) { + _PyArg_BadArgument("code", "argument 7", "bytes", PyTuple_GET_ITEM(args, 6)); + goto exit; + } + code = PyTuple_GET_ITEM(args, 6); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 7))) { + _PyArg_BadArgument("code", "argument 8", "tuple", PyTuple_GET_ITEM(args, 7)); + goto exit; + } + consts = PyTuple_GET_ITEM(args, 7); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 8))) { + _PyArg_BadArgument("code", "argument 9", "tuple", PyTuple_GET_ITEM(args, 8)); + goto exit; + } + names = PyTuple_GET_ITEM(args, 8); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 9))) { + _PyArg_BadArgument("code", "argument 10", "tuple", PyTuple_GET_ITEM(args, 9)); + goto exit; + } + varnames = PyTuple_GET_ITEM(args, 9); + if (!PyUnicode_Check(PyTuple_GET_ITEM(args, 10))) { + _PyArg_BadArgument("code", "argument 11", "str", PyTuple_GET_ITEM(args, 10)); + goto exit; + } + if (PyUnicode_READY(PyTuple_GET_ITEM(args, 10)) == -1) { + goto exit; + } + filename = PyTuple_GET_ITEM(args, 10); + if (!PyUnicode_Check(PyTuple_GET_ITEM(args, 11))) { + _PyArg_BadArgument("code", "argument 12", "str", PyTuple_GET_ITEM(args, 11)); + goto exit; + } + if (PyUnicode_READY(PyTuple_GET_ITEM(args, 11)) == -1) { + goto exit; + } + name = PyTuple_GET_ITEM(args, 11); + firstlineno = _PyLong_AsInt(PyTuple_GET_ITEM(args, 12)); + if (firstlineno == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyBytes_Check(PyTuple_GET_ITEM(args, 13))) { + _PyArg_BadArgument("code", "argument 14", "bytes", PyTuple_GET_ITEM(args, 13)); + goto exit; + } + linetable = PyTuple_GET_ITEM(args, 13); + if (PyTuple_GET_SIZE(args) < 15) { + goto skip_optional; + } + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 14))) { + _PyArg_BadArgument("code", "argument 15", "tuple", PyTuple_GET_ITEM(args, 14)); + goto exit; + } + freevars = PyTuple_GET_ITEM(args, 14); + if (PyTuple_GET_SIZE(args) < 16) { + goto skip_optional; + } + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 15))) { + _PyArg_BadArgument("code", "argument 16", "tuple", PyTuple_GET_ITEM(args, 15)); + goto exit; + } + cellvars = PyTuple_GET_ITEM(args, 15); +skip_optional: + return_value = code_new_impl(type, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, linetable, freevars, cellvars); + +exit: + return return_value; +} + 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_lnotab=None)\n" +" co_linetable=None)\n" "--\n" "\n" "Return a copy of the code object with new values for the specified fields."); @@ -24,13 +160,13 @@ code_replace_impl(PyCodeObject *self, int co_argcount, PyObject *co_consts, PyObject *co_names, PyObject *co_varnames, PyObject *co_freevars, PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyBytesObject *co_lnotab); + PyObject *co_name, PyBytesObject *co_linetable); static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - 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_lnotab", NULL}; + 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_linetable", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; PyObject *argsbuf[16]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; @@ -49,7 +185,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *co_cellvars = self->co_cellvars; PyObject *co_filename = self->co_filename; PyObject *co_name = self->co_name; - PyBytesObject *co_lnotab = (PyBytesObject *)self->co_lnotab; + PyBytesObject *co_linetable = (PyBytesObject *)self->co_linetable; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); if (!args) { @@ -59,11 +195,6 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje goto skip_optional_kwonly; } if (args[0]) { - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } co_argcount = _PyLong_AsInt(args[0]); if (co_argcount == -1 && PyErr_Occurred()) { goto exit; @@ -73,11 +204,6 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } co_posonlyargcount = _PyLong_AsInt(args[1]); if (co_posonlyargcount == -1 && PyErr_Occurred()) { goto exit; @@ -87,11 +213,6 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } co_kwonlyargcount = _PyLong_AsInt(args[2]); if (co_kwonlyargcount == -1 && PyErr_Occurred()) { goto exit; @@ -101,11 +222,6 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[3]) { - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } co_nlocals = _PyLong_AsInt(args[3]); if (co_nlocals == -1 && PyErr_Occurred()) { goto exit; @@ -115,11 +231,6 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[4]) { - if (PyFloat_Check(args[4])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } co_stacksize = _PyLong_AsInt(args[4]); if (co_stacksize == -1 && PyErr_Occurred()) { goto exit; @@ -129,11 +240,6 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[5]) { - if (PyFloat_Check(args[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } co_flags = _PyLong_AsInt(args[5]); if (co_flags == -1 && PyErr_Occurred()) { goto exit; @@ -143,11 +249,6 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[6]) { - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } co_firstlineno = _PyLong_AsInt(args[6]); if (co_firstlineno == -1 && PyErr_Occurred()) { goto exit; @@ -243,14 +344,14 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (!PyBytes_Check(args[15])) { - _PyArg_BadArgument("replace", "argument 'co_lnotab'", "bytes", args[15]); + _PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[15]); goto exit; } - co_lnotab = (PyBytesObject *)args[15]; + co_linetable = (PyBytesObject *)args[15]; 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_lnotab); + 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_linetable); exit: return return_value; } -/*[clinic end generated code: output=27fe34e82106b220 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e3091c7baaaaa420 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/complexobject.c.h b/contrib/tools/python3/src/Objects/clinic/complexobject.c.h index 8caa910d037..557fbf9752f 100644 --- a/contrib/tools/python3/src/Objects/clinic/complexobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/complexobject.c.h @@ -2,6 +2,73 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(complex_conjugate__doc__, +"conjugate($self, /)\n" +"--\n" +"\n" +"Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j."); + +#define COMPLEX_CONJUGATE_METHODDEF \ + {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS, complex_conjugate__doc__}, + +static PyObject * +complex_conjugate_impl(PyComplexObject *self); + +static PyObject * +complex_conjugate(PyComplexObject *self, PyObject *Py_UNUSED(ignored)) +{ + return complex_conjugate_impl(self); +} + +PyDoc_STRVAR(complex___getnewargs____doc__, +"__getnewargs__($self, /)\n" +"--\n" +"\n"); + +#define COMPLEX___GETNEWARGS___METHODDEF \ + {"__getnewargs__", (PyCFunction)complex___getnewargs__, METH_NOARGS, complex___getnewargs____doc__}, + +static PyObject * +complex___getnewargs___impl(PyComplexObject *self); + +static PyObject * +complex___getnewargs__(PyComplexObject *self, PyObject *Py_UNUSED(ignored)) +{ + return complex___getnewargs___impl(self); +} + +PyDoc_STRVAR(complex___format____doc__, +"__format__($self, format_spec, /)\n" +"--\n" +"\n" +"Convert to a string according to format_spec."); + +#define COMPLEX___FORMAT___METHODDEF \ + {"__format__", (PyCFunction)complex___format__, METH_O, complex___format____doc__}, + +static PyObject * +complex___format___impl(PyComplexObject *self, PyObject *format_spec); + +static PyObject * +complex___format__(PyComplexObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *format_spec; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("__format__", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + format_spec = arg; + return_value = complex___format___impl(self, format_spec); + +exit: + return return_value; +} + PyDoc_STRVAR(complex_new__doc__, "complex(real=0, imag=0)\n" "--\n" @@ -23,7 +90,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *r = _PyLong_Zero; + PyObject *r = NULL; PyObject *i = NULL; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf); @@ -46,4 +113,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=a0fe23fdbdc9b06b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=056cac3226d94967 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/dictobject.c.h b/contrib/tools/python3/src/Objects/clinic/dictobject.c.h index 7395e3bcebb..beb3f360f86 100644 --- a/contrib/tools/python3/src/Objects/clinic/dictobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/dictobject.c.h @@ -122,7 +122,8 @@ PyDoc_STRVAR(dict_pop__doc__, "\n" "D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n" "\n" -"If key is not found, default is returned if given, otherwise KeyError is raised"); +"If the key is not found, return the default if given; otherwise,\n" +"raise a KeyError."); #define DICT_POP_METHODDEF \ {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__doc__}, @@ -190,4 +191,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=4d98145508da8fa3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7b77c16e43d6735a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/floatobject.c.h b/contrib/tools/python3/src/Objects/clinic/floatobject.c.h index 6ecdd9e66e9..494c0a22713 100644 --- a/contrib/tools/python3/src/Objects/clinic/floatobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/floatobject.c.h @@ -206,7 +206,7 @@ static PyObject * float_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - PyObject *x = _PyLong_Zero; + PyObject *x = NULL; if ((type == &PyFloat_Type) && !_PyArg_NoKeywords("float", kwargs)) { @@ -387,4 +387,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a6af179ec5f83fba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f4aae29054273cb5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/listobject.c.h b/contrib/tools/python3/src/Objects/clinic/listobject.c.h index ed137c95a8e..01e31d76cfa 100644 --- a/contrib/tools/python3/src/Objects/clinic/listobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/listobject.c.h @@ -24,14 +24,9 @@ list_insert(PyListObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -128,14 +123,9 @@ list_pop(PyListObject *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -196,11 +186,6 @@ list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_kwonly; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } reverse = _PyLong_AsInt(args[1]); if (reverse == -1 && PyErr_Occurred()) { goto exit; @@ -367,4 +352,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=1ff61490c091d165 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0063aad535edf62d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/longobject.c.h b/contrib/tools/python3/src/Objects/clinic/longobject.c.h index 27e8dfe935b..4bd47b116f8 100644 --- a/contrib/tools/python3/src/Objects/clinic/longobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/longobject.c.h @@ -87,6 +87,40 @@ exit: return return_value; } +PyDoc_STRVAR(int___round____doc__, +"__round__($self, ndigits=, /)\n" +"--\n" +"\n" +"Rounding an Integral returns itself.\n" +"\n" +"Rounding with an ndigits argument also returns an integer."); + +#define INT___ROUND___METHODDEF \ + {"__round__", (PyCFunction)(void(*)(void))int___round__, METH_FASTCALL, int___round____doc__}, + +static PyObject * +int___round___impl(PyObject *self, PyObject *o_ndigits); + +static PyObject * +int___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *o_ndigits = NULL; + + if (!_PyArg_CheckPositional("__round__", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + o_ndigits = args[0]; +skip_optional: + return_value = int___round___impl(self, o_ndigits); + +exit: + return return_value; +} + PyDoc_STRVAR(int___sizeof____doc__, "__sizeof__($self, /)\n" "--\n" @@ -138,6 +172,31 @@ int_bit_length(PyObject *self, PyObject *Py_UNUSED(ignored)) return int_bit_length_impl(self); } +PyDoc_STRVAR(int_bit_count__doc__, +"bit_count($self, /)\n" +"--\n" +"\n" +"Number of ones in the binary representation of the absolute value of self.\n" +"\n" +"Also known as the population count.\n" +"\n" +">>> bin(13)\n" +"\'0b1101\'\n" +">>> (13).bit_count()\n" +"3"); + +#define INT_BIT_COUNT_METHODDEF \ + {"bit_count", (PyCFunction)int_bit_count, METH_NOARGS, int_bit_count__doc__}, + +static PyObject * +int_bit_count_impl(PyObject *self); + +static PyObject * +int_bit_count(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_bit_count_impl(self); +} + PyDoc_STRVAR(int_as_integer_ratio__doc__, "as_integer_ratio($self, /)\n" "--\n" @@ -209,14 +268,9 @@ int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject * if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -313,4 +367,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=77bc3b2615822cb8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea18e51af5b53591 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h b/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h index 75ac2011261..4a682f69d65 100644 --- a/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h @@ -2,6 +2,198 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(memoryview__doc__, +"memoryview(object)\n" +"--\n" +"\n" +"Create a new memoryview object which references the given object."); + +static PyObject * +memoryview_impl(PyTypeObject *type, PyObject *object); + +static PyObject * +memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"object", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "memoryview", 0}; + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *object; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + object = fastargs[0]; + return_value = memoryview_impl(type, object); + +exit: + return return_value; +} + +PyDoc_STRVAR(memoryview_release__doc__, +"release($self, /)\n" +"--\n" +"\n" +"Release the underlying buffer exposed by the memoryview object."); + +#define MEMORYVIEW_RELEASE_METHODDEF \ + {"release", (PyCFunction)memoryview_release, METH_NOARGS, memoryview_release__doc__}, + +static PyObject * +memoryview_release_impl(PyMemoryViewObject *self); + +static PyObject * +memoryview_release(PyMemoryViewObject *self, PyObject *Py_UNUSED(ignored)) +{ + return memoryview_release_impl(self); +} + +PyDoc_STRVAR(memoryview_cast__doc__, +"cast($self, /, format, shape=)\n" +"--\n" +"\n" +"Cast a memoryview to a new format or shape."); + +#define MEMORYVIEW_CAST_METHODDEF \ + {"cast", (PyCFunction)(void(*)(void))memoryview_cast, METH_FASTCALL|METH_KEYWORDS, memoryview_cast__doc__}, + +static PyObject * +memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format, + PyObject *shape); + +static PyObject * +memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"format", "shape", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "cast", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *format; + PyObject *shape = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("cast", "argument 'format'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + format = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + shape = args[1]; +skip_optional_pos: + return_value = memoryview_cast_impl(self, format, shape); + +exit: + return return_value; +} + +PyDoc_STRVAR(memoryview_toreadonly__doc__, +"toreadonly($self, /)\n" +"--\n" +"\n" +"Return a readonly version of the memoryview."); + +#define MEMORYVIEW_TOREADONLY_METHODDEF \ + {"toreadonly", (PyCFunction)memoryview_toreadonly, METH_NOARGS, memoryview_toreadonly__doc__}, + +static PyObject * +memoryview_toreadonly_impl(PyMemoryViewObject *self); + +static PyObject * +memoryview_toreadonly(PyMemoryViewObject *self, PyObject *Py_UNUSED(ignored)) +{ + return memoryview_toreadonly_impl(self); +} + +PyDoc_STRVAR(memoryview_tolist__doc__, +"tolist($self, /)\n" +"--\n" +"\n" +"Return the data in the buffer as a list of elements."); + +#define MEMORYVIEW_TOLIST_METHODDEF \ + {"tolist", (PyCFunction)memoryview_tolist, METH_NOARGS, memoryview_tolist__doc__}, + +static PyObject * +memoryview_tolist_impl(PyMemoryViewObject *self); + +static PyObject * +memoryview_tolist(PyMemoryViewObject *self, PyObject *Py_UNUSED(ignored)) +{ + return memoryview_tolist_impl(self); +} + +PyDoc_STRVAR(memoryview_tobytes__doc__, +"tobytes($self, /, order=\'C\')\n" +"--\n" +"\n" +"Return the data in the buffer as a byte string.\n" +"\n" +"Order can be {\'C\', \'F\', \'A\'}. When order is \'C\' or \'F\', the data of the\n" +"original array is converted to C or Fortran order. For contiguous views,\n" +"\'A\' returns an exact copy of the physical memory. In particular, in-memory\n" +"Fortran order is preserved. For non-contiguous views, the data is converted\n" +"to C first. order=None is the same as order=\'C\'."); + +#define MEMORYVIEW_TOBYTES_METHODDEF \ + {"tobytes", (PyCFunction)(void(*)(void))memoryview_tobytes, METH_FASTCALL|METH_KEYWORDS, memoryview_tobytes__doc__}, + +static PyObject * +memoryview_tobytes_impl(PyMemoryViewObject *self, const char *order); + +static PyObject * +memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"order", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "tobytes", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + const char *order = NULL; + + 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] == Py_None) { + order = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t order_length; + order = PyUnicode_AsUTF8AndSize(args[0], &order_length); + if (order == NULL) { + goto exit; + } + if (strlen(order) != (size_t)order_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("tobytes", "argument 'order'", "str or None", args[0]); + goto exit; + } +skip_optional_pos: + return_value = memoryview_tobytes_impl(self, order); + +exit: + return return_value; +} + PyDoc_STRVAR(memoryview_hex__doc__, "hex($self, /, sep=, bytes_per_sep=1)\n" "--\n" @@ -56,11 +248,6 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } bytes_per_sep = _PyLong_AsInt(args[1]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; @@ -71,4 +258,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=ee265a73f68b0077 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1b879bb934d18c66 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/odictobject.c.h b/contrib/tools/python3/src/Objects/clinic/odictobject.c.h index f43bc14ce1b..a3ab9ea507f 100644 --- a/contrib/tools/python3/src/Objects/clinic/odictobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/odictobject.c.h @@ -83,6 +83,49 @@ exit: return return_value; } +PyDoc_STRVAR(OrderedDict_pop__doc__, +"pop($self, /, key, default=)\n" +"--\n" +"\n" +"od.pop(key[,default]) -> v, remove specified key and return the corresponding value.\n" +"\n" +"If the key is not found, return the default if given; otherwise,\n" +"raise a KeyError."); + +#define ORDEREDDICT_POP_METHODDEF \ + {"pop", (PyCFunction)(void(*)(void))OrderedDict_pop, METH_FASTCALL|METH_KEYWORDS, OrderedDict_pop__doc__}, + +static PyObject * +OrderedDict_pop_impl(PyODictObject *self, PyObject *key, + PyObject *default_value); + +static PyObject * +OrderedDict_pop(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"key", "default", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "pop", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *key; + PyObject *default_value = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + key = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + default_value = args[1]; +skip_optional_pos: + return_value = OrderedDict_pop_impl(self, key, default_value); + +exit: + return return_value; +} + PyDoc_STRVAR(OrderedDict_popitem__doc__, "popitem($self, /, last=True)\n" "--\n" @@ -168,4 +211,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=8eb1296df9142908 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e0afaad5b4bb47fe input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/typeobject.c.h b/contrib/tools/python3/src/Objects/clinic/typeobject.c.h index 357eb44b12b..8c70d76d916 100644 --- a/contrib/tools/python3/src/Objects/clinic/typeobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/typeobject.c.h @@ -166,11 +166,6 @@ object___reduce_ex__(PyObject *self, PyObject *arg) PyObject *return_value = NULL; int protocol; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } protocol = _PyLong_AsInt(arg); if (protocol == -1 && PyErr_Occurred()) { goto exit; @@ -248,4 +243,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=7a6d272d282308f3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4fb62939b08baf9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h b/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h index cf81df4af67..9ef8ce2e353 100644 --- a/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h @@ -86,14 +86,9 @@ unicode_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("center", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -224,11 +219,6 @@ unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } tabsize = _PyLong_AsInt(args[0]); if (tabsize == -1 && PyErr_Occurred()) { goto exit; @@ -530,14 +520,9 @@ unicode_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ljust", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -730,14 +715,9 @@ unicode_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -849,14 +829,9 @@ unicode_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("rjust", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -923,14 +898,9 @@ unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -1025,14 +995,9 @@ unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); + PyObject *iobj = _PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -1081,11 +1046,6 @@ unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } keepends = _PyLong_AsInt(args[0]); if (keepends == -1 && PyErr_Occurred()) { goto exit; @@ -1231,14 +1191,9 @@ unicode_zfill(PyObject *self, PyObject *arg) PyObject *return_value = NULL; Py_ssize_t width; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(arg); + PyObject *iobj = _PyNumber_Index(arg); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -1303,4 +1258,73 @@ unicode_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) { return unicode_sizeof_impl(self); } -/*[clinic end generated code: output=b91233f3722643be input=a9049054013a1b77]*/ + +static PyObject * +unicode_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, + const char *errors); + +static PyObject * +unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"object", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "str", 0}; + 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) - 0; + PyObject *x = NULL; + const char *encoding = NULL; + const char *errors = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 3, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + x = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[1]) { + if (!PyUnicode_Check(fastargs[1])) { + _PyArg_BadArgument("str", "argument 'encoding'", "str", fastargs[1]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(fastargs[2])) { + _PyArg_BadArgument("str", "argument 'errors'", "str", fastargs[2]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(fastargs[2], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_pos: + return_value = unicode_new_impl(type, x, encoding, errors); + +exit: + return return_value; +} +/*[clinic end generated code: output=f10cf85d3935b3b7 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/codeobject.c b/contrib/tools/python3/src/Objects/codeobject.c index cb4fb681243..c9f922707e9 100644 --- a/contrib/tools/python3/src/Objects/codeobject.c +++ b/contrib/tools/python3/src/Objects/codeobject.c @@ -4,10 +4,10 @@ #include "code.h" #include "opcode.h" #include "structmember.h" // PyMemberDef -#include "pycore_code.h" +#include "pycore_code.h" // _PyOpcache #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_tupleobject.h" +#include "pycore_tuple.h" // _PyTuple_ITEMS() #include "clinic/codeobject.c.h" /* Holder for co_extra information */ @@ -119,7 +119,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, - PyObject *lnotab) + PyObject *linetable) { PyCodeObject *co; Py_ssize_t *cell2arg = NULL; @@ -137,7 +137,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, cellvars == NULL || !PyTuple_Check(cellvars) || name == NULL || !PyUnicode_Check(name) || filename == NULL || !PyUnicode_Check(filename) || - lnotab == NULL || !PyBytes_Check(lnotab)) { + linetable == NULL || !PyBytes_Check(linetable)) { PyErr_BadInternalCall(); return NULL; } @@ -213,7 +213,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, PyObject *arg = PyTuple_GET_ITEM(varnames, j); int cmp = PyUnicode_Compare(cell, arg); if (cmp == -1 && PyErr_Occurred()) { - PyMem_FREE(cell2arg); + PyMem_Free(cell2arg); return NULL; } if (cmp == 0) { @@ -224,14 +224,14 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, } } if (!used_cell2arg) { - PyMem_FREE(cell2arg); + PyMem_Free(cell2arg); cell2arg = NULL; } } co = PyObject_New(PyCodeObject, &PyCode_Type); if (co == NULL) { if (cell2arg) - PyMem_FREE(cell2arg); + PyMem_Free(cell2arg); return NULL; } co->co_argcount = argcount; @@ -258,8 +258,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, Py_INCREF(name); co->co_name = name; co->co_firstlineno = firstlineno; - Py_INCREF(lnotab); - co->co_lnotab = lnotab; + Py_INCREF(linetable); + co->co_linetable = linetable; co->co_zombieframe = NULL; co->co_weakreflist = NULL; co->co_extra = NULL; @@ -277,12 +277,12 @@ PyCode_New(int argcount, int kwonlyargcount, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, - PyObject *lnotab) + PyObject *linetable) { return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, freevars, cellvars, filename, - name, firstlineno, lnotab); + name, firstlineno, linetable); } int @@ -294,15 +294,15 @@ _PyCode_InitOpcache(PyCodeObject *co) return -1; } - _Py_CODEUNIT *opcodes = (_Py_CODEUNIT*)PyBytes_AS_STRING(co->co_code); + const _Py_CODEUNIT *opcodes = (_Py_CODEUNIT*)PyBytes_AS_STRING(co->co_code); Py_ssize_t opts = 0; for (Py_ssize_t i = 0; i < co_size;) { unsigned char opcode = _Py_OPCODE(opcodes[i]); i++; // 'i' is now aligned to (next_instr - first_instr) - // TODO: LOAD_METHOD, LOAD_ATTR - if (opcode == LOAD_GLOBAL) { + // TODO: LOAD_METHOD + if (opcode == LOAD_GLOBAL || opcode == LOAD_ATTR) { opts++; co->co_opcache_map[i] = (unsigned char)opts; if (opts > 254) { @@ -314,12 +314,12 @@ _PyCode_InitOpcache(PyCodeObject *co) if (opts) { co->co_opcache = (_PyOpcache *)PyMem_Calloc(opts, sizeof(_PyOpcache)); if (co->co_opcache == NULL) { - PyMem_FREE(co->co_opcache_map); + PyMem_Free(co->co_opcache_map); return -1; } } else { - PyMem_FREE(co->co_opcache_map); + PyMem_Free(co->co_opcache_map); co->co_opcache_map = NULL; co->co_opcache = NULL; } @@ -369,7 +369,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) filename_ob, /* filename */ funcname_ob, /* name */ firstlineno, /* firstlineno */ - emptystring /* lnotab */ + emptystring /* linetable */ ); failed: @@ -395,11 +395,89 @@ static PyMemberDef code_memberlist[] = { {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, {"co_name", T_OBJECT, OFF(co_name), READONLY}, - {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, - {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY}, + {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, + {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY}, {NULL} /* Sentinel */ }; +static int +emit_pair(PyObject **bytes, int *offset, int a, int b) +{ + Py_ssize_t len = PyBytes_GET_SIZE(*bytes); + if (*offset + 2 >= len) { + if (_PyBytes_Resize(bytes, len * 2) < 0) + return 0; + } + unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(*bytes); + lnotab += *offset; + *lnotab++ = a; + *lnotab++ = b; + *offset += 2; + return 1; +} + +static int +emit_delta(PyObject **bytes, int bdelta, int ldelta, int *offset) +{ + while (bdelta > 255) { + if (!emit_pair(bytes, offset, 255, 0)) { + return 0; + } + bdelta -= 255; + } + while (ldelta > 127) { + if (!emit_pair(bytes, offset, bdelta, 127)) { + return 0; + } + bdelta = 0; + ldelta -= 127; + } + while (ldelta < -128) { + if (!emit_pair(bytes, offset, bdelta, -128)) { + return 0; + } + bdelta = 0; + ldelta += 128; + } + return emit_pair(bytes, offset, bdelta, ldelta); +} + +static PyObject * +code_getlnotab(PyCodeObject *code, void *closure) +{ + PyCodeAddressRange bounds; + PyObject *bytes; + int table_offset = 0; + int code_offset = 0; + int line = code->co_firstlineno; + bytes = PyBytes_FromStringAndSize(NULL, 64); + if (bytes == NULL) { + return NULL; + } + _PyCode_InitAddressRange(code, &bounds); + while (PyLineTable_NextAddressRange(&bounds)) { + if (bounds.opaque.computed_line != line) { + int bdelta = bounds.ar_start - code_offset; + int ldelta = bounds.opaque.computed_line - line; + if (!emit_delta(&bytes, bdelta, ldelta, &table_offset)) { + Py_DECREF(bytes); + return NULL; + } + code_offset = bounds.ar_start; + line = bounds.opaque.computed_line; + } + } + _PyBytes_Resize(&bytes, table_offset); + return bytes; +} + + +static PyGetSetDef code_getsetlist[] = { + {"co_lnotab", (getter)code_getlnotab, NULL, NULL}, + {0} +}; + + /* Helper for code_new: return a shallow copy of a tuple that is guaranteed to contain exact strings, by converting string subclasses to exact strings and complaining if a non-string is found. */ @@ -442,46 +520,45 @@ validate_and_copy_tuple(PyObject *tup) return newtuple; } -PyDoc_STRVAR(code_doc, -"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n\ - flags, codestring, constants, names, varnames, filename, name,\n\ - firstlineno, lnotab[, freevars[, cellvars]])\n\ -\n\ -Create a code object. Not for the faint of heart."); +/*[clinic input] +@classmethod +code.__new__ as code_new + + argcount: int + posonlyargcount: int + kwonlyargcount: int + nlocals: int + stacksize: int + flags: int + codestring as code: object(subclass_of="&PyBytes_Type") + constants as consts: object(subclass_of="&PyTuple_Type") + names: object(subclass_of="&PyTuple_Type") + varnames: object(subclass_of="&PyTuple_Type") + filename: unicode + name: unicode + firstlineno: int + linetable: object(subclass_of="&PyBytes_Type") + freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = () + cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = () + / + +Create a code object. Not for the faint of heart. +[clinic start generated code]*/ static PyObject * -code_new(PyTypeObject *type, PyObject *args, PyObject *kw) +code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, + int kwonlyargcount, int nlocals, int stacksize, int flags, + PyObject *code, PyObject *consts, PyObject *names, + PyObject *varnames, PyObject *filename, PyObject *name, + int firstlineno, PyObject *linetable, PyObject *freevars, + PyObject *cellvars) +/*[clinic end generated code: output=42c1839b082ba293 input=0ec80da632b99f57]*/ { - int argcount; - int posonlyargcount; - int kwonlyargcount; - int nlocals; - int stacksize; - int flags; PyObject *co = NULL; - PyObject *code; - PyObject *consts; - PyObject *names, *ournames = NULL; - PyObject *varnames, *ourvarnames = NULL; - PyObject *freevars = NULL, *ourfreevars = NULL; - PyObject *cellvars = NULL, *ourcellvars = NULL; - PyObject *filename; - PyObject *name; - int firstlineno; - PyObject *lnotab; - - if (!PyArg_ParseTuple(args, "iiiiiiSO!O!O!UUiS|O!O!:code", - &argcount, &posonlyargcount, &kwonlyargcount, - &nlocals, &stacksize, &flags, - &code, - &PyTuple_Type, &consts, - &PyTuple_Type, &names, - &PyTuple_Type, &varnames, - &filename, &name, - &firstlineno, &lnotab, - &PyTuple_Type, &freevars, - &PyTuple_Type, &cellvars)) - return NULL; + PyObject *ournames = NULL; + PyObject *ourvarnames = NULL; + PyObject *ourfreevars = NULL; + PyObject *ourcellvars = NULL; if (PySys_Audit("code.__new__", "OOOiiiiii", code, filename, name, argcount, posonlyargcount, @@ -541,7 +618,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) code, consts, ournames, ourvarnames, ourfreevars, ourcellvars, filename, - name, firstlineno, lnotab); + name, firstlineno, linetable); cleanup: Py_XDECREF(ournames); Py_XDECREF(ourvarnames); @@ -554,10 +631,10 @@ static void code_dealloc(PyCodeObject *co) { if (co->co_opcache != NULL) { - PyMem_FREE(co->co_opcache); + PyMem_Free(co->co_opcache); } if (co->co_opcache_map != NULL) { - PyMem_FREE(co->co_opcache_map); + PyMem_Free(co->co_opcache_map); } co->co_opcache_flag = 0; co->co_opcache_size = 0; @@ -585,14 +662,14 @@ code_dealloc(PyCodeObject *co) Py_XDECREF(co->co_cellvars); Py_XDECREF(co->co_filename); Py_XDECREF(co->co_name); - Py_XDECREF(co->co_lnotab); + Py_XDECREF(co->co_linetable); if (co->co_cell2arg != NULL) - PyMem_FREE(co->co_cell2arg); + PyMem_Free(co->co_cell2arg); if (co->co_zombieframe != NULL) PyObject_GC_Del(co->co_zombieframe); if (co->co_weakreflist != NULL) PyObject_ClearWeakRefs((PyObject*)co); - PyObject_DEL(co); + PyObject_Free(co); } static PyObject * @@ -637,7 +714,7 @@ code.replace co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None co_filename: unicode(c_default="self->co_filename") = None co_name: unicode(c_default="self->co_name") = None - co_lnotab: PyBytesObject(c_default="(PyBytesObject *)self->co_lnotab") = None + co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None Return a copy of the code object with new values for the specified fields. [clinic start generated code]*/ @@ -650,8 +727,8 @@ code_replace_impl(PyCodeObject *self, int co_argcount, PyObject *co_consts, PyObject *co_names, PyObject *co_varnames, PyObject *co_freevars, PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyBytesObject *co_lnotab) -/*[clinic end generated code: output=25c8e303913bcace input=d9051bc8f24e6b28]*/ + PyObject *co_name, PyBytesObject *co_linetable) +/*[clinic end generated code: output=50d77e668d3b449b input=a5f997b173d7f636]*/ { #define CHECK_INT_ARG(ARG) \ if (ARG < 0) { \ @@ -681,7 +758,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, - co_firstlineno, (PyObject*)co_lnotab); + co_firstlineno, (PyObject*)co_linetable); } static PyObject * @@ -934,10 +1011,188 @@ code_hash(PyCodeObject *co) return h; } +typedef struct { + PyObject_HEAD + PyCodeObject *li_code; + PyCodeAddressRange li_line; + char *li_end; +} lineiterator; + + +static void +lineiter_dealloc(lineiterator *li) +{ + Py_DECREF(li->li_code); + Py_TYPE(li)->tp_free(li); +} + +static PyObject * +lineiter_next(lineiterator *li) +{ + PyCodeAddressRange *bounds = &li->li_line; + 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; + } + 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; +} + +static PyTypeObject LineIterator = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "line_iterator", /* tp_name */ + sizeof(lineiterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)lineiter_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 */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)lineiter_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 */ + PyObject_Del, /* tp_free */ +}; + +static PyObject * +code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args)) +{ + lineiterator *li = (lineiterator *)PyType_GenericAlloc(&LineIterator, 0); + if (li == NULL) { + return NULL; + } + Py_INCREF(code); + li->li_code = code; + _PyCode_InitAddressRange(code, &li->li_line); + return (PyObject *)li; +} + +static void +retreat(PyCodeAddressRange *bounds) +{ + int ldelta = ((signed char *)bounds->opaque.lo_next)[-1]; + if (ldelta == -128) { + ldelta = 0; + } + bounds->opaque.computed_line -= ldelta; + bounds->opaque.lo_next -= 2; + bounds->ar_end = bounds->ar_start; + bounds->ar_start -= ((unsigned char *)bounds->opaque.lo_next)[-2]; + ldelta = ((signed char *)bounds->opaque.lo_next)[-1]; + if (ldelta == -128) { + bounds->ar_line = -1; + } + else { + bounds->ar_line = bounds->opaque.computed_line; + } +} + +static void +advance(PyCodeAddressRange *bounds) +{ + bounds->ar_start = bounds->ar_end; + int delta = ((unsigned char *)bounds->opaque.lo_next)[0]; + bounds->ar_end += delta; + int ldelta = ((signed char *)bounds->opaque.lo_next)[1]; + bounds->opaque.lo_next += 2; + if (ldelta == -128) { + bounds->ar_line = -1; + } + else { + bounds->opaque.computed_line += ldelta; + bounds->ar_line = bounds->opaque.computed_line; + } +} + +static inline int +at_end(PyCodeAddressRange *bounds) { + return bounds->opaque.lo_next >= bounds->opaque.limit; +} + +int +PyLineTable_PreviousAddressRange(PyCodeAddressRange *range) +{ + if (range->ar_start <= 0) { + return 0; + } + retreat(range); + while (range->ar_start == range->ar_end) { + assert(range->ar_start > 0); + retreat(range); + } + return 1; +} + +int +PyLineTable_NextAddressRange(PyCodeAddressRange *range) +{ + if (at_end(range)) { + return 0; + } + advance(range); + while (range->ar_start == range->ar_end && !at_end(range)) { + assert(!at_end(range)); + advance(range); + } + return 1; +} + + /* XXX code objects need to participate in GC? */ static struct PyMethodDef code_methods[] = { {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS}, + {"co_lines", (PyCFunction)code_linesiterator, METH_NOARGS}, CODE_REPLACE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -963,7 +1218,7 @@ PyTypeObject PyCode_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - code_doc, /* tp_doc */ + code_new__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ code_richcompare, /* tp_richcompare */ @@ -972,7 +1227,7 @@ PyTypeObject PyCode_Type = { 0, /* tp_iternext */ code_methods, /* tp_methods */ code_memberlist, /* tp_members */ - 0, /* tp_getset */ + code_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -983,78 +1238,58 @@ PyTypeObject PyCode_Type = { code_new, /* tp_new */ }; -/* Use co_lnotab to compute the line number from a bytecode index, addrq. See +/* 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_Addr2Line(PyCodeObject *co, int addrq) { - Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2; - unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab); - int line = co->co_firstlineno; - int addr = 0; - while (--size >= 0) { - addr += *p++; - if (addr > addrq) - break; - line += (signed char)*p; - p++; - } - return line; + if (addrq < 0) { + return co->co_firstlineno; + } + assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); + PyCodeAddressRange bounds; + _PyCode_InitAddressRange(co, &bounds); + return _PyCode_CheckLineNumber(addrq, &bounds); +} + +void +PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range) +{ + range->opaque.lo_next = linetable; + range->opaque.limit = range->opaque.lo_next + length; + range->ar_start = -1; + range->ar_end = 0; + range->opaque.computed_line = firstlineno; + range->ar_line = -1; +} + +int +_PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds) +{ + const char *linetable = PyBytes_AS_STRING(co->co_linetable); + Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable); + PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds); + return bounds->ar_line; } /* Update *bounds to describe the first and one-past-the-last instructions in - the same line as lasti. Return the number of that line. */ + the same line as lasti. Return the number of that line, or -1 if lasti is out of bounds. */ int -_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) +_PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds) { - Py_ssize_t size; - int addr, line; - unsigned char* p; - - p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab); - size = PyBytes_GET_SIZE(co->co_lnotab) / 2; - - addr = 0; - line = co->co_firstlineno; - assert(line > 0); - - /* possible optimization: if f->f_lasti == instr_ub - (likely to be a common case) then we already know - instr_lb -- if we stored the matching value of p - somewhere we could skip the first while loop. */ - - /* See lnotab_notes.txt for the description of - co_lnotab. A point to remember: increments to p - come in (addr, line) pairs. */ - - bounds->ap_lower = 0; - while (size > 0) { - if (addr + *p > lasti) - break; - addr += *p++; - if ((signed char)*p) - bounds->ap_lower = addr; - line += (signed char)*p; - p++; - --size; - } - - if (size > 0) { - while (--size >= 0) { - addr += *p++; - if ((signed char)*p) - break; - p++; + while (bounds->ar_end <= lasti) { + if (!PyLineTable_NextAddressRange(bounds)) { + return -1; } - bounds->ap_upper = addr; } - else { - bounds->ap_upper = INT_MAX; + while (bounds->ar_start > lasti) { + if (!PyLineTable_PreviousAddressRange(bounds)) { + return -1; + } } - - return line; + return bounds->ar_line; } diff --git a/contrib/tools/python3/src/Objects/complexobject.c b/contrib/tools/python3/src/Objects/complexobject.c index e09cc15fe84..3e479497cfc 100644 --- a/contrib/tools/python3/src/Objects/complexobject.c +++ b/contrib/tools/python3/src/Objects/complexobject.c @@ -6,8 +6,11 @@ /* Submitted by Jim Hugunin */ #include "Python.h" +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_object.h" // _PyObject_Init() #include "structmember.h" // PyMemberDef + /*[clinic input] class complex "PyComplexObject *" "&PyComplex_Type" [clinic start generated code]*/ @@ -222,13 +225,12 @@ complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval) PyObject * PyComplex_FromCComplex(Py_complex cval) { - PyComplexObject *op; - /* Inline PyObject_New */ - op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); - if (op == NULL) + PyComplexObject *op = PyObject_Malloc(sizeof(PyComplexObject)); + if (op == NULL) { return PyErr_NoMemory(); - (void)PyObject_INIT(op, &PyComplex_Type); + } + _PyObject_Init((PyObject*)op, &PyComplex_Type); op->cval = cval; return (PyObject *) op; } @@ -403,10 +405,10 @@ static Py_hash_t complex_hash(PyComplexObject *v) { Py_uhash_t hashreal, hashimag, combined; - hashreal = (Py_uhash_t)_Py_HashDouble(v->cval.real); + hashreal = (Py_uhash_t)_Py_HashDouble((PyObject *) v, v->cval.real); if (hashreal == (Py_uhash_t)-1) return -1; - hashimag = (Py_uhash_t)_Py_HashDouble(v->cval.imag); + hashimag = (Py_uhash_t)_Py_HashDouble((PyObject *)v, v->cval.imag); if (hashimag == (Py_uhash_t)-1) return -1; /* Note: if the imaginary part is 0, hashimag is 0 now, @@ -501,23 +503,6 @@ complex_div(PyObject *v, PyObject *w) return PyComplex_FromCComplex(quot); } -static PyObject * -complex_remainder(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't mod complex numbers."); - return NULL; -} - - -static PyObject * -complex_divmod(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't take floor or mod of complex number."); - return NULL; -} - static PyObject * complex_pow(PyObject *v, PyObject *w, PyObject *z) { @@ -554,14 +539,6 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z) return PyComplex_FromCComplex(p); } -static PyObject * -complex_int_div(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't take floor of complex number."); - return NULL; -} - static PyObject * complex_neg(PyComplexObject *v) { @@ -660,62 +637,54 @@ Unimplemented: Py_RETURN_NOTIMPLEMENTED; } -static PyObject * -complex_int(PyObject *v) -{ - PyErr_SetString(PyExc_TypeError, - "can't convert complex to int"); - return NULL; -} +/*[clinic input] +complex.conjugate -static PyObject * -complex_float(PyObject *v) -{ - PyErr_SetString(PyExc_TypeError, - "can't convert complex to float"); - return NULL; -} +Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j. +[clinic start generated code]*/ static PyObject * -complex_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored)) +complex_conjugate_impl(PyComplexObject *self) +/*[clinic end generated code: output=5059ef162edfc68e input=5fea33e9747ec2c4]*/ { - Py_complex c; - c = ((PyComplexObject *)self)->cval; + Py_complex c = self->cval; c.imag = -c.imag; return PyComplex_FromCComplex(c); } -PyDoc_STRVAR(complex_conjugate_doc, -"complex.conjugate() -> complex\n" -"\n" -"Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j."); +/*[clinic input] +complex.__getnewargs__ + +[clinic start generated code]*/ static PyObject * -complex_getnewargs(PyComplexObject *v, PyObject *Py_UNUSED(ignored)) +complex___getnewargs___impl(PyComplexObject *self) +/*[clinic end generated code: output=689b8206e8728934 input=539543e0a50533d7]*/ { - Py_complex c = v->cval; + Py_complex c = self->cval; return Py_BuildValue("(dd)", c.real, c.imag); } -PyDoc_STRVAR(complex__format__doc, -"complex.__format__() -> str\n" -"\n" -"Convert to a string according to format_spec."); + +/*[clinic input] +complex.__format__ + + format_spec: unicode + / + +Convert to a string according to format_spec. +[clinic start generated code]*/ static PyObject * -complex__format__(PyObject* self, PyObject* args) +complex___format___impl(PyComplexObject *self, PyObject *format_spec) +/*[clinic end generated code: output=bfcb60df24cafea0 input=014ef5488acbe1d5]*/ { - PyObject *format_spec; _PyUnicodeWriter writer; int ret; - - if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) - return NULL; - _PyUnicodeWriter_Init(&writer); ret = _PyComplex_FormatAdvancedWriter( &writer, - self, + (PyObject *)self, format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); if (ret == -1) { _PyUnicodeWriter_Dealloc(&writer); @@ -725,11 +694,9 @@ complex__format__(PyObject* self, PyObject* args) } static PyMethodDef complex_methods[] = { - {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS, - complex_conjugate_doc}, - {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, - {"__format__", (PyCFunction)complex__format__, - METH_VARARGS, complex__format__doc}, + COMPLEX_CONJUGATE_METHODDEF + COMPLEX___GETNEWARGS___METHODDEF + COMPLEX___FORMAT___METHODDEF {NULL, NULL} /* sentinel */ }; @@ -897,7 +864,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) /*[clinic input] @classmethod complex.__new__ as complex_new - real as r: object(c_default="_PyLong_Zero") = 0 + real as r: object(c_default="NULL") = 0 imag as i: object(c_default="NULL") = 0 Create a complex number from a real part and an optional imaginary part. @@ -907,7 +874,7 @@ This is equivalent to (real + imag*1j) where imag defaults to 0. static PyObject * complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) -/*[clinic end generated code: output=b6c7dd577b537dc1 input=6f6b0bedba29bcb5]*/ +/*[clinic end generated code: output=b6c7dd577b537dc1 input=f4c667f2596d4fd1]*/ { PyObject *tmp; PyNumberMethods *nbr, *nbi = NULL; @@ -916,6 +883,10 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) int cr_is_complex = 0; int ci_is_complex = 0; + if (r == NULL) { + r = _PyLong_GetZero(); + } + /* Special-case for a single argument when type(arg) is complex. */ if (PyComplex_CheckExact(r) && i == NULL && type == &PyComplex_Type) { @@ -952,7 +923,9 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } nbr = Py_TYPE(r)->tp_as_number; - if (nbr == NULL || (nbr->nb_float == NULL && nbr->nb_index == NULL)) { + if (nbr == NULL || + (nbr->nb_float == NULL && nbr->nb_index == NULL && !PyComplex_Check(r))) + { PyErr_Format(PyExc_TypeError, "complex() first argument must be a string or a number, " "not '%.200s'", @@ -964,7 +937,9 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } if (i != NULL) { nbi = Py_TYPE(i)->tp_as_number; - if (nbi == NULL || (nbi->nb_float == NULL && nbi->nb_index == NULL)) { + if (nbi == NULL || + (nbi->nb_float == NULL && nbi->nb_index == NULL && !PyComplex_Check(i))) + { PyErr_Format(PyExc_TypeError, "complex() second argument must be a number, " "not '%.200s'", @@ -1043,8 +1018,8 @@ static PyNumberMethods complex_as_number = { (binaryfunc)complex_add, /* nb_add */ (binaryfunc)complex_sub, /* nb_subtract */ (binaryfunc)complex_mul, /* nb_multiply */ - (binaryfunc)complex_remainder, /* nb_remainder */ - (binaryfunc)complex_divmod, /* nb_divmod */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ (ternaryfunc)complex_pow, /* nb_power */ (unaryfunc)complex_neg, /* nb_negative */ (unaryfunc)complex_pos, /* nb_positive */ @@ -1056,9 +1031,9 @@ static PyNumberMethods complex_as_number = { 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ - complex_int, /* nb_int */ + 0, /* nb_int */ 0, /* nb_reserved */ - complex_float, /* nb_float */ + 0, /* nb_float */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply*/ @@ -1069,7 +1044,7 @@ static PyNumberMethods complex_as_number = { 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ - (binaryfunc)complex_int_div, /* nb_floor_divide */ + 0, /* nb_floor_divide */ (binaryfunc)complex_div, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ diff --git a/contrib/tools/python3/src/Objects/descrobject.c b/contrib/tools/python3/src/Objects/descrobject.c index 00349ab1791..09b0f82c699 100644 --- a/contrib/tools/python3/src/Objects/descrobject.c +++ b/contrib/tools/python3/src/Objects/descrobject.c @@ -1,10 +1,10 @@ /* Descriptors -- a new, flexible way to describe attributes */ #include "Python.h" -#include "pycore_ceval.h" // _Py_EnterRecursiveCall() -#include "pycore_object.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tupleobject.h" +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef _Py_IDENTIFIER(getattr); @@ -132,8 +132,7 @@ static PyObject * method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) { if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; + return Py_NewRef(descr); } if (descr_check((PyDescrObject *)descr, obj) < 0) { return NULL; @@ -157,14 +156,13 @@ static PyObject * member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) { if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; + return Py_NewRef(descr); } if (descr_check((PyDescrObject *)descr, obj) < 0) { return NULL; } - if (descr->d_member->flags & READ_RESTRICTED) { + if (descr->d_member->flags & PY_AUDIT_READ) { if (PySys_Audit("object.__getattr__", "Os", obj ? obj : Py_None, descr->d_member->name) < 0) { return NULL; @@ -178,8 +176,7 @@ static PyObject * getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) { if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; + return Py_NewRef(descr); } if (descr_check((PyDescrObject *)descr, obj) < 0) { return NULL; @@ -197,8 +194,7 @@ static PyObject * wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) { if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; + return Py_NewRef(descr); } if (descr_check((PyDescrObject *)descr, obj) < 0) { return NULL; @@ -997,6 +993,11 @@ PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) return (PyObject *)descr; } +int +PyDescr_IsData(PyObject *ob) +{ + return Py_TYPE(ob)->tp_descr_set != NULL; +} /* --- mappingproxy: read-only proxy for mappings --- */ @@ -1492,6 +1493,7 @@ typedef struct { PyObject *prop_set; PyObject *prop_del; PyObject *prop_doc; + PyObject *prop_name; int getter_doc; } propertyobject; @@ -1537,10 +1539,33 @@ property_deleter(PyObject *self, PyObject *deleter) } +PyDoc_STRVAR(set_name_doc, + "Method to set name of a property."); + +static PyObject * +property_set_name(PyObject *self, PyObject *args) { + if (PyTuple_GET_SIZE(args) != 2) { + PyErr_Format( + PyExc_TypeError, + "__set_name__() takes 2 positional arguments but %d were given", + PyTuple_GET_SIZE(args)); + return NULL; + } + + propertyobject *prop = (propertyobject *)self; + PyObject *name = PyTuple_GET_ITEM(args, 1); + + Py_XINCREF(name); + Py_XSETREF(prop->prop_name, name); + + Py_RETURN_NONE; +} + static PyMethodDef property_methods[] = { {"getter", property_getter, METH_O, getter_doc}, {"setter", property_setter, METH_O, setter_doc}, {"deleter", property_deleter, METH_O, deleter_doc}, + {"__set_name__", property_set_name, METH_VARARGS, set_name_doc}, {0} }; @@ -1555,6 +1580,7 @@ property_dealloc(PyObject *self) Py_XDECREF(gs->prop_set); Py_XDECREF(gs->prop_del); Py_XDECREF(gs->prop_doc); + Py_XDECREF(gs->prop_name); Py_TYPE(self)->tp_free(self); } @@ -1568,7 +1594,12 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) propertyobject *gs = (propertyobject *)self; if (gs->prop_get == NULL) { - PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); + if (gs->prop_name != NULL) { + PyErr_Format(PyExc_AttributeError, "unreadable attribute %R", gs->prop_name); + } else { + PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); + } + return NULL; } @@ -1586,10 +1617,18 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) else func = gs->prop_set; if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, + if (gs->prop_name != NULL) { + PyErr_Format(PyExc_AttributeError, value == NULL ? - "can't delete attribute" : - "can't set attribute"); + "can't delete attribute %R" : + "can't set attribute %R", + gs->prop_name); + } else { + PyErr_SetString(PyExc_AttributeError, + value == NULL ? + "can't delete attribute" : + "can't set attribute"); + } return -1; } if (value == NULL) @@ -1636,6 +1675,9 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) Py_DECREF(type); if (new == NULL) return NULL; + + Py_XINCREF(pold->prop_name); + Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name); return new; } @@ -1697,6 +1739,8 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, Py_XSETREF(self->prop_set, fset); Py_XSETREF(self->prop_del, fdel); Py_XSETREF(self->prop_doc, doc); + Py_XSETREF(self->prop_name, NULL); + self->getter_doc = 0; /* if no docstring given and the getter has one, use that one */ @@ -1771,6 +1815,7 @@ property_traverse(PyObject *self, visitproc visit, void *arg) Py_VISIT(pp->prop_set); Py_VISIT(pp->prop_del); Py_VISIT(pp->prop_doc); + Py_VISIT(pp->prop_name); return 0; } @@ -1805,7 +1850,8 @@ PyTypeObject PyDictProxy_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_MAPPING, /* tp_flags */ 0, /* tp_doc */ mappingproxy_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/contrib/tools/python3/src/Objects/dictobject.c b/contrib/tools/python3/src/Objects/dictobject.c index 2ae122d3239..24973c07b1d 100644 --- a/contrib/tools/python3/src/Objects/dictobject.c +++ b/contrib/tools/python3/src/Objects/dictobject.c @@ -111,8 +111,10 @@ converting the dict to the combined table. #define PyDict_MINSIZE 8 #include "Python.h" +#include "pycore_bitutils.h" // _Py_bit_length #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() -#include "pycore_object.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_pyerrors.h" // _PyErr_Fetch() #include "pycore_pystate.h" // _PyThreadState_GET() #include "dict-common.h" #include "stringlib/eq.h" // unicode_eq() @@ -235,7 +237,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); -static int dictresize(PyDictObject *mp, Py_ssize_t minused); +static int dictresize(PyDictObject *mp, Py_ssize_t newsize); static PyObject* dict_iter(PyDictObject *dict); @@ -246,52 +248,54 @@ static uint64_t pydict_global_version = 0; #define DICT_NEXT_VERSION() (++pydict_global_version) -/* Dictionary reuse scheme to save calls to malloc and free */ -#ifndef PyDict_MAXFREELIST -#define PyDict_MAXFREELIST 80 -#endif +#include "clinic/dictobject.c.h" -#if PyDict_MAXFREELIST > 0 -static PyDictObject *free_list[PyDict_MAXFREELIST]; -static int numfree = 0; -static PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; -static int numfreekeys = 0; -#endif -#include "clinic/dictobject.c.h" +static struct _Py_dict_state * +get_dict_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->dict_state; +} + void -_PyDict_ClearFreeList(void) +_PyDict_ClearFreeList(PyInterpreterState *interp) { -#if PyDict_MAXFREELIST > 0 - while (numfree) { - PyDictObject *op = free_list[--numfree]; + struct _Py_dict_state *state = &interp->dict_state; + while (state->numfree) { + PyDictObject *op = state->free_list[--state->numfree]; assert(PyDict_CheckExact(op)); PyObject_GC_Del(op); } - while (numfreekeys) { - PyObject_FREE(keys_free_list[--numfreekeys]); + while (state->keys_numfree) { + PyObject_Free(state->keys_free_list[--state->keys_numfree]); } -#endif } -/* Print summary info about the state of the optimized allocator */ + void -_PyDict_DebugMallocStats(FILE *out) +_PyDict_Fini(PyInterpreterState *interp) { -#if PyDict_MAXFREELIST > 0 - _PyDebugAllocatorStats(out, - "free PyDictObject", numfree, sizeof(PyDictObject)); + _PyDict_ClearFreeList(interp); +#ifdef Py_DEBUG + struct _Py_dict_state *state = &interp->dict_state; + state->numfree = -1; + state->keys_numfree = -1; #endif } +/* Print summary info about the state of the optimized allocator */ void -_PyDict_Fini(void) +_PyDict_DebugMallocStats(FILE *out) { - _PyDict_ClearFreeList(); + struct _Py_dict_state *state = get_dict_state(); + _PyDebugAllocatorStats(out, "free PyDictObject", + state->numfree, sizeof(PyDictObject)); } + #define DK_SIZE(dk) ((dk)->dk_size) #if SIZEOF_VOID_P > 4 #define DK_IXSIZE(dk) \ @@ -408,18 +412,40 @@ dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) */ #define USABLE_FRACTION(n) (((n) << 1)/3) -/* ESTIMATE_SIZE is reverse function of USABLE_FRACTION. +/* Find the smallest dk_size >= minsize. */ +static inline Py_ssize_t +calculate_keysize(Py_ssize_t minsize) +{ +#if SIZEOF_LONG == SIZEOF_SIZE_T + minsize = (minsize | PyDict_MINSIZE) - 1; + return 1LL << _Py_bit_length(minsize | (PyDict_MINSIZE-1)); +#elif defined(_MSC_VER) + // On 64bit Windows, sizeof(long) == 4. + minsize = (minsize | PyDict_MINSIZE) - 1; + unsigned long msb; + _BitScanReverse64(&msb, (uint64_t)minsize); + return 1LL << (msb + 1); +#else + Py_ssize_t size; + for (size = PyDict_MINSIZE; + size < minsize && size > 0; + size <<= 1) + ; + return size; +#endif +} + +/* estimate_keysize is reverse function of USABLE_FRACTION. + * * This can be used to reserve enough size to insert n entries without * resizing. */ -#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1) +static inline Py_ssize_t +estimate_keysize(Py_ssize_t n) +{ + return calculate_keysize((n*3 + 1) / 2); +} -/* Alternative fraction that is otherwise close enough to 2n/3 to make - * little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10. - * 32 * 2/3 = 21, 32 * 5/8 = 20. - * Its advantage is that it is faster to compute on machines with slow division. - * #define USABLE_FRACTION(n) (((n) >> 1) + ((n) >> 2) - ((n) >> 3)) - */ /* GROWTH_RATE. Growth rate upon hitting maximum load. * Currently set to used*3. @@ -536,7 +562,8 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) } -static PyDictKeysObject *new_keys_object(Py_ssize_t size) +static PyDictKeysObject* +new_keys_object(Py_ssize_t size) { PyDictKeysObject *dk; Py_ssize_t es, usable; @@ -560,14 +587,17 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size) es = sizeof(Py_ssize_t); } -#if PyDict_MAXFREELIST > 0 - if (size == PyDict_MINSIZE && numfreekeys > 0) { - dk = keys_free_list[--numfreekeys]; + struct _Py_dict_state *state = get_dict_state(); +#ifdef Py_DEBUG + // new_keys_object() must not be called after _PyDict_Fini() + assert(state->keys_numfree != -1); +#endif + if (size == PyDict_MINSIZE && state->keys_numfree > 0) { + dk = state->keys_free_list[--state->keys_numfree]; } else -#endif { - dk = PyObject_MALLOC(sizeof(PyDictKeysObject) + dk = PyObject_Malloc(sizeof(PyDictKeysObject) + es * size + sizeof(PyDictKeyEntry) * usable); if (dk == NULL) { @@ -597,17 +627,20 @@ free_keys_object(PyDictKeysObject *keys) Py_XDECREF(entries[i].me_key); Py_XDECREF(entries[i].me_value); } -#if PyDict_MAXFREELIST > 0 - if (keys->dk_size == PyDict_MINSIZE && numfreekeys < PyDict_MAXFREELIST) { - keys_free_list[numfreekeys++] = keys; + struct _Py_dict_state *state = get_dict_state(); +#ifdef Py_DEBUG + // free_keys_object() must not be called after _PyDict_Fini() + assert(state->keys_numfree != -1); +#endif + if (keys->dk_size == PyDict_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST) { + state->keys_free_list[state->keys_numfree++] = keys; return; } -#endif - PyObject_FREE(keys); + PyObject_Free(keys); } #define new_values(size) PyMem_NEW(PyObject *, size) -#define free_values(values) PyMem_FREE(values) +#define free_values(values) PyMem_Free(values) /* Consumes a reference to the keys object */ static PyObject * @@ -615,16 +648,18 @@ new_dict(PyDictKeysObject *keys, PyObject **values) { PyDictObject *mp; assert(keys != NULL); -#if PyDict_MAXFREELIST > 0 - if (numfree) { - mp = free_list[--numfree]; + struct _Py_dict_state *state = get_dict_state(); +#ifdef Py_DEBUG + // new_dict() must not be called after _PyDict_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree) { + mp = state->free_list[--state->numfree]; assert (mp != NULL); assert (Py_IS_TYPE(mp, &PyDict_Type)); _Py_NewReference((PyObject *)mp); } - else -#endif - { + else { mp = PyObject_GC_New(PyDictObject, &PyDict_Type); if (mp == NULL) { dictkeys_decref(keys); @@ -662,10 +697,11 @@ new_dict_with_shared_keys(PyDictKeysObject *keys) } -static PyObject * -clone_combined_dict(PyDictObject *orig) +static PyDictKeysObject * +clone_combined_dict_keys(PyDictObject *orig) { - assert(PyDict_CheckExact(orig)); + assert(PyDict_Check(orig)); + assert(Py_TYPE(orig)->tp_iter == (getiterfunc)dict_iter); assert(orig->ma_values == NULL); assert(orig->ma_keys->dk_refcnt == 1); @@ -692,19 +728,6 @@ clone_combined_dict(PyDictObject *orig) } } - PyDictObject *new = (PyDictObject *)new_dict(keys, NULL); - if (new == NULL) { - /* In case of an error, `new_dict()` takes care of - cleaning up `keys`. */ - return NULL; - } - new->ma_used = orig->ma_used; - ASSERT_CONSISTENT(new); - if (_PyObject_GC_IS_TRACKED(orig)) { - /* Maintain tracking. */ - _PyObject_GC_TRACK(new); - } - /* Since we copied the keys table we now have an extra reference in the system. Manually call increment _Py_RefTotal to signal that we have it now; calling dictkeys_incref would be an error as @@ -712,8 +735,7 @@ clone_combined_dict(PyDictObject *orig) #ifdef Py_REF_DEBUG _Py_RefTotal++; #endif - - return (PyObject *)new; + return keys; } PyObject * @@ -835,7 +857,6 @@ lookdict_unicode(PyDictObject *mp, PyObject *key, unicodes is to override __eq__, and for speed we don't cater to that here. */ if (!PyUnicode_CheckExact(key)) { - mp->ma_keys->dk_lookup = lookdict; return lookdict(mp, key, hash, value_addr); } @@ -878,7 +899,6 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, unicodes is to override __eq__, and for speed we don't cater to that here. */ if (!PyUnicode_CheckExact(key)) { - mp->ma_keys->dk_lookup = lookdict; return lookdict(mp, key, hash, value_addr); } @@ -1037,7 +1057,7 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash) static int insertion_resize(PyDictObject *mp) { - return dictresize(mp, GROWTH_RATE(mp)); + return dictresize(mp, calculate_keysize(GROWTH_RATE(mp))); } /* @@ -1062,7 +1082,6 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) if (ix == DKIX_ERROR) goto Fail; - assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); MAINTAIN_TRACKING(mp, key, value); /* When insertion order is different from shared key, we can't share @@ -1084,6 +1103,9 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) if (insertion_resize(mp) < 0) goto Fail; } + if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_lookup != lookdict) { + mp->ma_keys->dk_lookup = lookdict; + } Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); @@ -1195,22 +1217,19 @@ After resizing a table is always combined, but can be resplit by make_keys_shared(). */ static int -dictresize(PyDictObject *mp, Py_ssize_t minsize) +dictresize(PyDictObject *mp, Py_ssize_t newsize) { - Py_ssize_t newsize, numentries; + Py_ssize_t numentries; PyDictKeysObject *oldkeys; PyObject **oldvalues; PyDictKeyEntry *oldentries, *newentries; - /* Find the smallest table size > minused. */ - for (newsize = PyDict_MINSIZE; - newsize < minsize && newsize > 0; - newsize <<= 1) - ; if (newsize <= 0) { PyErr_NoMemory(); return -1; } + assert(IS_POWER_OF_2(newsize)); + assert(newsize >= PyDict_MINSIZE); oldkeys = mp->ma_keys; @@ -1273,16 +1292,18 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize) #ifdef Py_REF_DEBUG _Py_RefTotal--; #endif -#if PyDict_MAXFREELIST > 0 + struct _Py_dict_state *state = get_dict_state(); +#ifdef Py_DEBUG + // dictresize() must not be called after _PyDict_Fini() + assert(state->keys_numfree != -1); +#endif if (oldkeys->dk_size == PyDict_MINSIZE && - numfreekeys < PyDict_MAXFREELIST) + state->keys_numfree < PyDict_MAXFREELIST) { - keys_free_list[numfreekeys++] = oldkeys; + state->keys_free_list[state->keys_numfree++] = oldkeys; } - else -#endif - { - PyObject_FREE(oldkeys); + else { + PyObject_Free(oldkeys); } } @@ -1354,13 +1375,8 @@ _PyDict_NewPresized(Py_ssize_t minused) newsize = max_presize; } else { - Py_ssize_t minsize = ESTIMATE_SIZE(minused); - newsize = PyDict_MINSIZE*2; - while (newsize < minsize) { - newsize <<= 1; - } + newsize = estimate_keysize(minused); } - assert(IS_POWER_OF_2(newsize)); new_keys = new_keys_object(newsize); if (new_keys == NULL) @@ -1381,14 +1397,12 @@ _PyDict_NewPresized(Py_ssize_t minused) PyObject * PyDict_GetItem(PyObject *op, PyObject *key) { - Py_hash_t hash; - Py_ssize_t ix; + if (!PyDict_Check(op)) { + return NULL; + } PyDictObject *mp = (PyDictObject *)op; - PyThreadState *tstate; - PyObject *value; - if (!PyDict_Check(op)) - return NULL; + Py_hash_t hash; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -1399,30 +1413,66 @@ PyDict_GetItem(PyObject *op, PyObject *key) } } - /* We can arrive here with a NULL tstate during initialization: try - running "python -Wi" for an example related to string interning. - Let's just hope that no exception occurs then... This must be - _PyThreadState_GET() and not PyThreadState_Get() because the latter - abort Python if tstate is NULL. */ - tstate = _PyThreadState_GET(); - if (tstate != NULL && tstate->curexc_type != NULL) { - /* preserve the existing exception */ - PyObject *err_type, *err_value, *err_tb; - PyErr_Fetch(&err_type, &err_value, &err_tb); - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); - /* ignore errors */ - PyErr_Restore(err_type, err_value, err_tb); - if (ix < 0) - return NULL; + PyThreadState *tstate = _PyThreadState_GET(); +#ifdef Py_DEBUG + // bpo-40839: Before Python 3.10, it was possible to call PyDict_GetItem() + // with the GIL released. + _Py_EnsureTstateNotNULL(tstate); +#endif + + /* Preserve the existing exception */ + PyObject *exc_type, *exc_value, *exc_tb; + PyObject *value; + Py_ssize_t ix; + + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + + /* Ignore any exception raised by the lookup */ + _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + + if (ix < 0) { + return NULL; } - else { - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); - if (ix < 0) { - PyErr_Clear(); - return NULL; + return value; +} + +Py_ssize_t +_PyDict_GetItemHint(PyDictObject *mp, PyObject *key, + Py_ssize_t hint, PyObject **value) +{ + assert(*value == NULL); + assert(PyDict_CheckExact((PyObject*)mp)); + assert(PyUnicode_CheckExact(key)); + + if (hint >= 0 && hint < mp->ma_keys->dk_nentries) { + PyObject *res = NULL; + + PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint; + if (ep->me_key == key) { + if (mp->ma_keys->dk_lookup == lookdict_split) { + assert(mp->ma_values != NULL); + res = mp->ma_values[(size_t)hint]; + } + else { + res = ep->me_value; + } + if (res != NULL) { + *value = res; + return hint; + } } } - return value; + + Py_hash_t hash = ((PyASCIIObject *) key)->hash; + if (hash == -1) { + hash = PyObject_Hash(key); + if (hash == -1) { + return -1; + } + } + + return (mp->ma_keys->dk_lookup)(mp, key, hash, value); } /* Same as PyDict_GetItemWithError() but with hash supplied by caller. @@ -1933,7 +1983,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(iterable)))) { + if (dictresize(mp, estimate_keysize(PyDict_GET_SIZE(iterable)))) { Py_DECREF(d); return NULL; } @@ -1952,7 +2002,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, ESTIMATE_SIZE(PySet_GET_SIZE(iterable)))) { + if (dictresize(mp, estimate_keysize(PySet_GET_SIZE(iterable)))) { Py_DECREF(d); return NULL; } @@ -2025,13 +2075,15 @@ dict_dealloc(PyDictObject *mp) assert(keys->dk_refcnt == 1); dictkeys_decref(keys); } -#if PyDict_MAXFREELIST > 0 - if (numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) { - free_list[numfree++] = mp; - } - else + struct _Py_dict_state *state = get_dict_state(); +#ifdef Py_DEBUG + // new_dict() must not be called after _PyDict_Fini() + assert(state->numfree != -1); #endif - { + if (state->numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) { + state->free_list[state->numfree++] = mp; + } + else { Py_TYPE(mp)->tp_free((PyObject *)mp); } Py_TRASHCAN_END @@ -2465,8 +2517,8 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) goto Fail; } } - else if (PyDict_GetItemWithError(d, key) == NULL) { - if (PyErr_Occurred() || PyDict_SetItem(d, key, value) < 0) { + else { + if (PyDict_SetDefault(d, key, value) == NULL) { Py_DECREF(key); Py_DECREF(value); goto Fail; @@ -2515,18 +2567,51 @@ dict_merge(PyObject *a, PyObject *b, int override) if (other == mp || other->ma_used == 0) /* a.update(a) or a.update({}); nothing to do */ return 0; - if (mp->ma_used == 0) + if (mp->ma_used == 0) { /* Since the target dict is empty, PyDict_GetItem() * always returns NULL. Setting override to 1 * skips the unnecessary test. */ override = 1; + PyDictKeysObject *okeys = other->ma_keys; + + // If other is clean, combined, and just allocated, just clone it. + if (other->ma_values == NULL && + other->ma_used == okeys->dk_nentries && + (okeys->dk_size == PyDict_MINSIZE || + USABLE_FRACTION(okeys->dk_size/2) < other->ma_used)) { + PyDictKeysObject *keys = clone_combined_dict_keys(other); + if (keys == NULL) { + return -1; + } + + dictkeys_decref(mp->ma_keys); + mp->ma_keys = keys; + if (mp->ma_values != NULL) { + if (mp->ma_values != empty_values) { + free_values(mp->ma_values); + } + mp->ma_values = NULL; + } + + mp->ma_used = other->ma_used; + mp->ma_version_tag = DICT_NEXT_VERSION(); + ASSERT_CONSISTENT(mp); + + if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) { + /* Maintain tracking. */ + _PyObject_GC_TRACK(mp); + } + + return 0; + } + } /* Do one big resize at the start, rather than * incrementally resizing as we insert new items. Expect * that there will be no (or few) overlapping keys. */ if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) { - if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) { + if (dictresize(mp, estimate_keysize(mp->ma_used + other->ma_used))) { return -1; } } @@ -2548,19 +2633,20 @@ dict_merge(PyObject *a, PyObject *b, int override) Py_INCREF(value); if (override == 1) err = insertdict(mp, key, hash, value); - else if (_PyDict_GetItem_KnownHash(a, key, hash) == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(value); - Py_DECREF(key); - return -1; + else { + err = _PyDict_Contains_KnownHash(a, key, hash); + if (err == 0) { + err = insertdict(mp, key, hash, value); + } + else if (err > 0) { + if (override != 0) { + _PyErr_SetKeyError(key); + Py_DECREF(value); + Py_DECREF(key); + return -1; + } + err = 0; } - err = insertdict(mp, key, hash, value); - } - else if (override != 0) { - _PyErr_SetKeyError(key); - Py_DECREF(value); - Py_DECREF(key); - return -1; } Py_DECREF(value); Py_DECREF(key); @@ -2597,17 +2683,15 @@ dict_merge(PyObject *a, PyObject *b, int override) for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { if (override != 1) { - if (PyDict_GetItemWithError(a, key) != NULL) { - if (override != 0) { + status = PyDict_Contains(a, key); + if (status != 0) { + if (status > 0) { + if (override == 0) { + Py_DECREF(key); + continue; + } _PyErr_SetKeyError(key); - Py_DECREF(key); - Py_DECREF(iter); - return -1; } - Py_DECREF(key); - continue; - } - else if (PyErr_Occurred()) { Py_DECREF(key); Py_DECREF(iter); return -1; @@ -2706,12 +2790,13 @@ PyDict_Copy(PyObject *o) return (PyObject *)split_copy; } - if (PyDict_CheckExact(mp) && mp->ma_values == NULL && + if (Py_TYPE(mp)->tp_iter == (getiterfunc)dict_iter && + mp->ma_values == NULL && (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3)) { /* Use fast-copy if: - (1) 'mp' is an instance of a subclassed dict; and + (1) type(mp) doesn't override tp_iter; and (2) 'mp' is not a split-dict; and @@ -2723,13 +2808,31 @@ PyDict_Copy(PyObject *o) operations and copied after that. In cases like this, we defer to PyDict_Merge, which produces a compacted copy. */ - return clone_combined_dict(mp); + PyDictKeysObject *keys = clone_combined_dict_keys(mp); + if (keys == NULL) { + return NULL; + } + PyDictObject *new = (PyDictObject *)new_dict(keys, NULL); + if (new == NULL) { + /* In case of an error, `new_dict()` takes care of + cleaning up `keys`. */ + return NULL; + } + + new->ma_used = mp->ma_used; + ASSERT_CONSISTENT(new); + if (_PyObject_GC_IS_TRACKED(mp)) { + /* Maintain tracking. */ + _PyObject_GC_TRACK(new); + } + + return (PyObject *)new; } copy = PyDict_New(); if (copy == NULL) return NULL; - if (PyDict_Merge(copy, o, 1) == 0) + if (dict_merge(copy, o, 1) == 0) return copy; Py_DECREF(copy); return NULL; @@ -2965,6 +3068,9 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return NULL; } } + if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_lookup != lookdict) { + mp->ma_keys->dk_lookup = lookdict; + } Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); ep0 = DK_ENTRIES(mp->ma_keys); ep = &ep0[mp->ma_keys->dk_nentries]; @@ -3042,12 +3148,13 @@ dict.pop D.pop(k[,d]) -> v, remove specified key and return the corresponding value. -If key is not found, default is returned if given, otherwise KeyError is raised +If the key is not found, return the default if given; otherwise, +raise a KeyError. [clinic start generated code]*/ static PyObject * dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value) -/*[clinic end generated code: output=3abb47b89f24c21c input=eeebec7812190348]*/ +/*[clinic end generated code: output=3abb47b89f24c21c input=e221baa01044c44c]*/ { return _PyDict_Pop((PyObject*)self, key, default_value); } @@ -3302,7 +3409,7 @@ PyDict_Contains(PyObject *op, PyObject *key) /* Internal version of PyDict_Contains used when the hash value is already known */ int -_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash) +_PyDict_Contains_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) { PyDictObject *mp = (PyDictObject *)op; PyObject *value; @@ -3314,6 +3421,16 @@ _PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash) return (ix != DKIX_EMPTY && value != NULL); } +int +_PyDict_ContainsId(PyObject *op, struct _Py_Identifier *key) +{ + PyObject *kv = _PyUnicode_FromId(key); /* borrowed */ + if (kv == NULL) { + return -1; + } + return PyDict_Contains(op, kv); +} + /* Hack to implement "key in dict" */ static PySequenceMethods dict_as_sequence = { 0, /* sq_length */ @@ -3346,16 +3463,15 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) d = (PyDictObject *)self; /* The object has been implicitly tracked by tp_alloc */ - if (type == &PyDict_Type) + if (type == &PyDict_Type) { _PyObject_GC_UNTRACK(d); + } d->ma_used = 0; d->ma_version_tag = DICT_NEXT_VERSION(); - d->ma_keys = new_keys_object(PyDict_MINSIZE); - if (d->ma_keys == NULL) { - Py_DECREF(self); - return NULL; - } + dictkeys_incref(Py_EMPTY_KEYS); + d->ma_keys = Py_EMPTY_KEYS; + d->ma_values = empty_values; ASSERT_CONSISTENT(d); return self; } @@ -3436,7 +3552,8 @@ PyTypeObject PyDict_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS | + _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_MAPPING, /* tp_flags */ dictionary_doc, /* tp_doc */ dict_traverse, /* tp_traverse */ dict_tp_clear, /* tp_clear */ @@ -3459,18 +3576,6 @@ PyTypeObject PyDict_Type = { .tp_vectorcall = dict_vectorcall, }; -PyObject * -_PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key) -{ - PyObject *kv; - kv = _PyUnicode_FromId(key); /* borrowed */ - if (kv == NULL) { - PyErr_Clear(); - return NULL; - } - return PyDict_GetItem(dp, kv); -} - /* For backward compatibility with old dictionary interface */ PyObject * @@ -4129,6 +4234,22 @@ _PyDictView_New(PyObject *dict, PyTypeObject *type) return (PyObject *)dv; } +static PyObject * +dictview_mapping(PyObject *view, void *Py_UNUSED(ignored)) { + assert(view != NULL); + assert(PyDictKeys_Check(view) + || PyDictValues_Check(view) + || PyDictItems_Check(view)); + PyObject *mapping = (PyObject *)((_PyDictViewObject *)view)->dv_dict; + return PyDictProxy_New(mapping); +} + +static PyGetSetDef dictview_getset[] = { + {"mapping", dictview_mapping, (setter)NULL, + "dictionary that this view refers to", NULL}, + {0} +}; + /* TODO(guido): The views objects are not complete: * support more set operations @@ -4338,7 +4459,7 @@ _PyDictView_Intersect(PyObject* self, PyObject *other) /* if other is a set and self is smaller than other, reuse set intersection logic */ - if (Py_IS_TYPE(other, &PySet_Type) && len_self <= PyObject_Size(other)) { + if (PySet_CheckExact(other) && len_self <= PyObject_Size(other)) { _Py_IDENTIFIER(intersection); return _PyObject_CallMethodIdObjArgs(other, &PyId_intersection, self, NULL); } @@ -4416,9 +4537,99 @@ dictviews_or(PyObject* self, PyObject *other) return result; } +static PyObject * +dictitems_xor(PyObject *self, PyObject *other) +{ + assert(PyDictItems_Check(self)); + assert(PyDictItems_Check(other)); + PyObject *d1 = (PyObject *)((_PyDictViewObject *)self)->dv_dict; + PyObject *d2 = (PyObject *)((_PyDictViewObject *)other)->dv_dict; + + PyObject *temp_dict = PyDict_Copy(d1); + if (temp_dict == NULL) { + return NULL; + } + PyObject *result_set = PySet_New(NULL); + if (result_set == NULL) { + Py_CLEAR(temp_dict); + return NULL; + } + + PyObject *key = NULL, *val1 = NULL, *val2 = NULL; + Py_ssize_t pos = 0; + Py_hash_t hash; + + while (_PyDict_Next(d2, &pos, &key, &val2, &hash)) { + Py_INCREF(key); + Py_INCREF(val2); + val1 = _PyDict_GetItem_KnownHash(temp_dict, key, hash); + + int to_delete; + if (val1 == NULL) { + if (PyErr_Occurred()) { + goto error; + } + to_delete = 0; + } + else { + Py_INCREF(val1); + to_delete = PyObject_RichCompareBool(val1, val2, Py_EQ); + if (to_delete < 0) { + goto error; + } + } + + if (to_delete) { + if (_PyDict_DelItem_KnownHash(temp_dict, key, hash) < 0) { + goto error; + } + } + else { + PyObject *pair = PyTuple_Pack(2, key, val2); + if (pair == NULL) { + goto error; + } + if (PySet_Add(result_set, pair) < 0) { + Py_DECREF(pair); + goto error; + } + Py_DECREF(pair); + } + Py_DECREF(key); + Py_XDECREF(val1); + Py_DECREF(val2); + } + key = val1 = val2 = NULL; + + _Py_IDENTIFIER(items); + PyObject *remaining_pairs = _PyObject_CallMethodIdNoArgs(temp_dict, + &PyId_items); + if (remaining_pairs == NULL) { + goto error; + } + if (_PySet_Update(result_set, remaining_pairs) < 0) { + Py_DECREF(remaining_pairs); + goto error; + } + Py_DECREF(temp_dict); + Py_DECREF(remaining_pairs); + return result_set; + +error: + Py_XDECREF(temp_dict); + Py_XDECREF(result_set); + Py_XDECREF(key); + Py_XDECREF(val1); + Py_XDECREF(val2); + return NULL; +} + static PyObject* dictviews_xor(PyObject* self, PyObject *other) { + if (PyDictItems_Check(self) && PyDictItems_Check(other)) { + return dictitems_xor(self, other); + } PyObject *result = dictviews_to_set(self); if (result == NULL) { return NULL; @@ -4552,7 +4763,7 @@ PyTypeObject PyDictKeys_Type = { (getiterfunc)dictkeys_iter, /* tp_iter */ 0, /* tp_iternext */ dictkeys_methods, /* tp_methods */ - 0, + .tp_getset = dictview_getset, }; static PyObject * @@ -4658,7 +4869,7 @@ PyTypeObject PyDictItems_Type = { (getiterfunc)dictitems_iter, /* tp_iter */ 0, /* tp_iternext */ dictitems_methods, /* tp_methods */ - 0, + .tp_getset = dictview_getset, }; static PyObject * @@ -4739,7 +4950,7 @@ PyTypeObject PyDictValues_Type = { (getiterfunc)dictvalues_iter, /* tp_iter */ 0, /* tp_iternext */ dictvalues_methods, /* tp_methods */ - 0, + .tp_getset = dictview_getset, }; static PyObject * @@ -4764,10 +4975,12 @@ PyDictKeysObject * _PyDict_NewKeysForClass(void) { PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE); - if (keys == NULL) + if (keys == NULL) { PyErr_Clear(); - else + } + else { keys->dk_lookup = lookdict_split; + } return keys; } diff --git a/contrib/tools/python3/src/Objects/enumobject.c b/contrib/tools/python3/src/Objects/enumobject.c index bdd0ea5f397..98ece3f13fc 100644 --- a/contrib/tools/python3/src/Objects/enumobject.c +++ b/contrib/tools/python3/src/Objects/enumobject.c @@ -1,6 +1,7 @@ /* enumerate object */ #include "Python.h" +#include "pycore_long.h" // _PyLong_GetOne() #include "pycore_object.h" // _PyObject_GC_TRACK() #include "clinic/enumobject.c.h" @@ -116,7 +117,7 @@ enum_next_long(enumobject *en, PyObject* next_item) } next_index = en->en_longindex; assert(next_index != NULL); - stepped_up = PyNumber_Add(next_index, _PyLong_One); + stepped_up = PyNumber_Add(next_index, _PyLong_GetOne()); if (stepped_up == NULL) { Py_DECREF(next_item); return NULL; @@ -325,6 +326,24 @@ reversed_new_impl(PyTypeObject *type, PyObject *seq) return (PyObject *)ro; } +static PyObject * +reversed_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + assert(PyType_Check(type)); + + if (!_PyArg_NoKwnames("reversed", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("reversed", nargs, 1, 1)) { + return NULL; + } + + return reversed_new_impl((PyTypeObject *)type, args[0]); +} + static void reversed_dealloc(reversedobject *ro) { @@ -456,4 +475,5 @@ PyTypeObject PyReversed_Type = { PyType_GenericAlloc, /* tp_alloc */ reversed_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)reversed_vectorcall, }; diff --git a/contrib/tools/python3/src/Objects/exceptions.c b/contrib/tools/python3/src/Objects/exceptions.c index e67ecfab858..6537a7ccd1e 100644 --- a/contrib/tools/python3/src/Objects/exceptions.c +++ b/contrib/tools/python3/src/Objects/exceptions.c @@ -19,8 +19,13 @@ PyObject *PyExc_IOError = NULL; PyObject *PyExc_WindowsError = NULL; #endif -/* The dict map from errno codes to OSError subclasses */ -static PyObject *errnomap = NULL; + +static struct _Py_exc_state* +get_exc_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->exc_state; +} /* NOTE: If the exception class hierarchy changes, don't forget to update @@ -359,8 +364,6 @@ PyException_SetContext(PyObject *self, PyObject *context) Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context); } -#undef PyExceptionClass_Name - const char * PyExceptionClass_Name(PyObject *ob) { @@ -985,10 +988,11 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) )) goto error; + struct _Py_exc_state *state = get_exc_state(); if (myerrno && PyLong_Check(myerrno) && - errnomap && (PyObject *) type == PyExc_OSError) { + state->errnomap && (PyObject *) type == PyExc_OSError) { PyObject *newtype; - newtype = PyDict_GetItemWithError(errnomap, myerrno); + newtype = PyDict_GetItemWithError(state->errnomap, myerrno); if (newtype) { assert(PyType_Check(newtype)); type = (PyTypeObject *) newtype; @@ -1322,29 +1326,155 @@ SimpleExtendsException(PyExc_RuntimeError, NotImplementedError, /* * NameError extends Exception */ -SimpleExtendsException(PyExc_Exception, NameError, - "Name not found globally."); + +static int +NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"name", NULL}; + PyObject *name = NULL; + + if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) { + return -1; + } + + PyObject *empty_tuple = PyTuple_New(0); + if (!empty_tuple) { + return -1; + } + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist, + &name)) { + Py_DECREF(empty_tuple); + return -1; + } + Py_DECREF(empty_tuple); + + Py_XINCREF(name); + Py_XSETREF(self->name, name); + + return 0; +} + +static int +NameError_clear(PyNameErrorObject *self) +{ + Py_CLEAR(self->name); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +NameError_dealloc(PyNameErrorObject *self) +{ + _PyObject_GC_UNTRACK(self); + NameError_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +NameError_traverse(PyNameErrorObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->name); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +static PyMemberDef NameError_members[] = { + {"name", T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")}, + {NULL} /* Sentinel */ +}; + +static PyMethodDef NameError_methods[] = { + {NULL} /* Sentinel */ +}; + +ComplexExtendsException(PyExc_Exception, NameError, + NameError, 0, + NameError_methods, NameError_members, + 0, BaseException_str, "Name not found globally."); /* * UnboundLocalError extends NameError */ -SimpleExtendsException(PyExc_NameError, UnboundLocalError, + +MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError, "Local name referenced but not bound to a value."); /* * AttributeError extends Exception */ -SimpleExtendsException(PyExc_Exception, AttributeError, - "Attribute not found."); +static int +AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"name", "obj", NULL}; + PyObject *name = NULL; + PyObject *obj = NULL; + + if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) { + return -1; + } + + PyObject *empty_tuple = PyTuple_New(0); + if (!empty_tuple) { + return -1; + } + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist, + &name, &obj)) { + Py_DECREF(empty_tuple); + return -1; + } + Py_DECREF(empty_tuple); + + Py_XINCREF(name); + Py_XSETREF(self->name, name); + + Py_XINCREF(obj); + Py_XSETREF(self->obj, obj); + + return 0; +} + +static int +AttributeError_clear(PyAttributeErrorObject *self) +{ + Py_CLEAR(self->obj); + Py_CLEAR(self->name); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +AttributeError_dealloc(PyAttributeErrorObject *self) +{ + _PyObject_GC_UNTRACK(self); + AttributeError_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->obj); + Py_VISIT(self->name); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +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")}, + {NULL} /* Sentinel */ +}; + +static PyMethodDef AttributeError_methods[] = { + {NULL} /* Sentinel */ +}; + +ComplexExtendsException(PyExc_Exception, AttributeError, + AttributeError, 0, + AttributeError_methods, AttributeError_members, + 0, BaseException_str, "Attribute not found."); /* * SyntaxError extends Exception */ -/* Helper function to customize error message for some syntax errors */ -static int _report_missing_parentheses(PySyntaxErrorObject *self); - static int SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) { @@ -1361,39 +1491,30 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) if (lenargs == 2) { info = PyTuple_GET_ITEM(args, 1); info = PySequence_Tuple(info); - if (!info) + if (!info) { return -1; + } - if (PyTuple_GET_SIZE(info) != 4) { - /* not a very good error message, but it's what Python 2.4 gives */ - PyErr_SetString(PyExc_IndexError, "tuple index out of range"); + self->end_lineno = NULL; + self->end_offset = NULL; + if (!PyArg_ParseTuple(info, "OOOO|OO", + &self->filename, &self->lineno, + &self->offset, &self->text, + &self->end_lineno, &self->end_offset)) { Py_DECREF(info); return -1; } - Py_INCREF(PyTuple_GET_ITEM(info, 0)); - Py_XSETREF(self->filename, PyTuple_GET_ITEM(info, 0)); - - Py_INCREF(PyTuple_GET_ITEM(info, 1)); - Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1)); - - Py_INCREF(PyTuple_GET_ITEM(info, 2)); - Py_XSETREF(self->offset, PyTuple_GET_ITEM(info, 2)); - - Py_INCREF(PyTuple_GET_ITEM(info, 3)); - Py_XSETREF(self->text, PyTuple_GET_ITEM(info, 3)); - + Py_INCREF(self->filename); + Py_INCREF(self->lineno); + Py_INCREF(self->offset); + Py_INCREF(self->text); + Py_XINCREF(self->end_lineno); + Py_XINCREF(self->end_offset); Py_DECREF(info); - /* - * Issue #21669: Custom error for 'print' & 'exec' as statements - * - * Only applies to SyntaxError instances, not to subclasses such - * as TabError or IndentationError (see issue #31161) - */ - if (Py_IS_TYPE(self, (PyTypeObject *)PyExc_SyntaxError) && - self->text && PyUnicode_Check(self->text) && - _report_missing_parentheses(self) < 0) { + if (self->end_lineno != NULL && self->end_offset == NULL) { + PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided"); return -1; } } @@ -1407,6 +1528,8 @@ SyntaxError_clear(PySyntaxErrorObject *self) Py_CLEAR(self->filename); Py_CLEAR(self->lineno); Py_CLEAR(self->offset); + Py_CLEAR(self->end_lineno); + Py_CLEAR(self->end_offset); Py_CLEAR(self->text); Py_CLEAR(self->print_file_and_line); return BaseException_clear((PyBaseExceptionObject *)self); @@ -1427,6 +1550,8 @@ SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg) Py_VISIT(self->filename); Py_VISIT(self->lineno); Py_VISIT(self->offset); + Py_VISIT(self->end_lineno); + Py_VISIT(self->end_offset); Py_VISIT(self->text); Py_VISIT(self->print_file_and_line); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); @@ -1517,6 +1642,10 @@ static PyMemberDef SyntaxError_members[] = { PyDoc_STR("exception offset")}, {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0, PyDoc_STR("exception text")}, + {"end_lineno", T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0, + PyDoc_STR("exception end lineno")}, + {"end_offset", T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0, + PyDoc_STR("exception end offset")}, {"print_file_and_line", T_OBJECT, offsetof(PySyntaxErrorObject, print_file_and_line), 0, PyDoc_STR("exception print_file_and_line")}, @@ -2274,8 +2403,6 @@ SimpleExtendsException(PyExc_Exception, ReferenceError, */ #define MEMERRORS_SAVE 16 -static PyBaseExceptionObject *memerrors_freelist = NULL; -static int memerrors_numfree = 0; static PyObject * MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -2288,16 +2415,21 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return BaseException_new(type, args, kwds); } - if (memerrors_freelist == NULL) + struct _Py_exc_state *state = get_exc_state(); + if (state->memerrors_freelist == NULL) { return BaseException_new(type, args, kwds); + } + /* Fetch object from freelist and revive it */ - self = memerrors_freelist; + self = state->memerrors_freelist; self->args = PyTuple_New(0); /* This shouldn't happen since the empty tuple is persistent */ - if (self->args == NULL) + if (self->args == NULL) { return NULL; - memerrors_freelist = (PyBaseExceptionObject *) self->dict; - memerrors_numfree--; + } + + state->memerrors_freelist = (PyBaseExceptionObject *) self->dict; + state->memerrors_numfree--; self->dict = NULL; _Py_NewReference((PyObject *)self); _PyObject_GC_TRACK(self); @@ -2309,6 +2441,8 @@ MemoryError_dealloc(PyBaseExceptionObject *self) { BaseException_clear(self); + /* If this is a subclass of MemoryError, we don't need to + * do anything in the free-list*/ if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) { Py_TYPE(self)->tp_free((PyObject *)self); return; @@ -2316,12 +2450,14 @@ MemoryError_dealloc(PyBaseExceptionObject *self) _PyObject_GC_UNTRACK(self); - if (memerrors_numfree >= MEMERRORS_SAVE) + struct _Py_exc_state *state = get_exc_state(); + if (state->memerrors_numfree >= MEMERRORS_SAVE) { Py_TYPE(self)->tp_free((PyObject *)self); + } else { - self->dict = (PyObject *) memerrors_freelist; - memerrors_freelist = self; - memerrors_numfree++; + self->dict = (PyObject *) state->memerrors_freelist; + state->memerrors_freelist = self; + state->memerrors_numfree++; } } @@ -2346,11 +2482,11 @@ preallocate_memerrors(void) } static void -free_preallocated_memerrors(void) +free_preallocated_memerrors(struct _Py_exc_state *state) { - while (memerrors_freelist != NULL) { - PyObject *self = (PyObject *) memerrors_freelist; - memerrors_freelist = (PyBaseExceptionObject *) memerrors_freelist->dict; + while (state->memerrors_freelist != NULL) { + PyObject *self = (PyObject *) state->memerrors_freelist; + state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict; Py_TYPE(self)->tp_free((PyObject *)self); } } @@ -2453,6 +2589,13 @@ SimpleExtendsException(PyExc_Warning, BytesWarning, "related to conversion from str or comparing to str."); +/* + * EncodingWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, EncodingWarning, + "Base class for warnings about encodings."); + + /* * ResourceWarning extends Warning */ @@ -2518,8 +2661,10 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, #endif /* MS_WINDOWS */ PyStatus -_PyExc_Init(void) +_PyExc_Init(PyInterpreterState *interp) { + struct _Py_exc_state *state = &interp->exc_state; + #define PRE_INIT(TYPE) \ if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \ @@ -2532,7 +2677,7 @@ _PyExc_Init(void) do { \ PyObject *_code = PyLong_FromLong(CODE); \ assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \ - if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) { \ + if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \ Py_XDECREF(_code); \ return _PyStatus_ERR("errmap insertion problem."); \ } \ @@ -2579,6 +2724,7 @@ _PyExc_Init(void) PRE_INIT(BufferError); PRE_INIT(Warning); PRE_INIT(UserWarning); + PRE_INIT(EncodingWarning); PRE_INIT(DeprecationWarning); PRE_INIT(PendingDeprecationWarning); PRE_INIT(SyntaxWarning); @@ -2608,15 +2754,14 @@ _PyExc_Init(void) PRE_INIT(TimeoutError); if (preallocate_memerrors() < 0) { - return _PyStatus_ERR("Could not preallocate MemoryError object"); + return _PyStatus_NO_MEMORY(); } /* Add exceptions to errnomap */ - if (!errnomap) { - errnomap = PyDict_New(); - if (!errnomap) { - return _PyStatus_ERR("Cannot allocate map from errnos to OSError subclasses"); - } + assert(state->errnomap == NULL); + state->errnomap = PyDict_New(); + if (!state->errnomap) { + return _PyStatus_NO_MEMORY(); } ADD_ERRNO(BlockingIOError, EAGAIN); @@ -2719,6 +2864,7 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) POST_INIT(BufferError); POST_INIT(Warning); POST_INIT(UserWarning); + POST_INIT(EncodingWarning); POST_INIT(DeprecationWarning); POST_INIT(PendingDeprecationWarning); POST_INIT(SyntaxWarning); @@ -2754,10 +2900,11 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) } void -_PyExc_Fini(void) +_PyExc_Fini(PyInterpreterState *interp) { - free_preallocated_memerrors(); - Py_CLEAR(errnomap); + struct _Py_exc_state *state = &interp->exc_state; + free_preallocated_memerrors(state); + Py_CLEAR(state->errnomap); } /* Helper to do the equivalent of "raise X from Y" in C, but always using @@ -2890,189 +3037,3 @@ _PyErr_TrySetFromCause(const char *format, ...) PyErr_Restore(new_exc, new_val, new_tb); return new_val; } - - -/* To help with migration from Python 2, SyntaxError.__init__ applies some - * heuristics to try to report a more meaningful exception when print and - * exec are used like statements. - * - * The heuristics are currently expected to detect the following cases: - * - top level statement - * - statement in a nested suite - * - trailing section of a one line complex statement - * - * They're currently known not to trigger: - * - after a semi-colon - * - * The error message can be a bit odd in cases where the "arguments" are - * completely illegal syntactically, but that isn't worth the hassle of - * fixing. - * - * We also can't do anything about cases that are legal Python 3 syntax - * but mean something entirely different from what they did in Python 2 - * (omitting the arguments entirely, printing items preceded by a unary plus - * or minus, using the stream redirection syntax). - */ - - -// Static helper for setting legacy print error message -static int -_set_legacy_print_statement_msg(PySyntaxErrorObject *self, Py_ssize_t start) -{ - // PRINT_OFFSET is to remove the `print ` prefix from the data. - const int PRINT_OFFSET = 6; - const int STRIP_BOTH = 2; - Py_ssize_t start_pos = start + PRINT_OFFSET; - Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text); - Py_UCS4 semicolon = ';'; - Py_ssize_t end_pos = PyUnicode_FindChar(self->text, semicolon, - start_pos, text_len, 1); - if (end_pos < -1) { - return -1; - } else if (end_pos == -1) { - end_pos = text_len; - } - - PyObject *data = PyUnicode_Substring(self->text, start_pos, end_pos); - if (data == NULL) { - return -1; - } - - PyObject *strip_sep_obj = PyUnicode_FromString(" \t\r\n"); - if (strip_sep_obj == NULL) { - Py_DECREF(data); - return -1; - } - - PyObject *new_data = _PyUnicode_XStrip(data, STRIP_BOTH, strip_sep_obj); - Py_DECREF(data); - Py_DECREF(strip_sep_obj); - if (new_data == NULL) { - return -1; - } - // gets the modified text_len after stripping `print ` - text_len = PyUnicode_GET_LENGTH(new_data); - const char *maybe_end_arg = ""; - if (text_len > 0 && PyUnicode_READ_CHAR(new_data, text_len-1) == ',') { - maybe_end_arg = " end=\" \""; - } - PyObject *error_msg = PyUnicode_FromFormat( - "Missing parentheses in call to 'print'. Did you mean print(%U%s)?", - new_data, maybe_end_arg - ); - Py_DECREF(new_data); - if (error_msg == NULL) - return -1; - - Py_XSETREF(self->msg, error_msg); - return 1; -} - -static int -_check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start) -{ - /* Return values: - * -1: an error occurred - * 0: nothing happened - * 1: the check triggered & the error message was changed - */ - static PyObject *print_prefix = NULL; - static PyObject *exec_prefix = NULL; - Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text), match; - int kind = PyUnicode_KIND(self->text); - const void *data = PyUnicode_DATA(self->text); - - /* Ignore leading whitespace */ - while (start < text_len) { - Py_UCS4 ch = PyUnicode_READ(kind, data, start); - if (!Py_UNICODE_ISSPACE(ch)) - break; - start++; - } - /* Checking against an empty or whitespace-only part of the string */ - if (start == text_len) { - return 0; - } - - /* Check for legacy print statements */ - if (print_prefix == NULL) { - print_prefix = PyUnicode_InternFromString("print "); - if (print_prefix == NULL) { - return -1; - } - } - match = PyUnicode_Tailmatch(self->text, print_prefix, - start, text_len, -1); - if (match == -1) { - return -1; - } - if (match) { - return _set_legacy_print_statement_msg(self, start); - } - - /* Check for legacy exec statements */ - if (exec_prefix == NULL) { - exec_prefix = PyUnicode_InternFromString("exec "); - if (exec_prefix == NULL) { - return -1; - } - } - match = PyUnicode_Tailmatch(self->text, exec_prefix, start, text_len, -1); - if (match == -1) { - return -1; - } - if (match) { - PyObject *msg = PyUnicode_FromString("Missing parentheses in call " - "to 'exec'"); - if (msg == NULL) { - return -1; - } - Py_XSETREF(self->msg, msg); - return 1; - } - /* Fall back to the default error message */ - return 0; -} - -static int -_report_missing_parentheses(PySyntaxErrorObject *self) -{ - Py_UCS4 left_paren = 40; - Py_ssize_t left_paren_index; - Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text); - int legacy_check_result = 0; - - /* Skip entirely if there is an opening parenthesis */ - left_paren_index = PyUnicode_FindChar(self->text, left_paren, - 0, text_len, 1); - if (left_paren_index < -1) { - return -1; - } - if (left_paren_index != -1) { - /* Use default error message for any line with an opening paren */ - return 0; - } - /* Handle the simple statement case */ - legacy_check_result = _check_for_legacy_statements(self, 0); - if (legacy_check_result < 0) { - return -1; - - } - if (legacy_check_result == 0) { - /* Handle the one-line complex statement case */ - Py_UCS4 colon = 58; - Py_ssize_t colon_index; - colon_index = PyUnicode_FindChar(self->text, colon, - 0, text_len, 1); - if (colon_index < -1) { - return -1; - } - if (colon_index >= 0 && colon_index < text_len) { - /* Check again, starting from just after the colon */ - if (_check_for_legacy_statements(self, colon_index+1) < 0) { - return -1; - } - } - } - return 0; -} diff --git a/contrib/tools/python3/src/Objects/fileobject.c b/contrib/tools/python3/src/Objects/fileobject.c index 1c6ecaf82c2..5a2816f5524 100644 --- a/contrib/tools/python3/src/Objects/fileobject.c +++ b/contrib/tools/python3/src/Objects/fileobject.c @@ -223,6 +223,17 @@ PyObject_AsFileDescriptor(PyObject *o) return fd; } +int +_PyLong_FileDescriptor_Converter(PyObject *o, void *ptr) +{ + int fd = PyObject_AsFileDescriptor(o); + if (fd == -1) { + return 0; + } + *(int *)ptr = fd; + return 1; +} + /* ** Py_UniversalNewlineFgets is an fgets variation that understands ** all of \r, \n and \r\n conventions. @@ -314,29 +325,6 @@ typedef struct { int fd; } PyStdPrinter_Object; -static PyObject * -stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews) -{ - PyStdPrinter_Object *self; - - assert(type != NULL && type->tp_alloc != NULL); - - self = (PyStdPrinter_Object *) type->tp_alloc(type, 0); - if (self != NULL) { - self->fd = -1; - } - - return (PyObject *) self; -} - -static int -stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_TypeError, - "cannot create 'stderrprinter' instances"); - return -1; -} - PyObject * PyFile_NewStdPrinter(int fd) { @@ -379,7 +367,7 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) return NULL; } - /* Encode Unicode to UTF-8/surrogateescape */ + /* Encode Unicode to UTF-8/backslashreplace */ str = PyUnicode_AsUTF8AndSize(unicode, &n); if (str == NULL) { PyErr_Clear(); @@ -496,7 +484,7 @@ PyTypeObject PyStdPrinter_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -512,9 +500,9 @@ PyTypeObject PyStdPrinter_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - stdprinter_init, /* tp_init */ + 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ - stdprinter_new, /* tp_new */ + 0, /* tp_new */ PyObject_Del, /* tp_free */ }; diff --git a/contrib/tools/python3/src/Objects/floatobject.c b/contrib/tools/python3/src/Objects/floatobject.c index 6ac6127ae51..2e02f37f4a5 100644 --- a/contrib/tools/python3/src/Objects/floatobject.c +++ b/contrib/tools/python3/src/Objects/floatobject.c @@ -4,7 +4,11 @@ for any kind of float exception without losing portability. */ #include "Python.h" -#include "pycore_dtoa.h" +#include "pycore_dtoa.h" // _Py_dg_dtoa() +#include "pycore_interp.h" // _PyInterpreterState.float_state +#include "pycore_long.h" // _PyLong_GetOne() +#include "pycore_object.h" // _PyObject_Init() +#include "pycore_pystate.h" // _PyInterpreterState_GET() #include #include @@ -16,16 +20,18 @@ class float "PyObject *" "&PyFloat_Type" #include "clinic/floatobject.c.h" -/* Special free list - free_list is a singly-linked list of available PyFloatObjects, linked - via abuse of their ob_type members. -*/ - #ifndef PyFloat_MAXFREELIST -#define PyFloat_MAXFREELIST 100 +# define PyFloat_MAXFREELIST 100 #endif -static int numfree = 0; -static PyFloatObject *free_list = NULL; + + +static struct _Py_float_state * +get_float_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->float_state; +} + double PyFloat_GetMax(void) @@ -59,12 +65,14 @@ static PyStructSequence_Field floatinfo_fields[] = { "is a normalized float"}, {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is " "a normalized"}, - {"dig", "DBL_DIG -- digits"}, + {"dig", "DBL_DIG -- maximum number of decimal digits that " + "can be faithfully represented in a float"}, {"mant_dig", "DBL_MANT_DIG -- mantissa digits"}, {"epsilon", "DBL_EPSILON -- Difference between 1 and the next " "representable float"}, {"radix", "FLT_RADIX -- radix of exponent"}, - {"rounds", "FLT_ROUNDS -- rounding mode"}, + {"rounds", "FLT_ROUNDS -- rounding mode used for arithmetic " + "operations"}, {0} }; @@ -115,17 +123,23 @@ PyFloat_GetInfo(void) PyObject * PyFloat_FromDouble(double fval) { - PyFloatObject *op = free_list; + struct _Py_float_state *state = get_float_state(); + PyFloatObject *op = state->free_list; if (op != NULL) { - free_list = (PyFloatObject *) Py_TYPE(op); - numfree--; - } else { - op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject)); - if (!op) +#ifdef Py_DEBUG + // PyFloat_FromDouble() must not be called after _PyFloat_Fini() + assert(state->numfree != -1); +#endif + state->free_list = (PyFloatObject *) Py_TYPE(op); + state->numfree--; + } + else { + op = PyObject_Malloc(sizeof(PyFloatObject)); + if (!op) { return PyErr_NoMemory(); + } } - /* Inline PyObject_New */ - (void)PyObject_INIT(op, &PyFloat_Type); + _PyObject_Init((PyObject*)op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; } @@ -202,7 +216,7 @@ PyFloat_FromString(PyObject *v) } else { PyErr_Format(PyExc_TypeError, - "float() argument must be a string or a number, not '%.200s'", + "float() argument must be a string or a real number, not '%.200s'", Py_TYPE(v)->tp_name); return NULL; } @@ -217,16 +231,22 @@ static void float_dealloc(PyFloatObject *op) { if (PyFloat_CheckExact(op)) { - if (numfree >= PyFloat_MAXFREELIST) { - PyObject_FREE(op); + struct _Py_float_state *state = get_float_state(); +#ifdef Py_DEBUG + // float_dealloc() must not be called after _PyFloat_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree >= PyFloat_MAXFREELIST) { + PyObject_Free(op); return; } - numfree++; - Py_SET_TYPE(op, (PyTypeObject *)free_list); - free_list = op; + state->numfree++; + Py_SET_TYPE(op, (PyTypeObject *)state->free_list); + state->free_list = op; } - else + else { Py_TYPE(op)->tp_free((PyObject *)op); + } } double @@ -248,7 +268,7 @@ PyFloat_AsDouble(PyObject *op) nb = Py_TYPE(op)->tp_as_number; if (nb == NULL || nb->nb_float == NULL) { if (nb && nb->nb_index) { - PyObject *res = PyNumber_Index(op); + PyObject *res = _PyNumber_Index(op); if (!res) { return -1; } @@ -485,7 +505,7 @@ float_richcompare(PyObject *v, PyObject *w, int op) Py_DECREF(vv); vv = temp; - temp = PyNumber_Or(vv, _PyLong_One); + temp = PyNumber_Or(vv, _PyLong_GetOne()); if (temp == NULL) goto Error; Py_DECREF(vv); @@ -536,7 +556,7 @@ float_richcompare(PyObject *v, PyObject *w, int op) static Py_hash_t float_hash(PyFloatObject *v) { - return _Py_HashDouble(v->ob_fval); + return _Py_HashDouble((PyObject *)v, v->ob_fval); } static PyObject * @@ -1586,7 +1606,7 @@ float_subtype_new(PyTypeObject *type, PyObject *x); /*[clinic input] @classmethod float.__new__ as float_new - x: object(c_default="_PyLong_Zero") = 0 + x: object(c_default="NULL") = 0 / Convert a string or number to a floating point number, if possible. @@ -1594,10 +1614,18 @@ Convert a string or number to a floating point number, if possible. static PyObject * float_new_impl(PyTypeObject *type, PyObject *x) -/*[clinic end generated code: output=ccf1e8dc460ba6ba input=540ee77c204ff87a]*/ +/*[clinic end generated code: output=ccf1e8dc460ba6ba input=f43661b7de03e9d8]*/ { - if (type != &PyFloat_Type) + if (type != &PyFloat_Type) { + if (x == NULL) { + x = _PyLong_GetZero(); + } return float_subtype_new(type, x); /* Wimp out */ + } + + if (x == NULL) { + return PyFloat_FromDouble(0.0); + } /* If it's a string, but not a string subclass, use PyFloat_FromString. */ if (PyUnicode_CheckExact(x)) @@ -1630,6 +1658,24 @@ float_subtype_new(PyTypeObject *type, PyObject *x) return newobj; } +static PyObject * +float_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + if (!_PyArg_NoKwnames("float", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("float", nargs, 0, 1)) { + return NULL; + } + + PyObject *x = nargs >= 1 ? args[0] : NULL; + return float_new_impl((PyTypeObject *)type, x); +} + + /*[clinic input] float.__getnewargs__ [clinic start generated code]*/ @@ -1899,7 +1945,8 @@ PyTypeObject PyFloat_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ float_new__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -1918,9 +1965,10 @@ PyTypeObject PyFloat_Type = { 0, /* tp_init */ 0, /* tp_alloc */ float_new, /* tp_new */ + .tp_vectorcall = (vectorcallfunc)float_vectorcall, }; -int +void _PyFloat_Init(void) { /* We attempt to determine if this machine is using IEEE @@ -1968,41 +2016,52 @@ _PyFloat_Init(void) double_format = detected_double_format; float_format = detected_float_format; +} +int +_PyFloat_InitTypes(void) +{ /* Init float info */ if (FloatInfoType.tp_name == NULL) { if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { - return 0; + return -1; } } - return 1; + return 0; } void -_PyFloat_ClearFreeList(void) +_PyFloat_ClearFreeList(PyInterpreterState *interp) { - PyFloatObject *f = free_list, *next; - for (; f; f = next) { - next = (PyFloatObject*) Py_TYPE(f); - PyObject_FREE(f); - } - free_list = NULL; - numfree = 0; + struct _Py_float_state *state = &interp->float_state; + PyFloatObject *f = state->free_list; + while (f != NULL) { + PyFloatObject *next = (PyFloatObject*) Py_TYPE(f); + PyObject_Free(f); + f = next; + } + state->free_list = NULL; + state->numfree = 0; } void -_PyFloat_Fini(void) +_PyFloat_Fini(PyInterpreterState *interp) { - _PyFloat_ClearFreeList(); + _PyFloat_ClearFreeList(interp); +#ifdef Py_DEBUG + struct _Py_float_state *state = &interp->float_state; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ void _PyFloat_DebugMallocStats(FILE *out) { + struct _Py_float_state *state = get_float_state(); _PyDebugAllocatorStats(out, "free PyFloatObject", - numfree, sizeof(PyFloatObject)); + state->numfree, sizeof(PyFloatObject)); } diff --git a/contrib/tools/python3/src/Objects/frameobject.c b/contrib/tools/python3/src/Objects/frameobject.c index 4ae17bcfc21..d02cf9d3ba9 100644 --- a/contrib/tools/python3/src/Objects/frameobject.c +++ b/contrib/tools/python3/src/Objects/frameobject.c @@ -1,27 +1,34 @@ /* Frame object implementation */ #include "Python.h" -#include "pycore_object.h" -#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() +#include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_moduleobject.h" // _PyModule_GetDict() +#include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "code.h" -#include "frameobject.h" -#include "opcode.h" +#include "frameobject.h" // PyFrameObject +#include "opcode.h" // EXTENDED_ARG #include "structmember.h" // PyMemberDef #define OFF(x) offsetof(PyFrameObject, x) static PyMemberDef frame_memberlist[] = { {"f_back", T_OBJECT, OFF(f_back), READONLY}, - {"f_code", T_OBJECT, OFF(f_code), READONLY|READ_RESTRICTED}, + {"f_code", T_OBJECT, OFF(f_code), READONLY|PY_AUDIT_READ}, {"f_builtins", T_OBJECT, OFF(f_builtins), READONLY}, {"f_globals", T_OBJECT, OFF(f_globals), READONLY}, - {"f_lasti", T_INT, OFF(f_lasti), READONLY}, {"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0}, {"f_trace_opcodes", T_BOOL, OFF(f_trace_opcodes), 0}, {NULL} /* Sentinel */ }; +static struct _Py_frame_state * +get_frame_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->frame; +} + + static PyObject * frame_getlocals(PyFrameObject *f, void *closure) { @@ -35,18 +42,33 @@ int PyFrame_GetLineNumber(PyFrameObject *f) { assert(f != NULL); - if (f->f_trace) { + if (f->f_lineno != 0) { return f->f_lineno; } else { - return PyCode_Addr2Line(f->f_code, f->f_lasti); + return PyCode_Addr2Line(f->f_code, f->f_lasti*sizeof(_Py_CODEUNIT)); } } static PyObject * frame_getlineno(PyFrameObject *f, void *closure) { - return PyLong_FromLong(PyFrame_GetLineNumber(f)); + int lineno = PyFrame_GetLineNumber(f); + if (lineno < 0) { + Py_RETURN_NONE; + } + else { + return PyLong_FromLong(lineno); + } +} + +static PyObject * +frame_getlasti(PyFrameObject *f, void *closure) +{ + if (f->f_lasti < 0) { + return PyLong_FromLong(-1); + } + return PyLong_FromLong(f->f_lasti*sizeof(_Py_CODEUNIT)); } @@ -128,7 +150,7 @@ markblocks(PyCodeObject *code_obj, int len) case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: case JUMP_IF_NOT_EXC_MATCH: - j = get_arg(code, i) / sizeof(_Py_CODEUNIT); + j = get_arg(code, i); assert(j < len); if (blocks[j] == -1 && j < i) { todo = 1; @@ -138,7 +160,7 @@ markblocks(PyCodeObject *code_obj, int len) blocks[i+1] = block_stack; break; case JUMP_ABSOLUTE: - j = get_arg(code, i) / sizeof(_Py_CODEUNIT); + j = get_arg(code, i); assert(j < len); if (blocks[j] == -1 && j < i) { todo = 1; @@ -147,7 +169,7 @@ markblocks(PyCodeObject *code_obj, int len) blocks[j] = block_stack; break; case SETUP_FINALLY: - j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; + j = get_arg(code, i) + i + 1; assert(j < len); except_stack = push_block(block_stack, Except); assert(blocks[j] == -1 || blocks[j] == except_stack); @@ -157,7 +179,7 @@ markblocks(PyCodeObject *code_obj, int len) break; case SETUP_WITH: case SETUP_ASYNC_WITH: - j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; + j = get_arg(code, i) + i + 1; assert(j < len); except_stack = push_block(block_stack, Except); assert(blocks[j] == -1 || blocks[j] == except_stack); @@ -166,7 +188,7 @@ markblocks(PyCodeObject *code_obj, int len) blocks[i+1] = block_stack; break; case JUMP_FORWARD: - j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; + j = get_arg(code, i) + i + 1; assert(j < len); assert(blocks[j] == -1 || blocks[j] == block_stack); blocks[j] = block_stack; @@ -179,7 +201,7 @@ markblocks(PyCodeObject *code_obj, int len) case FOR_ITER: blocks[i+1] = block_stack; block_stack = pop_block(block_stack); - j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; + j = get_arg(code, i) + i + 1; assert(j < len); assert(blocks[j] == -1 || blocks[j] == block_stack); blocks[j] = block_stack; @@ -240,36 +262,22 @@ explain_incompatible_block_stack(int64_t to_stack) static int * marklines(PyCodeObject *code, int len) { + PyCodeAddressRange bounds; + _PyCode_InitAddressRange(code, &bounds); + assert (bounds.ar_end == 0); + int *linestarts = PyMem_New(int, len); if (linestarts == NULL) { return NULL; } - Py_ssize_t size = PyBytes_GET_SIZE(code->co_lnotab) / 2; - unsigned char *p = (unsigned char*)PyBytes_AS_STRING(code->co_lnotab); - int line = code->co_firstlineno; - int addr = 0; - int index = 0; - while (--size >= 0) { - addr += *p++; - if (index*2 < addr) { - linestarts[index++] = line; - } - while (index*2 < addr) { - linestarts[index++] = -1; - if (index >= len) { - break; - } - } - line += (signed char)*p; - p++; - } - if (index < len) { - linestarts[index++] = line; + for (int i = 0; i < len; i++) { + linestarts[i] = -1; } - while (index < len) { - linestarts[index++] = -1; + + while (PyLineTable_NextAddressRange(&bounds)) { + assert(bounds.ar_start/(int)sizeof(_Py_CODEUNIT) < len); + linestarts[bounds.ar_start/sizeof(_Py_CODEUNIT)] = bounds.ar_line; } - assert(index == len); return linestarts; } @@ -291,17 +299,20 @@ first_line_not_before(int *lines, int len, int line) static void frame_stack_pop(PyFrameObject *f) { - PyObject *v = (*--f->f_stacktop); + assert(f->f_stackdepth >= 0); + f->f_stackdepth--; + PyObject *v = f->f_valuestack[f->f_stackdepth]; Py_DECREF(v); } static void frame_block_unwind(PyFrameObject *f) { + assert(f->f_stackdepth >= 0); assert(f->f_iblock > 0); f->f_iblock--; PyTryBlock *b = &f->f_blockstack[f->f_iblock]; - intptr_t delta = (f->f_stacktop - f->f_valuestack) - b->b_level; + intptr_t delta = f->f_stackdepth - b->b_level; while (delta > 0) { frame_stack_pop(f); delta--; @@ -343,33 +354,36 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore return -1; } - /* Upon the 'call' trace event of a new frame, f->f_lasti is -1 and - * f->f_trace is NULL, check first on the first condition. - * Forbidding jumps from the 'call' event of a new frame is a side effect - * of allowing to set f_lineno only from trace functions. */ - if (f->f_lasti == -1) { - PyErr_Format(PyExc_ValueError, + /* + * This code preserves the historical restrictions on + * setting the line number of a frame. + * Jumps are forbidden on a 'return' trace event (except after a yield). + * Jumps from 'call' trace events are also forbidden. + * In addition, jumps are forbidden when not tracing, + * as this is a debugging feature. + */ + switch(f->f_state) { + case FRAME_CREATED: + PyErr_Format(PyExc_ValueError, "can't jump from the 'call' trace event of a new frame"); - return -1; - } - - /* You can only do this from within a trace function, not via - * _getframe or similar hackery. */ - if (!f->f_trace) { - PyErr_Format(PyExc_ValueError, - "f_lineno can only be set by a trace function"); - return -1; - } - - /* Forbid jumps upon a 'return' trace event (except after executing a - * YIELD_VALUE or YIELD_FROM opcode, f_stacktop is not NULL in that case) - * and upon an 'exception' trace event. - * Jumps from 'call' trace events have already been forbidden above for new - * frames, so this check does not change anything for 'call' events. */ - if (f->f_stacktop == NULL) { - PyErr_SetString(PyExc_ValueError, + return -1; + case FRAME_RETURNED: + case FRAME_UNWINDING: + case FRAME_RAISED: + case FRAME_CLEARED: + PyErr_SetString(PyExc_ValueError, "can only jump from a 'line' trace event"); - return -1; + return -1; + case FRAME_EXECUTING: + case FRAME_SUSPENDED: + /* You can only do this from within a trace function, not via + * _getframe or similar hackery. */ + if (!f->f_trace) { + PyErr_Format(PyExc_ValueError, + "f_lineno can only be set by a trace function"); + return -1; + } + break; } int new_lineno; @@ -423,7 +437,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore int64_t target_block_stack = -1; int64_t best_block_stack = -1; int best_addr = -1; - int64_t start_block_stack = blocks[f->f_lasti/sizeof(_Py_CODEUNIT)]; + int64_t start_block_stack = blocks[f->f_lasti]; const char *msg = "cannot find bytecode for specified line"; for (int i = 0; i < len; i++) { if (lines[i] == new_lineno) { @@ -432,7 +446,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore msg = NULL; if (target_block_stack > best_block_stack) { best_block_stack = target_block_stack; - best_addr = i*sizeof(_Py_CODEUNIT); + best_addr = i; } } else if (msg) { @@ -475,8 +489,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore start_block_stack = pop_block(start_block_stack); } - /* Finally set the new f_lineno and f_lasti and return OK. */ - f->f_lineno = new_lineno; + /* Finally set the new f_lasti and return OK. */ + f->f_lineno = 0; f->f_lasti = best_addr; return 0; } @@ -497,11 +511,9 @@ frame_gettrace(PyFrameObject *f, void *closure) static int frame_settrace(PyFrameObject *f, PyObject* v, void *closure) { - /* We rely on f_lineno being accurate when f_trace is set. */ - f->f_lineno = PyFrame_GetLineNumber(f); - - if (v == Py_None) + if (v == Py_None) { v = NULL; + } Py_XINCREF(v); Py_XSETREF(f->f_trace, v); @@ -514,6 +526,7 @@ static PyGetSetDef frame_getsetlist[] = { {"f_lineno", (getter)frame_getlineno, (setter)frame_setlineno, NULL}, {"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL}, + {"f_lasti", (getter)frame_getlasti, NULL, NULL}, {0} }; @@ -561,31 +574,25 @@ static PyGetSetDef frame_getsetlist[] = { /* max value for numfree */ #define PyFrame_MAXFREELIST 200 -#if PyFrame_MAXFREELIST > 0 -static PyFrameObject *free_list = NULL; -static int numfree = 0; /* number of frames currently in free_list */ -#endif - static void _Py_HOT_FUNCTION frame_dealloc(PyFrameObject *f) { - PyObject **p, **valuestack; - PyCodeObject *co; - - if (_PyObject_GC_IS_TRACKED(f)) + if (_PyObject_GC_IS_TRACKED(f)) { _PyObject_GC_UNTRACK(f); + } Py_TRASHCAN_BEGIN(f, frame_dealloc); /* Kill all local variables */ - valuestack = f->f_valuestack; - for (p = f->f_localsplus; p < valuestack; p++) + PyObject **valuestack = f->f_valuestack; + for (PyObject **p = f->f_localsplus; p < valuestack; p++) { Py_CLEAR(*p); + } /* Free stack */ - if (f->f_stacktop != NULL) { - for (p = valuestack; p < f->f_stacktop; p++) - Py_XDECREF(*p); + for (int i = 0; i < f->f_stackdepth; i++) { + Py_XDECREF(f->f_valuestack[i]); } + f->f_stackdepth = 0; Py_XDECREF(f->f_back); Py_DECREF(f->f_builtins); @@ -593,19 +600,24 @@ frame_dealloc(PyFrameObject *f) Py_CLEAR(f->f_locals); Py_CLEAR(f->f_trace); - co = f->f_code; + PyCodeObject *co = f->f_code; if (co->co_zombieframe == NULL) { co->co_zombieframe = f; } -#if PyFrame_MAXFREELIST > 0 - else if (numfree < PyFrame_MAXFREELIST) { - ++numfree; - f->f_back = free_list; - free_list = f; - } -#endif else { - PyObject_GC_Del(f); + struct _Py_frame_state *state = get_frame_state(); +#ifdef Py_DEBUG + // frame_dealloc() must not be called after _PyFrame_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree < PyFrame_MAXFREELIST) { + ++state->numfree; + f->f_back = state->free_list; + state->free_list = f; + } + else { + PyObject_GC_Del(f); + } } Py_DECREF(co); @@ -638,10 +650,8 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg) } /* stack */ - if (f->f_stacktop != NULL) { - for (PyObject **p = f->f_valuestack; p < f->f_stacktop; p++) { - Py_VISIT(*p); - } + for (int i = 0; i < f->f_stackdepth; i++) { + Py_VISIT(f->f_valuestack[i]); } return 0; } @@ -654,9 +664,7 @@ frame_tp_clear(PyFrameObject *f) * frame may also point to this frame, believe itself to still be * active, and try cleaning up this frame again. */ - PyObject **oldtop = f->f_stacktop; - f->f_stacktop = NULL; - f->f_executing = 0; + f->f_state = FRAME_CLEARED; Py_CLEAR(f->f_trace); @@ -667,18 +675,17 @@ frame_tp_clear(PyFrameObject *f) } /* stack */ - if (oldtop != NULL) { - for (PyObject **p = f->f_valuestack; p < oldtop; p++) { - Py_CLEAR(*p); - } + for (int i = 0; i < f->f_stackdepth; i++) { + Py_CLEAR(f->f_valuestack[i]); } + f->f_stackdepth = 0; return 0; } static PyObject * frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) { - if (f->f_executing) { + if (_PyFrame_IsExecuting(f)) { PyErr_SetString(PyExc_RuntimeError, "cannot clear an executing frame"); return NULL; @@ -770,9 +777,7 @@ _Py_IDENTIFIER(__builtins__); static inline PyFrameObject* frame_alloc(PyCodeObject *code) { - PyFrameObject *f; - - f = code->co_zombieframe; + PyFrameObject *f = code->co_zombieframe; if (f != NULL) { code->co_zombieframe = NULL; _Py_NewReference((PyObject *)f); @@ -783,21 +788,23 @@ frame_alloc(PyCodeObject *code) Py_ssize_t ncells = PyTuple_GET_SIZE(code->co_cellvars); Py_ssize_t nfrees = PyTuple_GET_SIZE(code->co_freevars); Py_ssize_t extras = code->co_stacksize + code->co_nlocals + ncells + nfrees; -#if PyFrame_MAXFREELIST > 0 - if (free_list == NULL) -#endif + struct _Py_frame_state *state = get_frame_state(); + if (state->free_list == NULL) { f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras); if (f == NULL) { return NULL; } } -#if PyFrame_MAXFREELIST > 0 else { - assert(numfree > 0); - --numfree; - f = free_list; - free_list = free_list->f_back; +#ifdef Py_DEBUG + // frame_alloc() must not be called after _PyFrame_Fini() + assert(state->numfree != -1); +#endif + assert(state->numfree > 0); + --state->numfree; + f = state->free_list; + state->free_list = state->free_list->f_back; if (Py_SIZE(f) < extras) { PyFrameObject *new_f = PyObject_GC_Resize(PyFrameObject, f, extras); if (new_f == NULL) { @@ -808,132 +815,72 @@ frame_alloc(PyCodeObject *code) } _Py_NewReference((PyObject *)f); } -#endif - f->f_code = code; extras = code->co_nlocals + ncells + nfrees; f->f_valuestack = f->f_localsplus + extras; - for (Py_ssize_t i=0; if_localsplus[i] = NULL; } - f->f_locals = NULL; - f->f_trace = NULL; return f; } -static inline PyObject * -frame_get_builtins(PyFrameObject *back, PyObject *globals) -{ - PyObject *builtins; - - if (back != NULL && back->f_globals == globals) { - /* If we share the globals, we share the builtins. - Save a lookup and a call. */ - builtins = back->f_builtins; - assert(builtins != NULL); - Py_INCREF(builtins); - return builtins; - } - - builtins = _PyDict_GetItemIdWithError(globals, &PyId___builtins__); - if (builtins != NULL && PyModule_Check(builtins)) { - builtins = PyModule_GetDict(builtins); - assert(builtins != NULL); - } - if (builtins != NULL) { - Py_INCREF(builtins); - return builtins; - } - - if (PyErr_Occurred()) { - return NULL; - } - - /* No builtins! Make up a minimal one. - Give them 'None', at least. */ - builtins = PyDict_New(); - if (builtins == NULL) { - return NULL; - } - if (PyDict_SetItemString(builtins, "None", Py_None) < 0) { - Py_DECREF(builtins); - return NULL; - } - return builtins; -} - - PyFrameObject* _Py_HOT_FUNCTION -_PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code, - PyObject *globals, PyObject *locals) +_PyFrame_New_NoTrack(PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals) { -#ifdef Py_DEBUG - if (code == NULL || globals == NULL || !PyDict_Check(globals) || - (locals != NULL && !PyMapping_Check(locals))) { - PyErr_BadInternalCall(); - return NULL; - } -#endif - - PyFrameObject *back = tstate->frame; - PyObject *builtins = frame_get_builtins(back, globals); - if (builtins == NULL) { - return NULL; - } + assert(con != NULL); + assert(con->fc_globals != NULL); + assert(con->fc_builtins != NULL); + assert(con->fc_code != NULL); + assert(locals == NULL || PyMapping_Check(locals)); - PyFrameObject *f = frame_alloc(code); + PyFrameObject *f = frame_alloc((PyCodeObject *)con->fc_code); if (f == NULL) { - Py_DECREF(builtins); return NULL; } - f->f_stacktop = f->f_valuestack; - f->f_builtins = builtins; - Py_XINCREF(back); - f->f_back = back; - Py_INCREF(code); - Py_INCREF(globals); - f->f_globals = globals; - /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */ - if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) == - (CO_NEWLOCALS | CO_OPTIMIZED)) - ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */ - else if (code->co_flags & CO_NEWLOCALS) { - locals = PyDict_New(); - if (locals == NULL) { - Py_DECREF(f); - return NULL; - } - f->f_locals = locals; - } - else { - if (locals == NULL) - locals = globals; - Py_INCREF(locals); - f->f_locals = locals; - } - + f->f_back = (PyFrameObject*)Py_XNewRef(tstate->frame); + f->f_code = (PyCodeObject *)Py_NewRef(con->fc_code); + f->f_builtins = Py_NewRef(con->fc_builtins); + f->f_globals = Py_NewRef(con->fc_globals); + f->f_locals = Py_XNewRef(locals); + // f_valuestack initialized by frame_alloc() + f->f_trace = NULL; + f->f_stackdepth = 0; + f->f_trace_lines = 1; + f->f_trace_opcodes = 0; + f->f_gen = NULL; f->f_lasti = -1; - f->f_lineno = code->co_firstlineno; + f->f_lineno = 0; f->f_iblock = 0; - f->f_executing = 0; - f->f_gen = NULL; - f->f_trace_opcodes = 0; - f->f_trace_lines = 1; - - assert(f->f_code != NULL); - + f->f_state = FRAME_CREATED; + // f_blockstack and f_localsplus initialized by frame_alloc() return f; } +/* Legacy API */ PyFrameObject* PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) { - PyFrameObject *f = _PyFrame_New_NoTrack(tstate, code, globals, locals); - if (f) + PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref + if (builtins == NULL) { + return NULL; + } + PyFrameConstructor desc = { + .fc_globals = globals, + .fc_builtins = builtins, + .fc_name = code->co_name, + .fc_qualname = code->co_name, + .fc_code = (PyObject *)code, + .fc_defaults = NULL, + .fc_kwdefaults = NULL, + .fc_closure = NULL + }; + PyFrameObject *f = _PyFrame_New_NoTrack(tstate, &desc, locals); + if (f) { _PyObject_GC_TRACK(f); + } return f; } @@ -1177,34 +1124,36 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) /* Clear out the free list */ void -_PyFrame_ClearFreeList(void) +_PyFrame_ClearFreeList(PyInterpreterState *interp) { -#if PyFrame_MAXFREELIST > 0 - while (free_list != NULL) { - PyFrameObject *f = free_list; - free_list = free_list->f_back; + struct _Py_frame_state *state = &interp->frame; + while (state->free_list != NULL) { + PyFrameObject *f = state->free_list; + state->free_list = state->free_list->f_back; PyObject_GC_Del(f); - --numfree; + --state->numfree; } - assert(numfree == 0); -#endif + assert(state->numfree == 0); } void -_PyFrame_Fini(void) +_PyFrame_Fini(PyInterpreterState *interp) { - _PyFrame_ClearFreeList(); + _PyFrame_ClearFreeList(interp); +#ifdef Py_DEBUG + struct _Py_frame_state *state = &interp->frame; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ void _PyFrame_DebugMallocStats(FILE *out) { -#if PyFrame_MAXFREELIST > 0 + struct _Py_frame_state *state = get_frame_state(); _PyDebugAllocatorStats(out, "free PyFrameObject", - numfree, sizeof(PyFrameObject)); -#endif + state->numfree, sizeof(PyFrameObject)); } @@ -1227,3 +1176,21 @@ PyFrame_GetBack(PyFrameObject *frame) Py_XINCREF(back); return back; } + +PyObject* +_PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) +{ + PyObject *builtins = _PyDict_GetItemIdWithError(globals, &PyId___builtins__); + if (builtins) { + if (PyModule_Check(builtins)) { + builtins = _PyModule_GetDict(builtins); + assert(builtins != NULL); + } + return builtins; + } + if (PyErr_Occurred()) { + return NULL; + } + + return _PyEval_GetBuiltins(tstate); +} diff --git a/contrib/tools/python3/src/Objects/funcobject.c b/contrib/tools/python3/src/Objects/funcobject.c index 2c60275d906..801478ade22 100644 --- a/contrib/tools/python3/src/Objects/funcobject.c +++ b/contrib/tools/python3/src/Objects/funcobject.c @@ -2,77 +2,94 @@ /* Function object implementation */ #include "Python.h" -#include "pycore_object.h" -#include "pycore_tupleobject.h" -#include "code.h" +#include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pyerrors.h" // _PyErr_Occurred() #include "structmember.h" // PyMemberDef PyObject * PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname) { - PyFunctionObject *op; - PyObject *doc, *consts, *module; - static PyObject *__name__ = NULL; + assert(globals != NULL); + assert(PyDict_Check(globals)); + Py_INCREF(globals); - if (__name__ == NULL) { - __name__ = PyUnicode_InternFromString("__name__"); - if (__name__ == NULL) - return NULL; + PyThreadState *tstate = _PyThreadState_GET(); + + PyCodeObject *code_obj = (PyCodeObject *)code; + Py_INCREF(code_obj); + + PyObject *name = code_obj->co_name; + assert(name != NULL); + Py_INCREF(name); + if (!qualname) { + qualname = name; } + Py_INCREF(qualname); - /* __module__: If module name is in globals, use it. - Otherwise, use None. */ - module = PyDict_GetItemWithError(globals, __name__); - if (module) { - Py_INCREF(module); + PyObject *consts = code_obj->co_consts; + assert(PyTuple_Check(consts)); + PyObject *doc; + if (PyTuple_Size(consts) >= 1) { + doc = PyTuple_GetItem(consts, 0); + if (!PyUnicode_Check(doc)) { + doc = Py_None; + } } - else if (PyErr_Occurred()) { - return NULL; + else { + doc = Py_None; + } + Py_INCREF(doc); + + // __module__: Use globals['__name__'] if it exists, or NULL. + _Py_IDENTIFIER(__name__); + PyObject *module = _PyDict_GetItemIdWithError(globals, &PyId___name__); + PyObject *builtins = NULL; + if (module == NULL && _PyErr_Occurred(tstate)) { + goto error; + } + Py_XINCREF(module); + + builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref + if (builtins == NULL) { + goto error; } + Py_INCREF(builtins); - op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); + PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); if (op == NULL) { - Py_XDECREF(module); - return NULL; + goto error; } /* Note: No failures from this point on, since func_dealloc() does not expect a partially-created object. */ - op->func_weakreflist = NULL; - Py_INCREF(code); - op->func_code = code; - Py_INCREF(globals); op->func_globals = globals; - op->func_name = ((PyCodeObject *)code)->co_name; - Py_INCREF(op->func_name); - op->func_defaults = NULL; /* No default arguments */ - op->func_kwdefaults = NULL; /* No keyword only defaults */ + op->func_builtins = builtins; + op->func_name = name; + op->func_qualname = qualname; + op->func_code = (PyObject*)code_obj; + op->func_defaults = NULL; // No default positional arguments + op->func_kwdefaults = NULL; // No default keyword arguments op->func_closure = NULL; - op->vectorcall = _PyFunction_Vectorcall; - op->func_module = module; - - consts = ((PyCodeObject *)code)->co_consts; - if (PyTuple_Size(consts) >= 1) { - doc = PyTuple_GetItem(consts, 0); - if (!PyUnicode_Check(doc)) - doc = Py_None; - } - else - doc = Py_None; - Py_INCREF(doc); op->func_doc = doc; - op->func_dict = NULL; + op->func_weakreflist = NULL; + op->func_module = module; op->func_annotations = NULL; - - if (qualname) - op->func_qualname = qualname; - else - op->func_qualname = op->func_name; - Py_INCREF(op->func_qualname); + op->vectorcall = _PyFunction_Vectorcall; _PyObject_GC_TRACK(op); return (PyObject *)op; + +error: + Py_DECREF(globals); + Py_DECREF(code_obj); + Py_DECREF(name); + Py_DECREF(qualname); + Py_DECREF(doc); + Py_XDECREF(module); + Py_XDECREF(builtins); + return NULL; } PyObject * @@ -204,6 +221,37 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure) return 0; } +static PyObject * +func_get_annotation_dict(PyFunctionObject *op) +{ + if (op->func_annotations == NULL) { + return NULL; + } + if (PyTuple_CheckExact(op->func_annotations)) { + PyObject *ann_tuple = op->func_annotations; + PyObject *ann_dict = PyDict_New(); + if (ann_dict == NULL) { + return NULL; + } + + assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0); + + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) { + int err = PyDict_SetItem(ann_dict, + PyTuple_GET_ITEM(ann_tuple, i), + PyTuple_GET_ITEM(ann_tuple, i + 1)); + + if (err < 0) { + return NULL; + } + } + Py_SETREF(op->func_annotations, ann_dict); + } + Py_INCREF(op->func_annotations); + assert(PyDict_Check(op->func_annotations)); + return op->func_annotations; +} + PyObject * PyFunction_GetAnnotations(PyObject *op) { @@ -211,7 +259,7 @@ PyFunction_GetAnnotations(PyObject *op) PyErr_BadInternalCall(); return NULL; } - return ((PyFunctionObject *) op) -> func_annotations; + return func_get_annotation_dict((PyFunctionObject *)op); } int @@ -244,6 +292,7 @@ static PyMemberDef func_memberlist[] = { {"__doc__", T_OBJECT, OFF(func_doc), 0}, {"__globals__", T_OBJECT, OFF(func_globals), READONLY}, {"__module__", T_OBJECT, OFF(func_module), 0}, + {"__builtins__", T_OBJECT, OFF(func_builtins), READONLY}, {NULL} /* Sentinel */ }; @@ -425,8 +474,7 @@ func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_annotations == NULL) return NULL; } - Py_INCREF(op->func_annotations); - return op->func_annotations; + return func_get_annotation_dict(op); } static int @@ -550,9 +598,9 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code, globals); - if (newfunc == NULL) + if (newfunc == NULL) { return NULL; - + } if (name != Py_None) { Py_INCREF(name); Py_SETREF(newfunc->func_name, name); @@ -574,15 +622,16 @@ func_clear(PyFunctionObject *op) { Py_CLEAR(op->func_code); Py_CLEAR(op->func_globals); - Py_CLEAR(op->func_module); + Py_CLEAR(op->func_builtins); Py_CLEAR(op->func_name); + Py_CLEAR(op->func_qualname); + Py_CLEAR(op->func_module); Py_CLEAR(op->func_defaults); Py_CLEAR(op->func_kwdefaults); Py_CLEAR(op->func_doc); Py_CLEAR(op->func_dict); Py_CLEAR(op->func_closure); Py_CLEAR(op->func_annotations); - Py_CLEAR(op->func_qualname); return 0; } @@ -601,7 +650,7 @@ static PyObject* func_repr(PyFunctionObject *op) { return PyUnicode_FromFormat("", - op->func_qualname, op); + op->func_qualname, op); } static int @@ -609,6 +658,7 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg) { Py_VISIT(f->func_code); Py_VISIT(f->func_globals); + Py_VISIT(f->func_builtins); Py_VISIT(f->func_module); Py_VISIT(f->func_defaults); Py_VISIT(f->func_kwdefaults); @@ -676,6 +726,50 @@ PyTypeObject PyFunction_Type = { }; +static int +functools_copy_attr(PyObject *wrapper, PyObject *wrapped, PyObject *name) +{ + PyObject *value = PyObject_GetAttr(wrapped, name); + if (value == NULL) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + return 0; + } + return -1; + } + + int res = PyObject_SetAttr(wrapper, name, value); + Py_DECREF(value); + return res; +} + +// Similar to functools.wraps(wrapper, wrapped) +static int +functools_wraps(PyObject *wrapper, PyObject *wrapped) +{ +#define COPY_ATTR(ATTR) \ + do { \ + _Py_IDENTIFIER(ATTR); \ + PyObject *attr = _PyUnicode_FromId(&PyId_ ## ATTR); \ + if (attr == NULL) { \ + return -1; \ + } \ + if (functools_copy_attr(wrapper, wrapped, attr) < 0) { \ + return -1; \ + } \ + } while (0) \ + + COPY_ATTR(__module__); + COPY_ATTR(__name__); + COPY_ATTR(__qualname__); + COPY_ATTR(__doc__); + COPY_ATTR(__annotations__); + return 0; + +#undef COPY_ATTR +} + + /* Class method object */ /* A class method receives the class as implicit first argument, @@ -742,7 +836,7 @@ cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) type = (PyObject *)(Py_TYPE(obj)); if (Py_TYPE(cm->cm_callable)->tp_descr_get != NULL) { return Py_TYPE(cm->cm_callable)->tp_descr_get(cm->cm_callable, type, - NULL); + type); } return PyMethod_New(cm->cm_callable, type); } @@ -759,11 +853,16 @@ cm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; Py_INCREF(callable); Py_XSETREF(cm->cm_callable, callable); + + if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) { + return -1; + } return 0; } static PyMemberDef cm_memberlist[] = { {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY}, + {"__wrapped__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY}, {NULL} /* Sentinel */ }; @@ -782,13 +881,17 @@ cm_get___isabstractmethod__(classmethod *cm, void *closure) static PyGetSetDef cm_getsetlist[] = { {"__isabstractmethod__", - (getter)cm_get___isabstractmethod__, NULL, - NULL, - NULL}, + (getter)cm_get___isabstractmethod__, NULL, NULL, NULL}, {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL}, {NULL} /* Sentinel */ }; +static PyObject* +cm_repr(classmethod *cm) +{ + return PyUnicode_FromFormat("", cm->cm_callable); +} + PyDoc_STRVAR(classmethod_doc, "classmethod(function) -> method\n\ \n\ @@ -821,7 +924,7 @@ PyTypeObject PyClassMethod_Type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ + (reprfunc)cm_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ @@ -941,11 +1044,23 @@ sm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; Py_INCREF(callable); Py_XSETREF(sm->sm_callable, callable); + + if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) { + return -1; + } return 0; } +static PyObject* +sm_call(PyObject *callable, PyObject *args, PyObject *kwargs) +{ + staticmethod *sm = (staticmethod *)callable; + return PyObject_Call(sm->sm_callable, args, kwargs); +} + static PyMemberDef sm_memberlist[] = { {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY}, + {"__wrapped__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY}, {NULL} /* Sentinel */ }; @@ -964,13 +1079,17 @@ sm_get___isabstractmethod__(staticmethod *sm, void *closure) static PyGetSetDef sm_getsetlist[] = { {"__isabstractmethod__", - (getter)sm_get___isabstractmethod__, NULL, - NULL, - NULL}, + (getter)sm_get___isabstractmethod__, NULL, NULL, NULL}, {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL}, {NULL} /* Sentinel */ }; +static PyObject* +sm_repr(staticmethod *sm) +{ + return PyUnicode_FromFormat("", sm->sm_callable); +} + PyDoc_STRVAR(staticmethod_doc, "staticmethod(function) -> method\n\ \n\ @@ -1001,12 +1120,12 @@ PyTypeObject PyStaticMethod_Type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ + (reprfunc)sm_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ - 0, /* tp_call */ + sm_call, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ diff --git a/contrib/tools/python3/src/Objects/genericaliasobject.c b/contrib/tools/python3/src/Objects/genericaliasobject.c index acbb01cfef9..dbe5d89b739 100644 --- a/contrib/tools/python3/src/Objects/genericaliasobject.c +++ b/contrib/tools/python3/src/Objects/genericaliasobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_object.h" +#include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check #include "structmember.h" // PyMemberDef typedef struct { @@ -24,7 +25,7 @@ ga_dealloc(PyObject *self) Py_XDECREF(alias->origin); Py_XDECREF(alias->args); Py_XDECREF(alias->parameters); - self->ob_type->tp_free(self); + Py_TYPE(self)->tp_free(self); } static int @@ -197,8 +198,8 @@ tuple_add(PyObject *self, Py_ssize_t len, PyObject *item) return 0; } -static PyObject * -make_parameters(PyObject *args) +PyObject * +_Py_make_parameters(PyObject *args) { Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t len = nargs; @@ -293,18 +294,10 @@ subs_tvars(PyObject *obj, PyObject *params, PyObject **argitems) return obj; } -static PyObject * -ga_getitem(PyObject *self, PyObject *item) +PyObject * +_Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObject *item) { - gaobject *alias = (gaobject *)self; - // do a lookup for __parameters__ so it gets populated (if not already) - if (alias->parameters == NULL) { - alias->parameters = make_parameters(alias->args); - if (alias->parameters == NULL) { - return NULL; - } - } - Py_ssize_t nparams = PyTuple_GET_SIZE(alias->parameters); + Py_ssize_t nparams = PyTuple_GET_SIZE(parameters); if (nparams == 0) { return PyErr_Format(PyExc_TypeError, "There are no type variables left in %R", @@ -319,32 +312,32 @@ ga_getitem(PyObject *self, PyObject *item) nitems > nparams ? "many" : "few", self); } - /* Replace all type variables (specified by alias->parameters) + /* Replace all type variables (specified by parameters) with corresponding values specified by argitems. t = list[T]; t[int] -> newargs = [int] t = dict[str, T]; t[int] -> newargs = [str, int] t = dict[T, list[S]]; t[str, int] -> newargs = [str, list[int]] */ - Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args); + Py_ssize_t nargs = PyTuple_GET_SIZE(args); PyObject *newargs = PyTuple_New(nargs); if (newargs == NULL) { return NULL; } for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { - PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg); + PyObject *arg = PyTuple_GET_ITEM(args, iarg); int typevar = is_typevar(arg); if (typevar < 0) { Py_DECREF(newargs); return NULL; } if (typevar) { - Py_ssize_t iparam = tuple_index(alias->parameters, nparams, arg); + Py_ssize_t iparam = tuple_index(parameters, nparams, arg); assert(iparam >= 0); arg = argitems[iparam]; Py_INCREF(arg); } else { - arg = subs_tvars(arg, alias->parameters, argitems); + arg = subs_tvars(arg, parameters, argitems); if (arg == NULL) { Py_DECREF(newargs); return NULL; @@ -353,6 +346,26 @@ ga_getitem(PyObject *self, PyObject *item) PyTuple_SET_ITEM(newargs, iarg, arg); } + return newargs; +} + +static PyObject * +ga_getitem(PyObject *self, PyObject *item) +{ + gaobject *alias = (gaobject *)self; + // Populate __parameters__ if needed. + if (alias->parameters == NULL) { + alias->parameters = _Py_make_parameters(alias->args); + if (alias->parameters == NULL) { + return NULL; + } + } + + PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item); + if (newargs == NULL) { + return NULL; + } + PyObject *res = Py_GenericAlias(alias->origin, newargs); Py_DECREF(newargs); @@ -430,8 +443,7 @@ ga_getattro(PyObject *self, PyObject *name) static PyObject * ga_richcompare(PyObject *a, PyObject *b, int op) { - if (!PyObject_TypeCheck(a, &Py_GenericAliasType) || - !PyObject_TypeCheck(b, &Py_GenericAliasType) || + if (!_PyGenericAlias_Check(b) || (op != Py_EQ && op != Py_NE)) { Py_RETURN_NOTIMPLEMENTED; @@ -551,7 +563,7 @@ ga_parameters(PyObject *self, void *unused) { gaobject *alias = (gaobject *)self; if (alias->parameters == NULL) { - alias->parameters = make_parameters(alias->args); + alias->parameters = _Py_make_parameters(alias->args); if (alias->parameters == NULL) { return NULL; } @@ -610,6 +622,10 @@ ga_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)self; } +static PyNumberMethods ga_as_number = { + .nb_or = _Py_union_type_or, // Add __or__ function +}; + // TODO: // - argument clinic? // - __doc__? @@ -623,6 +639,7 @@ PyTypeObject Py_GenericAliasType = { .tp_basicsize = sizeof(gaobject), .tp_dealloc = ga_dealloc, .tp_repr = ga_repr, + .tp_as_number = &ga_as_number, // allow X | Y of GenericAlias objs .tp_as_mapping = &ga_as_mapping, .tp_hash = ga_hash, .tp_call = ga_call, diff --git a/contrib/tools/python3/src/Objects/genobject.c b/contrib/tools/python3/src/Objects/genobject.c index 5ba4de82ea7..33fc4a59249 100644 --- a/contrib/tools/python3/src/Objects/genobject.c +++ b/contrib/tools/python3/src/Objects/genobject.c @@ -47,7 +47,7 @@ _PyGen_Finalize(PyObject *self) PyObject *res = NULL; PyObject *error_type, *error_value, *error_traceback; - if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) { + if (gen->gi_frame == NULL || _PyFrameHasCompleted(gen->gi_frame)) { /* Generator isn't paused, so no need to close */ return; } @@ -136,14 +136,29 @@ gen_dealloc(PyGenObject *gen) PyObject_GC_Del(gen); } -static PyObject * -gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) +static PySendResult +gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, + int exc, int closing) { PyThreadState *tstate = _PyThreadState_GET(); PyFrameObject *f = gen->gi_frame; PyObject *result; - if (gen->gi_running) { + *presult = NULL; + if (f != NULL && f->f_lasti < 0 && arg && arg != Py_None) { + const char *msg = "can't send non-None value to a " + "just-started generator"; + if (PyCoro_CheckExact(gen)) { + msg = NON_INIT_CORO_MSG; + } + else if (PyAsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a " + "just-started async generator"; + } + PyErr_SetString(PyExc_TypeError, msg); + return PYGEN_ERROR; + } + if (f != NULL && _PyFrame_IsExecuting(f)) { const char *msg = "generator already executing"; if (PyCoro_CheckExact(gen)) { msg = "coroutine already executing"; @@ -152,9 +167,9 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) msg = "async generator already executing"; } PyErr_SetString(PyExc_ValueError, msg); - return NULL; + return PYGEN_ERROR; } - if (f == NULL || f->f_stacktop == NULL) { + if (f == NULL || _PyFrameHasCompleted(f)) { if (PyCoro_CheckExact(gen) && !closing) { /* `gen` is an exhausted coroutine: raise an error, except when called from gen_close(), which should @@ -165,37 +180,21 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) } else if (arg && !exc) { /* `gen` is an exhausted generator: - only set exception if called from send(). */ - if (PyAsyncGen_CheckExact(gen)) { - PyErr_SetNone(PyExc_StopAsyncIteration); - } - else { - PyErr_SetNone(PyExc_StopIteration); - } + only return value if called from send(). */ + *presult = Py_None; + Py_INCREF(*presult); + return PYGEN_RETURN; } - return NULL; + return PYGEN_ERROR; } - if (f->f_lasti == -1) { - if (arg && arg != Py_None) { - const char *msg = "can't send non-None value to a " - "just-started generator"; - if (PyCoro_CheckExact(gen)) { - msg = NON_INIT_CORO_MSG; - } - else if (PyAsyncGen_CheckExact(gen)) { - msg = "can't send non-None value to a " - "just-started async generator"; - } - PyErr_SetString(PyExc_TypeError, msg); - return NULL; - } - } else { - /* Push arg onto the frame's value stack */ - result = arg ? arg : Py_None; - Py_INCREF(result); - *(f->f_stacktop++) = result; - } + assert(_PyFrame_IsRunnable(f)); + assert(f->f_lasti >= 0 || ((unsigned char *)PyBytes_AS_STRING(f->f_code->co_code))[0] == GEN_START); + /* Push arg onto the frame's value stack */ + result = arg ? arg : Py_None; + Py_INCREF(result); + gen->gi_frame->f_valuestack[gen->gi_frame->f_stackdepth] = result; + gen->gi_frame->f_stackdepth++; /* Generators always return to their most recent caller, not * necessarily their creator. */ @@ -203,7 +202,6 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) assert(f->f_back == NULL); f->f_back = tstate->frame; - gen->gi_running = 1; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; @@ -215,7 +213,6 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) result = _PyEval_EvalFrame(tstate, f, exc); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; - gen->gi_running = 0; /* Don't keep the reference to f_back any longer than necessary. It * may keep a chain of frames alive or it could create a reference @@ -225,53 +222,73 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ - if (result && f->f_stacktop == NULL) { - if (result == Py_None) { - /* Delay exception instantiation if we can */ - if (PyAsyncGen_CheckExact(gen)) { - PyErr_SetNone(PyExc_StopAsyncIteration); - } - else { - PyErr_SetNone(PyExc_StopIteration); - } + if (result) { + if (!_PyFrameHasCompleted(f)) { + *presult = result; + return PYGEN_NEXT; } - else { - /* Async generators cannot return anything but None */ - assert(!PyAsyncGen_CheckExact(gen)); - _PyGen_SetStopIterationValue(result); + assert(result == Py_None || !PyAsyncGen_CheckExact(gen)); + if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) { + /* Return NULL if called by gen_iternext() */ + Py_CLEAR(result); } - Py_CLEAR(result); } - else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) { - const char *msg = "generator raised StopIteration"; - if (PyCoro_CheckExact(gen)) { - msg = "coroutine raised StopIteration"; + 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)) { - msg = "async generator raised StopIteration"; + 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); } - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - - } - else if (!result && 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); } - if (!result || f->f_stacktop == NULL) { - /* 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->f_gen = NULL; - gen->gi_frame = NULL; - Py_DECREF(f); - } + /* 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->f_gen = NULL; + gen->gi_frame = NULL; + Py_DECREF(f); + + *presult = result; + return result ? PYGEN_RETURN : PYGEN_ERROR; +} +static PySendResult +PyGen_am_send(PyGenObject *gen, PyObject *arg, PyObject **result) +{ + return gen_send_ex2(gen, arg, result, 0, 0); +} + +static PyObject * +gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) +{ + PyObject *result; + if (gen_send_ex2(gen, arg, &result, exc, closing) == PYGEN_RETURN) { + if (PyAsyncGen_CheckExact(gen)) { + assert(result == Py_None); + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else if (result == Py_None) { + PyErr_SetNone(PyExc_StopIteration); + } + else { + _PyGen_SetStopIterationValue(result); + } + Py_CLEAR(result); + } return result; } @@ -279,8 +296,8 @@ PyDoc_STRVAR(send_doc, "send(arg) -> send 'arg' into generator,\n\ return next yielded value or raise StopIteration."); -PyObject * -_PyGen_Send(PyGenObject *gen, PyObject *arg) +static PyObject * +gen_send(PyGenObject *gen, PyObject *arg) { return gen_send_ex(gen, arg, 0, 0); } @@ -326,7 +343,7 @@ _PyGen_yf(PyGenObject *gen) PyObject *yf = NULL; PyFrameObject *f = gen->gi_frame; - if (f && f->f_stacktop) { + if (f) { PyObject *bytecode = f->f_code->co_code; unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode); @@ -338,9 +355,10 @@ _PyGen_yf(PyGenObject *gen) return NULL; } - if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM) + if (code[(f->f_lasti+1)*sizeof(_Py_CODEUNIT)] != YIELD_FROM) return NULL; - yf = f->f_stacktop[-1]; + assert(f->f_stackdepth > 0); + yf = f->f_valuestack[f->f_stackdepth-1]; Py_INCREF(yf); } @@ -355,9 +373,10 @@ gen_close(PyGenObject *gen, PyObject *args) int err = 0; if (yf) { - gen->gi_running = 1; + PyFrameState state = gen->gi_frame->f_state; + gen->gi_frame->f_state = FRAME_EXECUTING; err = gen_close_iter(yf); - gen->gi_running = 0; + gen->gi_frame->f_state = state; Py_DECREF(yf); } if (err == 0) @@ -404,9 +423,10 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, We have to allow some awaits to work it through, hence the `close_on_genexit` parameter here. */ - gen->gi_running = 1; + PyFrameState state = gen->gi_frame->f_state; + gen->gi_frame->f_state = FRAME_EXECUTING; err = gen_close_iter(yf); - gen->gi_running = 0; + gen->gi_frame->f_state = state; Py_DECREF(yf); if (err < 0) return gen_send_ex(gen, Py_None, 1, 0); @@ -417,7 +437,6 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, PyThreadState *tstate = _PyThreadState_GET(); PyFrameObject *f = tstate->frame; - gen->gi_running = 1; /* Since we are fast-tracking things by skipping the eval loop, we need to update the current frame so the stack trace will be reported correctly to the user. */ @@ -426,10 +445,12 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, tstate->frame = gen->gi_frame; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ + PyFrameState state = gen->gi_frame->f_state; + gen->gi_frame->f_state = FRAME_EXECUTING; ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); + gen->gi_frame->f_state = state; tstate->frame = f; - gen->gi_running = 0; } else { /* `yf` is an iterator or a coroutine-like object. */ PyObject *meth; @@ -441,23 +462,26 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, Py_DECREF(yf); goto throw_here; } - gen->gi_running = 1; + PyFrameState state = gen->gi_frame->f_state; + gen->gi_frame->f_state = FRAME_EXECUTING; ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL); - gen->gi_running = 0; + gen->gi_frame->f_state = state; Py_DECREF(meth); } Py_DECREF(yf); if (!ret) { PyObject *val; /* Pop subiterator from stack */ - ret = *(--gen->gi_frame->f_stacktop); + assert(gen->gi_frame->f_stackdepth > 0); + gen->gi_frame->f_stackdepth--; + ret = gen->gi_frame->f_valuestack[gen->gi_frame->f_stackdepth]; assert(ret == yf); Py_DECREF(ret); /* Termination repetition of YIELD_FROM */ assert(gen->gi_frame->f_lasti >= 0); - gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT); + gen->gi_frame->f_lasti += 1; if (_PyGen_FetchStopIterationValue(&val) == 0) { - ret = gen_send_ex(gen, val, 0, 0); + ret = gen_send(gen, val); Py_DECREF(val); } else { ret = gen_send_ex(gen, Py_None, 1, 0); @@ -543,7 +567,15 @@ gen_throw(PyGenObject *gen, PyObject *args) static PyObject * gen_iternext(PyGenObject *gen) { - return gen_send_ex(gen, NULL, 0, 0); + PyObject *result; + assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen)); + if (gen_send_ex2(gen, NULL, &result, 0, 0) == PYGEN_RETURN) { + if (result != Py_None) { + _PyGen_SetStopIterationValue(result); + } + Py_CLEAR(result); + } + return result; } /* @@ -700,6 +732,16 @@ gen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored)) return yf; } + +static PyObject * +gen_getrunning(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + if (gen->gi_frame == NULL) { + Py_RETURN_FALSE; + } + return PyBool_FromLong(_PyFrame_IsExecuting(gen->gi_frame)); +} + static PyGetSetDef gen_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, PyDoc_STR("name of the generator")}, @@ -707,23 +749,31 @@ static PyGetSetDef gen_getsetlist[] = { PyDoc_STR("qualified name of the generator")}, {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL, PyDoc_STR("object being iterated by yield from, or None")}, + {"gi_running", (getter)gen_getrunning, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef gen_memberlist[] = { - {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY|READ_RESTRICTED}, - {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY}, - {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|READ_RESTRICTED}, + {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY|PY_AUDIT_READ}, + {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|PY_AUDIT_READ}, {NULL} /* Sentinel */ }; static PyMethodDef gen_methods[] = { - {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc}, + {"send",(PyCFunction)gen_send, METH_O, send_doc}, {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc}, {NULL, NULL} /* Sentinel */ }; +static PyAsyncMethods gen_as_async = { + 0, /* am_await */ + 0, /* am_aiter */ + 0, /* am_anext */ + (sendfunc)PyGen_am_send, /* am_send */ +}; + + PyTypeObject PyGen_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "generator", /* tp_name */ @@ -734,7 +784,7 @@ PyTypeObject PyGen_Type = { 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + &gen_as_async, /* tp_as_async */ (reprfunc)gen_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -790,7 +840,6 @@ gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, f->f_gen = (PyObject *) gen; Py_INCREF(f->f_code); gen->gi_code = (PyObject *)(f->f_code); - gen->gi_running = 0; gen->gi_weakreflist = NULL; gen->gi_exc_state.exc_type = NULL; gen->gi_exc_state.exc_value = NULL; @@ -920,6 +969,15 @@ coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored)) return yf; } +static PyObject * +cr_getrunning(PyCoroObject *coro, void *Py_UNUSED(ignored)) +{ + if (coro->cr_frame == NULL) { + Py_RETURN_FALSE; + } + return PyBool_FromLong(_PyFrame_IsExecuting(coro->cr_frame)); +} + static PyGetSetDef coro_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, PyDoc_STR("name of the coroutine")}, @@ -927,13 +985,13 @@ static PyGetSetDef coro_getsetlist[] = { PyDoc_STR("qualified name of the coroutine")}, {"cr_await", (getter)coro_get_cr_await, NULL, PyDoc_STR("object being awaited on, or None")}, + {"cr_running", (getter)cr_getrunning, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef coro_memberlist[] = { - {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY|READ_RESTRICTED}, - {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY}, - {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|READ_RESTRICTED}, + {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY|PY_AUDIT_READ}, + {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|PY_AUDIT_READ}, {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin), READONLY}, {NULL} /* Sentinel */ }; @@ -950,7 +1008,7 @@ PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); static PyMethodDef coro_methods[] = { - {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc}, + {"send",(PyCFunction)gen_send, METH_O, coro_send_doc}, {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc}, {NULL, NULL} /* Sentinel */ @@ -959,7 +1017,8 @@ static PyMethodDef coro_methods[] = { static PyAsyncMethods coro_as_async = { (unaryfunc)coro_await, /* am_await */ 0, /* am_aiter */ - 0 /* am_anext */ + 0, /* am_anext */ + (sendfunc)PyGen_am_send, /* am_send */ }; PyTypeObject PyCoro_Type = { @@ -1025,13 +1084,13 @@ coro_wrapper_dealloc(PyCoroWrapper *cw) static PyObject * coro_wrapper_iternext(PyCoroWrapper *cw) { - return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0); + return gen_iternext((PyGenObject *)cw->cw_coroutine); } static PyObject * coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg) { - return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0); + return gen_send((PyGenObject *)cw->cw_coroutine, arg); } static PyObject * @@ -1171,7 +1230,7 @@ typedef enum { } AwaitableState; -typedef struct { +typedef struct PyAsyncGenASend { PyObject_HEAD PyAsyncGenObject *ags_gen; @@ -1183,7 +1242,7 @@ typedef struct { } PyAsyncGenASend; -typedef struct { +typedef struct PyAsyncGenAThrow { PyObject_HEAD PyAsyncGenObject *agt_gen; @@ -1195,28 +1254,12 @@ typedef struct { } PyAsyncGenAThrow; -typedef struct { +typedef struct _PyAsyncGenWrappedValue { PyObject_HEAD PyObject *agw_val; } _PyAsyncGenWrappedValue; -#ifndef _PyAsyncGen_MAXFREELIST -#define _PyAsyncGen_MAXFREELIST 80 -#endif - -/* Freelists boost performance 6-10%; they also reduce memory - fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend - are short-living objects that are instantiated for every - __anext__ call. -*/ - -static _PyAsyncGenWrappedValue *ag_value_freelist[_PyAsyncGen_MAXFREELIST]; -static int ag_value_freelist_free = 0; - -static PyAsyncGenASend *ag_asend_freelist[_PyAsyncGen_MAXFREELIST]; -static int ag_asend_freelist_free = 0; - #define _PyAsyncGenWrappedValue_CheckExact(o) \ Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type) @@ -1328,12 +1371,10 @@ static PyGetSetDef async_gen_getsetlist[] = { }; static PyMemberDef async_gen_memberlist[] = { - {"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), - READONLY|READ_RESTRICTED}, + {"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY|PY_AUDIT_READ}, {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), READONLY}, - {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), - READONLY|READ_RESTRICTED}, + {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY|PY_AUDIT_READ}, {NULL} /* Sentinel */ }; @@ -1359,7 +1400,8 @@ static PyMethodDef async_gen_methods[] = { static PyAsyncMethods async_gen_as_async = { 0, /* am_await */ PyObject_SelfIter, /* am_aiter */ - (unaryfunc)async_gen_anext /* am_anext */ + (unaryfunc)async_gen_anext, /* am_anext */ + (sendfunc)PyGen_am_send, /* am_send */ }; @@ -1416,6 +1458,14 @@ PyTypeObject PyAsyncGen_Type = { }; +static struct _Py_async_gen_state * +get_async_gen_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->async_gen; +} + + PyObject * PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) { @@ -1434,27 +1484,34 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) void -_PyAsyncGen_ClearFreeLists(void) +_PyAsyncGen_ClearFreeLists(PyInterpreterState *interp) { - while (ag_value_freelist_free) { + struct _Py_async_gen_state *state = &interp->async_gen; + + while (state->value_numfree) { _PyAsyncGenWrappedValue *o; - o = ag_value_freelist[--ag_value_freelist_free]; + o = state->value_freelist[--state->value_numfree]; assert(_PyAsyncGenWrappedValue_CheckExact(o)); PyObject_GC_Del(o); } - while (ag_asend_freelist_free) { + while (state->asend_numfree) { PyAsyncGenASend *o; - o = ag_asend_freelist[--ag_asend_freelist_free]; + o = state->asend_freelist[--state->asend_numfree]; assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type)); PyObject_GC_Del(o); } } void -_PyAsyncGen_Fini(void) +_PyAsyncGen_Fini(PyInterpreterState *interp) { - _PyAsyncGen_ClearFreeLists(); + _PyAsyncGen_ClearFreeLists(interp); +#ifdef Py_DEBUG + struct _Py_async_gen_state *state = &interp->async_gen; + state->value_numfree = -1; + state->asend_numfree = -1; +#endif } @@ -1497,10 +1554,16 @@ async_gen_asend_dealloc(PyAsyncGenASend *o) _PyObject_GC_UNTRACK((PyObject *)o); Py_CLEAR(o->ags_gen); Py_CLEAR(o->ags_sendval); - if (ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST) { + struct _Py_async_gen_state *state = get_async_gen_state(); +#ifdef Py_DEBUG + // async_gen_asend_dealloc() must not be called after _PyAsyncGen_Fini() + assert(state->asend_numfree != -1); +#endif + if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) { assert(PyAsyncGenASend_CheckExact(o)); - ag_asend_freelist[ag_asend_freelist_free++] = o; - } else { + state->asend_freelist[state->asend_numfree++] = o; + } + else { PyObject_GC_Del(o); } } @@ -1541,7 +1604,7 @@ async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg) } o->ags_gen->ag_running_async = 1; - result = gen_send_ex((PyGenObject*)o->ags_gen, arg, 0, 0); + result = gen_send((PyGenObject*)o->ags_gen, arg); result = async_gen_unwrap_value(o->ags_gen, result); if (result == NULL) { @@ -1601,7 +1664,8 @@ static PyMethodDef async_gen_asend_methods[] = { static PyAsyncMethods async_gen_asend_as_async = { PyObject_SelfIter, /* am_await */ 0, /* am_aiter */ - 0 /* am_anext */ + 0, /* am_anext */ + 0, /* am_send */ }; @@ -1652,11 +1716,17 @@ static PyObject * async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) { PyAsyncGenASend *o; - if (ag_asend_freelist_free) { - ag_asend_freelist_free--; - o = ag_asend_freelist[ag_asend_freelist_free]; + struct _Py_async_gen_state *state = get_async_gen_state(); +#ifdef Py_DEBUG + // async_gen_asend_new() must not be called after _PyAsyncGen_Fini() + assert(state->asend_numfree != -1); +#endif + if (state->asend_numfree) { + state->asend_numfree--; + o = state->asend_freelist[state->asend_numfree]; _Py_NewReference((PyObject *)o); - } else { + } + else { o = PyObject_GC_New(PyAsyncGenASend, &_PyAsyncGenASend_Type); if (o == NULL) { return NULL; @@ -1684,10 +1754,16 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o) { _PyObject_GC_UNTRACK((PyObject *)o); Py_CLEAR(o->agw_val); - if (ag_value_freelist_free < _PyAsyncGen_MAXFREELIST) { + struct _Py_async_gen_state *state = get_async_gen_state(); +#ifdef Py_DEBUG + // async_gen_wrapped_val_dealloc() must not be called after _PyAsyncGen_Fini() + assert(state->value_numfree != -1); +#endif + if (state->value_numfree < _PyAsyncGen_MAXFREELIST) { assert(_PyAsyncGenWrappedValue_CheckExact(o)); - ag_value_freelist[ag_value_freelist_free++] = o; - } else { + state->value_freelist[state->value_numfree++] = o; + } + else { PyObject_GC_Del(o); } } @@ -1751,12 +1827,18 @@ _PyAsyncGenValueWrapperNew(PyObject *val) _PyAsyncGenWrappedValue *o; assert(val); - if (ag_value_freelist_free) { - ag_value_freelist_free--; - o = ag_value_freelist[ag_value_freelist_free]; + struct _Py_async_gen_state *state = get_async_gen_state(); +#ifdef Py_DEBUG + // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini() + assert(state->value_numfree != -1); +#endif + if (state->value_numfree) { + state->value_numfree--; + o = state->value_freelist[state->value_numfree]; assert(_PyAsyncGenWrappedValue_CheckExact(o)); _Py_NewReference((PyObject*)o); - } else { + } + else { o = PyObject_GC_New(_PyAsyncGenWrappedValue, &_PyAsyncGenWrappedValue_Type); if (o == NULL) { @@ -1806,7 +1888,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) return NULL; } - if (f == NULL || f->f_stacktop == NULL) { + if (f == NULL || _PyFrameHasCompleted(f)) { o->agt_state = AWAITABLE_STATE_CLOSED; PyErr_SetNone(PyExc_StopIteration); return NULL; @@ -1879,7 +1961,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) assert(o->agt_state == AWAITABLE_STATE_ITER); - retval = gen_send_ex((PyGenObject *)gen, arg, 0, 0); + retval = gen_send((PyGenObject *)gen, arg); if (o->agt_args) { return async_gen_unwrap_value(o->agt_gen, retval); } else { @@ -1991,7 +2073,8 @@ static PyMethodDef async_gen_athrow_methods[] = { static PyAsyncMethods async_gen_athrow_as_async = { PyObject_SelfIter, /* am_await */ 0, /* am_aiter */ - 0 /* am_anext */ + 0, /* am_anext */ + 0, /* am_send */ }; diff --git a/contrib/tools/python3/src/Objects/interpreteridobject.c b/contrib/tools/python3/src/Objects/interpreteridobject.c index 39bde972695..46239100dcb 100644 --- a/contrib/tools/python3/src/Objects/interpreteridobject.c +++ b/contrib/tools/python3/src/Objects/interpreteridobject.c @@ -24,15 +24,21 @@ newinterpid(PyTypeObject *cls, int64_t id, int force) } } + if (interp != NULL) { + if (_PyInterpreterState_IDIncref(interp) < 0) { + return NULL; + } + } + interpid *self = PyObject_New(interpid, cls); if (self == NULL) { + if (interp != NULL) { + _PyInterpreterState_IDDecref(interp); + } return NULL; } self->id = id; - if (interp != NULL) { - _PyInterpreterState_IDIncref(interp); - } return self; } diff --git a/contrib/tools/python3/src/Objects/iterobject.c b/contrib/tools/python3/src/Objects/iterobject.c index 6cac41ad539..e493e41131b 100644 --- a/contrib/tools/python3/src/Objects/iterobject.c +++ b/contrib/tools/python3/src/Objects/iterobject.c @@ -157,7 +157,7 @@ PyTypeObject PySeqIter_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)iter_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -276,7 +276,7 @@ PyTypeObject PyCallIter_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)calliter_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -288,3 +288,214 @@ PyTypeObject PyCallIter_Type = { }; +/* -------------------------------------- */ + +typedef struct { + PyObject_HEAD + PyObject *wrapped; + PyObject *default_value; +} anextawaitableobject; + +static void +anextawaitable_dealloc(anextawaitableobject *obj) +{ + _PyObject_GC_UNTRACK(obj); + Py_XDECREF(obj->wrapped); + Py_XDECREF(obj->default_value); + PyObject_GC_Del(obj); +} + +static int +anextawaitable_traverse(anextawaitableobject *obj, visitproc visit, void *arg) +{ + Py_VISIT(obj->wrapped); + Py_VISIT(obj->default_value); + return 0; +} + +static PyObject * +anextawaitable_getiter(anextawaitableobject *obj) +{ + assert(obj->wrapped != NULL); + PyObject *awaitable = _PyCoro_GetAwaitableIter(obj->wrapped); + if (awaitable == NULL) { + return NULL; + } + if (Py_TYPE(awaitable)->tp_iternext == NULL) { + /* _PyCoro_GetAwaitableIter returns a Coroutine, a Generator, + * or an iterator. Of these, only coroutines lack tp_iternext. + */ + assert(PyCoro_CheckExact(awaitable)); + unaryfunc getter = Py_TYPE(awaitable)->tp_as_async->am_await; + PyObject *new_awaitable = getter(awaitable); + if (new_awaitable == NULL) { + Py_DECREF(awaitable); + return NULL; + } + Py_SETREF(awaitable, new_awaitable); + if (!PyIter_Check(awaitable)) { + PyErr_SetString(PyExc_TypeError, + "__await__ returned a non-iterable"); + Py_DECREF(awaitable); + return NULL; + } + } + return awaitable; +} + +static PyObject * +anextawaitable_iternext(anextawaitableobject *obj) +{ + /* Consider the following class: + * + * class A: + * async def __anext__(self): + * ... + * a = A() + * + * Then `await anext(a)` should call + * a.__anext__().__await__().__next__() + * + * On the other hand, given + * + * async def agen(): + * yield 1 + * yield 2 + * gen = agen() + * + * Then `await anext(gen)` can just call + * gen.__anext__().__next__() + */ + PyObject *awaitable = anextawaitable_getiter(obj); + if (awaitable == NULL) { + return NULL; + } + PyObject *result = (*Py_TYPE(awaitable)->tp_iternext)(awaitable); + Py_DECREF(awaitable); + if (result != NULL) { + return result; + } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) { + _PyGen_SetStopIterationValue(obj->default_value); + } + return NULL; +} + + +static PyObject * +anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) { + PyObject *awaitable = anextawaitable_getiter(obj); + if (awaitable == NULL) { + return NULL; + } + PyObject *ret = PyObject_CallMethod(awaitable, meth, "O", arg); + Py_DECREF(awaitable); + if (ret != NULL) { + return ret; + } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) { + /* `anextawaitableobject` is only used by `anext()` when + * a default value is provided. So when we have a StopAsyncIteration + * exception we replace it with a `StopIteration(default)`, as if + * it was the return value of `__anext__()` coroutine. + */ + _PyGen_SetStopIterationValue(obj->default_value); + } + return NULL; +} + + +static PyObject * +anextawaitable_send(anextawaitableobject *obj, PyObject *arg) { + return anextawaitable_proxy(obj, "send", arg); +} + + +static PyObject * +anextawaitable_throw(anextawaitableobject *obj, PyObject *arg) { + return anextawaitable_proxy(obj, "throw", arg); +} + + +static PyObject * +anextawaitable_close(anextawaitableobject *obj, PyObject *arg) { + return anextawaitable_proxy(obj, "close", arg); +} + + +PyDoc_STRVAR(send_doc, +"send(arg) -> send 'arg' into the wrapped iterator,\n\ +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."); + + +PyDoc_STRVAR(close_doc, +"close() -> raise GeneratorExit inside generator."); + + +static PyMethodDef anextawaitable_methods[] = { + {"send",(PyCFunction)anextawaitable_send, METH_O, send_doc}, + {"throw",(PyCFunction)anextawaitable_throw, METH_VARARGS, throw_doc}, + {"close",(PyCFunction)anextawaitable_close, METH_VARARGS, close_doc}, + {NULL, NULL} /* Sentinel */ +}; + + +static PyAsyncMethods anextawaitable_as_async = { + PyObject_SelfIter, /* am_await */ + 0, /* am_aiter */ + 0, /* am_anext */ + 0, /* am_send */ +}; + +PyTypeObject _PyAnextAwaitable_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "anext_awaitable", /* tp_name */ + sizeof(anextawaitableobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)anextawaitable_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &anextawaitable_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 */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)anextawaitable_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (unaryfunc)anextawaitable_iternext, /* tp_iternext */ + anextawaitable_methods, /* tp_methods */ +}; + +PyObject * +PyAnextAwaitable_New(PyObject *awaitable, PyObject *default_value) +{ + anextawaitableobject *anext = PyObject_GC_New( + anextawaitableobject, &_PyAnextAwaitable_Type); + if (anext == NULL) { + return NULL; + } + Py_INCREF(awaitable); + anext->wrapped = awaitable; + Py_INCREF(default_value); + anext->default_value = default_value; + _PyObject_GC_TRACK(anext); + return (PyObject *)anext; +} diff --git a/contrib/tools/python3/src/Objects/listobject.c b/contrib/tools/python3/src/Objects/listobject.c index 1e868b43c09..533ee7436d3 100644 --- a/contrib/tools/python3/src/Objects/listobject.c +++ b/contrib/tools/python3/src/Objects/listobject.c @@ -1,10 +1,10 @@ /* List object implementation */ #include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_object.h" -#include "pycore_tupleobject.h" -#include "pycore_accu.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_interp.h" // PyInterpreterState.list +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_tuple.h" // _PyTuple_FromArray() #ifdef STDC_HEADERS #include @@ -19,6 +19,15 @@ class list "PyListObject *" "&PyList_Type" #include "clinic/listobject.c.h" + +static struct _Py_list_state * +get_list_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->list; +} + + /* Ensure ob_item has room for at least newsize elements, and set * ob_size to newsize. If newsize > ob_size on entry, the content * of the new slots at exit is undefined heap trash; it's the caller's @@ -60,7 +69,7 @@ list_resize(PyListObject *self, Py_ssize_t newsize) * is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t. */ new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3; - /* Do not overallocate if the new size is closer to overalocated size + /* Do not overallocate if the new size is closer to overallocated size * than to the old size. */ if (newsize - Py_SIZE(self) > (Py_ssize_t)(new_allocated - newsize)) @@ -96,59 +105,65 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) return 0; } -/* Empty list reuse scheme to save calls to malloc and free */ -#ifndef PyList_MAXFREELIST -# define PyList_MAXFREELIST 80 -#endif - -static PyListObject *free_list[PyList_MAXFREELIST]; -static int numfree = 0; - void -_PyList_ClearFreeList(void) +_PyList_ClearFreeList(PyInterpreterState *interp) { - while (numfree) { - PyListObject *op = free_list[--numfree]; + struct _Py_list_state *state = &interp->list; + while (state->numfree) { + PyListObject *op = state->free_list[--state->numfree]; assert(PyList_CheckExact(op)); PyObject_GC_Del(op); } } void -_PyList_Fini(void) +_PyList_Fini(PyInterpreterState *interp) { - _PyList_ClearFreeList(); + _PyList_ClearFreeList(interp); +#ifdef Py_DEBUG + struct _Py_list_state *state = &interp->list; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ void _PyList_DebugMallocStats(FILE *out) { + struct _Py_list_state *state = get_list_state(); _PyDebugAllocatorStats(out, "free PyListObject", - numfree, sizeof(PyListObject)); + state->numfree, sizeof(PyListObject)); } PyObject * PyList_New(Py_ssize_t size) { - PyListObject *op; - if (size < 0) { PyErr_BadInternalCall(); return NULL; } - if (numfree) { - numfree--; - op = free_list[numfree]; + + struct _Py_list_state *state = get_list_state(); + PyListObject *op; +#ifdef Py_DEBUG + // PyList_New() must not be called after _PyList_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree) { + state->numfree--; + op = state->free_list[state->numfree]; _Py_NewReference((PyObject *)op); - } else { + } + else { op = PyObject_GC_New(PyListObject, &PyList_Type); - if (op == NULL) + if (op == NULL) { return NULL; + } } - if (size <= 0) + if (size <= 0) { op->ob_item = NULL; + } else { op->ob_item = (PyObject **) PyMem_Calloc(size, sizeof(PyObject *)); if (op->ob_item == NULL) { @@ -256,12 +271,8 @@ ins1(PyListObject *self, Py_ssize_t where, PyObject *v) PyErr_BadInternalCall(); return -1; } - if (n == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to list"); - return -1; - } + assert((size_t)n + 1 < PY_SSIZE_T_MAX); if (list_resize(self, n+1) < 0) return -1; @@ -296,12 +307,7 @@ app1(PyListObject *self, PyObject *v) Py_ssize_t n = PyList_GET_SIZE(self); assert (v != NULL); - if (n == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to list"); - return -1; - } - + assert((size_t)n + 1 < PY_SSIZE_T_MAX); if (list_resize(self, n+1) < 0) return -1; @@ -336,12 +342,19 @@ list_dealloc(PyListObject *op) while (--i >= 0) { Py_XDECREF(op->ob_item[i]); } - PyMem_FREE(op->ob_item); + PyMem_Free(op->ob_item); } - if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) - free_list[numfree++] = op; - else + struct _Py_list_state *state = get_list_state(); +#ifdef Py_DEBUG + // list_dealloc() must not be called after _PyList_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) { + state->free_list[state->numfree++] = op; + } + else { Py_TYPE(op)->tp_free((PyObject *)op); + } Py_TRASHCAN_END } @@ -501,8 +514,7 @@ list_concat(PyListObject *a, PyObject *bb) return NULL; } #define b ((PyListObject *)bb) - if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) - return PyErr_NoMemory(); + assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX); size = Py_SIZE(a) + Py_SIZE(b); if (size == 0) { return PyList_New(0); @@ -587,7 +599,7 @@ _list_clear(PyListObject *a) while (--i >= 0) { Py_XDECREF(item[i]); } - PyMem_FREE(item); + PyMem_Free(item); } /* Never fails; the return value can be ignored. Note that there is no guarantee that the list is actually empty @@ -663,7 +675,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) /* If norig == 0, item might be NULL, in which case we may not memcpy from it. */ if (s) { if (s > sizeof(recycle_on_stack)) { - recycle = (PyObject **)PyMem_MALLOC(s); + recycle = (PyObject **)PyMem_Malloc(s); if (recycle == NULL) { PyErr_NoMemory(); goto Error; @@ -701,7 +713,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) result = 0; Error: if (recycle != recycle_on_stack) - PyMem_FREE(recycle); + PyMem_Free(recycle); Py_XDECREF(v_as_SF); return result; #undef b @@ -2225,7 +2237,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) /* Leverage stack space we allocated but won't otherwise use */ keys = &ms.temparray[saved_ob_size+1]; else { - keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size); + keys = PyMem_Malloc(sizeof(PyObject *) * saved_ob_size); if (keys == NULL) { PyErr_NoMemory(); goto keyfunc_fail; @@ -2238,7 +2250,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) for (i=i-1 ; i>=0 ; i--) Py_DECREF(keys[i]); if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) - PyMem_FREE(keys); + PyMem_Free(keys); goto keyfunc_fail; } } @@ -2409,7 +2421,7 @@ fail: for (i = 0; i < saved_ob_size; i++) Py_DECREF(keys[i]); if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) - PyMem_FREE(keys); + PyMem_Free(keys); } if (self->allocated != -1 && result != NULL) { @@ -2437,7 +2449,7 @@ keyfunc_fail: while (--i >= 0) { Py_XDECREF(final_ob_item[i]); } - PyMem_FREE(final_ob_item); + PyMem_Free(final_ob_item); } Py_XINCREF(result); return result; @@ -2903,7 +2915,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) } garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyMem_Malloc(slicelength*sizeof(PyObject*)); if (!garbage) { PyErr_NoMemory(); return -1; @@ -2944,7 +2956,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) for (i = 0; i < slicelength; i++) { Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyMem_Free(garbage); return res; } @@ -2985,7 +2997,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) } garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyMem_Malloc(slicelength*sizeof(PyObject*)); if (!garbage) { Py_DECREF(seq); PyErr_NoMemory(); @@ -3006,7 +3018,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyMem_Free(garbage); Py_DECREF(seq); return 0; @@ -3047,7 +3059,8 @@ PyTypeObject PyList_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS | + _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE, /* tp_flags */ list___init____doc__, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ (inquiry)_list_clear, /* tp_clear */ diff --git a/contrib/tools/python3/src/Objects/longobject.c b/contrib/tools/python3/src/Objects/longobject.c index cf13b2c4301..685bd56096f 100644 --- a/contrib/tools/python3/src/Objects/longobject.c +++ b/contrib/tools/python3/src/Objects/longobject.c @@ -3,8 +3,11 @@ /* XXX The functional organization of this file is terrible */ #include "Python.h" -#include "pycore_interp.h" // _PY_NSMALLPOSINTS -#include "pycore_pystate.h" // _Py_IsMainInterpreter() +#include "pycore_bitutils.h" // _Py_popcount32() +#include "pycore_interp.h" // _PY_NSMALLPOSINTS +#include "pycore_long.h" // __PyLong_GetSmallInt_internal() +#include "pycore_object.h" // _PyObject_InitVar() +#include "pycore_pystate.h" // _Py_IsMainInterpreter() #include "longintrepr.h" #include @@ -17,8 +20,8 @@ class int "PyObject *" "&PyLong_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/ -#define NSMALLPOSINTS _PY_NSMALLPOSINTS #define NSMALLNEGINTS _PY_NSMALLNEGINTS +#define NSMALLPOSINTS _PY_NSMALLPOSINTS _Py_IDENTIFIER(little); _Py_IDENTIFIER(big); @@ -29,10 +32,6 @@ _Py_IDENTIFIER(big); (Py_SIZE(x) == 0 ? (sdigit)0 : \ (sdigit)(x)->ob_digit[0])) -PyObject *_PyLong_Zero = NULL; -PyObject *_PyLong_One = NULL; - -#if NSMALLNEGINTS + NSMALLPOSINTS > 0 #define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS) #define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS) @@ -40,8 +39,7 @@ static PyObject * get_small_int(sdigit ival) { assert(IS_SMALL_INT(ival)); - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *v = (PyObject*)tstate->interp->small_ints[ival + NSMALLNEGINTS]; + PyObject *v = __PyLong_GetSmallInt_internal(ival); Py_INCREF(v); return v; } @@ -58,12 +56,6 @@ maybe_small_long(PyLongObject *v) } return v; } -#else -#define IS_SMALL_INT(ival) 0 -#define IS_SMALL_UINT(ival) 0 -#define get_small_int(ival) (Py_UNREACHABLE(), NULL) -#define maybe_small_long(val) (val) -#endif /* If a freshly-allocated int is already shared, it must be a small integer, so negating it must go to PyLong_FromLong */ @@ -119,123 +111,6 @@ long_normalize(PyLongObject *v) return v; } -/* _PyLong_FromNbInt: Convert the given object to a PyLongObject - using the nb_int slot, if available. Raise TypeError if either the - nb_int slot is not available or the result of the call to nb_int - returns something not of type int. -*/ -PyObject * -_PyLong_FromNbInt(PyObject *integral) -{ - PyNumberMethods *nb; - PyObject *result; - - /* Fast path for the case that we already have an int. */ - if (PyLong_CheckExact(integral)) { - Py_INCREF(integral); - return integral; - } - - nb = Py_TYPE(integral)->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_Format(PyExc_TypeError, - "an integer is required (got type %.200s)", - Py_TYPE(integral)->tp_name); - return NULL; - } - - /* Convert using the nb_int slot, which should return something - of exact type int. */ - result = nb->nb_int(integral); - if (!result || PyLong_CheckExact(result)) - return result; - if (!PyLong_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__int__ returned non-int (type %.200s)", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; - } - /* Issue #17576: warn if 'result' not of exact type int. */ - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; -} - -/* Convert the given object to a PyLongObject using the nb_index or - nb_int slots, if available (the latter is deprecated). - Raise TypeError if either nb_index and nb_int slots are not - available or the result of the call to nb_index or nb_int - returns something not of type int. - Should be replaced with PyNumber_Index after the end of the - deprecation period. -*/ -PyObject * -_PyLong_FromNbIndexOrNbInt(PyObject *integral) -{ - PyNumberMethods *nb; - PyObject *result; - - /* Fast path for the case that we already have an int. */ - if (PyLong_CheckExact(integral)) { - Py_INCREF(integral); - return integral; - } - - nb = Py_TYPE(integral)->tp_as_number; - if (nb == NULL || (nb->nb_index == NULL && nb->nb_int == NULL)) { - PyErr_Format(PyExc_TypeError, - "an integer is required (got type %.200s)", - Py_TYPE(integral)->tp_name); - return NULL; - } - - if (nb->nb_index) { - /* Convert using the nb_index slot, which should return something - of exact type int. */ - result = nb->nb_index(integral); - if (!result || PyLong_CheckExact(result)) - return result; - if (!PyLong_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__index__ returned non-int (type %.200s)", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; - } - /* Issue #17576: warn if 'result' not of exact type int. */ - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__index__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) - { - Py_DECREF(result); - return NULL; - } - return result; - } - - result = _PyLong_FromNbInt(integral); - if (result && PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "an integer is required (got type %.200s). " - "Implicit conversion to integers using __int__ is deprecated, " - "and may be removed in a future version of Python.", - Py_TYPE(integral)->tp_name)) - { - Py_DECREF(result); - return NULL; - } - return result; -} - - /* Allocate a new int object with size digits. Return NULL and set exception if we run out of memory. */ @@ -256,13 +131,14 @@ _PyLong_New(Py_ssize_t size) "too many digits in integer"); return NULL; } - result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + + result = PyObject_Malloc(offsetof(PyLongObject, ob_digit) + size*sizeof(digit)); if (!result) { PyErr_NoMemory(); return NULL; } - return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); + _PyObject_InitVar((PyVarObject*)result, &PyLong_Type, size); + return result; } PyObject * @@ -480,7 +356,7 @@ PyLong_FromDouble(double dval) #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) #define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN) -/* Get a C long int from an int object or any object that has an __int__ +/* Get a C long int from an int object or any object that has an __index__ method. On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of @@ -499,7 +375,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) long res; Py_ssize_t i; int sign; - int do_decref = 0; /* if nb_int was called */ + int do_decref = 0; /* if PyNumber_Index was called */ *overflow = 0; if (vv == NULL) { @@ -511,7 +387,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) v = (PyLongObject *)vv; } else { - v = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(vv); + v = (PyLongObject *)_PyNumber_Index(vv); if (v == NULL) return -1; do_decref = 1; @@ -566,7 +442,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) return res; } -/* Get a C long int from an int object or any object that has an __int__ +/* Get a C long int from an int object or any object that has an __index__ method. Return -1 and set an error if overflow occurs. */ long @@ -583,7 +459,7 @@ PyLong_AsLong(PyObject *obj) return result; } -/* Get a C int from an int object or any object that has an __int__ +/* Get a C int from an int object or any object that has an __index__ method. Return -1 and set an error if overflow occurs. */ int @@ -791,7 +667,7 @@ PyLong_AsUnsignedLongMask(PyObject *op) return _PyLong_AsUnsignedLongMask(op); } - lo = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(op); + lo = (PyLongObject *)_PyNumber_Index(op); if (lo == NULL) return (unsigned long)-1; @@ -811,6 +687,13 @@ _PyLong_Sign(PyObject *vv) return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); } +static int +bit_length_digit(digit x) +{ + Py_BUILD_ASSERT(PyLong_SHIFT <= sizeof(unsigned long) * 8); + return _Py_bit_length((unsigned long)x); +} + size_t _PyLong_NumBits(PyObject *vv) { @@ -828,7 +711,7 @@ _PyLong_NumBits(PyObject *vv) if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT) goto Overflow; result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; - msd_bits = _Py_bit_length(msd); + msd_bits = bit_length_digit(msd); if (SIZE_MAX - msd_bits < result) goto Overflow; result += msd_bits; @@ -1230,7 +1113,7 @@ PyLong_FromSsize_t(Py_ssize_t ival) } /* Get a C long long int from an int object or any object that has an - __int__ method. Return -1 and set an error if overflow occurs. */ + __index__ method. Return -1 and set an error if overflow occurs. */ long long PyLong_AsLongLong(PyObject *vv) @@ -1238,7 +1121,7 @@ PyLong_AsLongLong(PyObject *vv) PyLongObject *v; long long bytes; int res; - int do_decref = 0; /* if nb_int was called */ + int do_decref = 0; /* if PyNumber_Index was called */ if (vv == NULL) { PyErr_BadInternalCall(); @@ -1249,7 +1132,7 @@ PyLong_AsLongLong(PyObject *vv) v = (PyLongObject *)vv; } else { - v = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(vv); + v = (PyLongObject *)_PyNumber_Index(vv); if (v == NULL) return -1; do_decref = 1; @@ -1364,7 +1247,7 @@ PyLong_AsUnsignedLongLongMask(PyObject *op) return _PyLong_AsUnsignedLongLongMask(op); } - lo = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(op); + lo = (PyLongObject *)_PyNumber_Index(op); if (lo == NULL) return (unsigned long long)-1; @@ -1374,7 +1257,7 @@ PyLong_AsUnsignedLongLongMask(PyObject *op) } /* Get a C long long int from an int object or any object that has an - __int__ method. + __index__ method. On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of the result. Otherwise *overflow is 0. @@ -1392,7 +1275,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) long long res; Py_ssize_t i; int sign; - int do_decref = 0; /* if nb_int was called */ + int do_decref = 0; /* if PyNumber_Index was called */ *overflow = 0; if (vv == NULL) { @@ -1404,7 +1287,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) v = (PyLongObject *)vv; } else { - v = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(vv); + v = (PyLongObject *)_PyNumber_Index(vv); if (v == NULL) return -1; do_decref = 1; @@ -1938,7 +1821,7 @@ long_format_binary(PyObject *aa, int base, int alternate, return -1; } size_a_in_bits = (size_a - 1) * PyLong_SHIFT + - _Py_bit_length(a->ob_digit[size_a - 1]); + bit_length_digit(a->ob_digit[size_a - 1]); /* Allow 1 character for a '-' sign. */ sz = negative + (size_a_in_bits + (bits - 1)) / bits; } @@ -2610,17 +2493,6 @@ _PyLong_FromBytes(const char *s, Py_ssize_t len, int base) return NULL; } -PyObject * -PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) -{ - PyObject *v, *unicode = PyUnicode_FromWideChar(u, length); - if (unicode == NULL) - return NULL; - v = PyLong_FromUnicodeObject(unicode, base); - Py_DECREF(unicode); - return v; -} - PyObject * PyLong_FromUnicodeObject(PyObject *u, int base) { @@ -2677,8 +2549,9 @@ long_divrem(PyLongObject *a, PyLongObject *b, if (*prem == NULL) { return -1; } - Py_INCREF(_PyLong_Zero); - *pdiv = (PyLongObject*)_PyLong_Zero; + PyObject *zero = _PyLong_GetZero(); + Py_INCREF(zero); + *pdiv = (PyLongObject*)zero; return 0; } if (size_b == 1) { @@ -2758,7 +2631,7 @@ 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 - _Py_bit_length(w1->ob_digit[size_w-1]); + d = PyLong_SHIFT - bit_length_digit(w1->ob_digit[size_w-1]); carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); assert(carry == 0); carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); @@ -2880,7 +2753,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) *e = 0; return 0.0; } - a_bits = _Py_bit_length(a->ob_digit[a_size-1]); + a_bits = bit_length_digit(a->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 && @@ -3787,7 +3660,7 @@ l_divmod(PyLongObject *v, PyLongObject *w, Py_DECREF(div); return -1; } - temp = (PyLongObject *) long_sub(div, (PyLongObject *)_PyLong_One); + temp = (PyLongObject *) long_sub(div, (PyLongObject *)_PyLong_GetOne()); if (temp == NULL) { Py_DECREF(mod); Py_DECREF(div); @@ -3973,8 +3846,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 + _Py_bit_length(a->ob_digit[a_size - 1]) - - _Py_bit_length(b->ob_digit[b_size - 1]); + diff = diff * PyLong_SHIFT + bit_length_digit(a->ob_digit[a_size - 1]) - + bit_length_digit(b->ob_digit[b_size - 1]); /* Now diff = a_bits - b_bits. */ if (diff > DBL_MAX_EXP) goto overflow; @@ -4050,7 +3923,7 @@ long_true_divide(PyObject *v, PyObject *w) } x_size = Py_ABS(Py_SIZE(x)); assert(x_size > 0); /* result of division is never zero */ - x_bits = (x_size-1)*PyLong_SHIFT+_Py_bit_length(x->ob_digit[x_size-1]); + x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->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; @@ -4196,7 +4069,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) Py_DECREF(c); Py_DECREF(n); - if (long_compare(a, (PyLongObject *)_PyLong_One)) { + if (long_compare(a, (PyLongObject *)_PyLong_GetOne())) { /* a != 1; we don't have an inverse. */ Py_DECREF(a); Py_DECREF(b); @@ -4432,7 +4305,7 @@ long_invert(PyLongObject *v) PyLongObject *x; if (Py_ABS(Py_SIZE(v)) <=1) return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); - x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_One); + x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_GetOne()); if (x == NULL) return NULL; _PyLong_Negate(&x); @@ -4865,7 +4738,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) alloc_b = Py_SIZE(b); /* reduce until a fits into 2 digits */ while ((size_a = Py_SIZE(a)) > 2) { - nbits = _Py_bit_length(a->ob_digit[size_a-1]); + nbits = bit_length_digit(a->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); @@ -5224,7 +5097,8 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) /* compare twice the remainder with the divisor, to see if we need to adjust the quotient and remainder */ - twice_rem = long_lshift((PyObject *)rem, _PyLong_One); + PyObject *one = _PyLong_GetOne(); // borrowed reference + twice_rem = long_lshift((PyObject *)rem, one); if (twice_rem == NULL) goto error; if (quo_is_neg) { @@ -5241,9 +5115,9 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { /* fix up quotient */ if (quo_is_neg) - temp = long_sub(quo, (PyLongObject *)_PyLong_One); + temp = long_sub(quo, (PyLongObject *)one); else - temp = long_add(quo, (PyLongObject *)_PyLong_One); + temp = long_add(quo, (PyLongObject *)one); Py_DECREF(quo); quo = (PyLongObject *)temp; if (quo == NULL) @@ -5274,10 +5148,22 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) return NULL; } +/*[clinic input] +int.__round__ + + ndigits as o_ndigits: object = NULL + / + +Rounding an Integral returns itself. + +Rounding with an ndigits argument also returns an integer. +[clinic start generated code]*/ + static PyObject * -long_round(PyObject *self, PyObject *args) +int___round___impl(PyObject *self, PyObject *o_ndigits) +/*[clinic end generated code: output=954fda6b18875998 input=1614cf23ec9e18c3]*/ { - PyObject *o_ndigits=NULL, *temp, *result, *ndigits; + PyObject *temp, *result, *ndigits; /* To round an integer m to the nearest 10**n (n positive), we make use of * the divmod_near operation, defined by: @@ -5293,12 +5179,10 @@ long_round(PyObject *self, PyObject *args) * * m - divmod_near(m, 10**n)[1]. */ - if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) - return NULL; if (o_ndigits == NULL) return long_long(self); - ndigits = PyNumber_Index(o_ndigits); + ndigits = _PyNumber_Index(o_ndigits); if (ndigits == NULL) return NULL; @@ -5386,7 +5270,7 @@ int_bit_length_impl(PyObject *self) return PyLong_FromLong(0); msd = ((PyLongObject *)self)->ob_digit[ndigits-1]; - msd_bits = _Py_bit_length(msd); + msd_bits = bit_length_digit(msd); if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits); @@ -5422,6 +5306,73 @@ int_bit_length_impl(PyObject *self) return NULL; } +static int +popcount_digit(digit d) +{ + // digit can be larger than uint32_t, but only PyLong_SHIFT bits + // of it will be ever used. + Py_BUILD_ASSERT(PyLong_SHIFT <= 32); + return _Py_popcount32((uint32_t)d); +} + +/*[clinic input] +int.bit_count + +Number of ones in the binary representation of the absolute value of self. + +Also known as the population count. + +>>> bin(13) +'0b1101' +>>> (13).bit_count() +3 +[clinic start generated code]*/ + +static PyObject * +int_bit_count_impl(PyObject *self) +/*[clinic end generated code: output=2e571970daf1e5c3 input=7e0adef8e8ccdf2e]*/ +{ + assert(self != NULL); + assert(PyLong_Check(self)); + + PyLongObject *z = (PyLongObject *)self; + Py_ssize_t ndigits = Py_ABS(Py_SIZE(z)); + Py_ssize_t bit_count = 0; + + /* Each digit has up to PyLong_SHIFT ones, so the accumulated bit count + from the first PY_SSIZE_T_MAX/PyLong_SHIFT digits can't overflow a + 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]); + } + + PyObject *result = PyLong_FromSsize_t(bit_count); + if (result == NULL) { + return NULL; + } + + /* 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])); + if (x == NULL) { + goto error; + } + PyObject *y = long_add((PyLongObject *)result, (PyLongObject *)x); + Py_DECREF(x); + if (y == NULL) { + goto error; + } + Py_DECREF(result); + result = y; + } + + return result; + + error: + Py_DECREF(result); + return NULL; +} /*[clinic input] int.as_integer_ratio @@ -5448,7 +5399,7 @@ int_as_integer_ratio_impl(PyObject *self) if (numerator == NULL) { return NULL; } - ratio_tuple = PyTuple_Pack(2, numerator, _PyLong_One); + ratio_tuple = PyTuple_Pack(2, numerator, _PyLong_GetOne()); Py_DECREF(numerator); return ratio_tuple; } @@ -5578,6 +5529,7 @@ static PyMethodDef long_methods[] = { {"conjugate", long_long_meth, METH_NOARGS, "Returns self, the complex conjugate of any int."}, INT_BIT_LENGTH_METHODDEF + INT_BIT_COUNT_METHODDEF INT_TO_BYTES_METHODDEF INT_FROM_BYTES_METHODDEF INT_AS_INTEGER_RATIO_METHODDEF @@ -5587,9 +5539,7 @@ static PyMethodDef long_methods[] = { "Flooring an Integral returns itself."}, {"__ceil__", long_long_meth, METH_NOARGS, "Ceiling of an Integral returns itself."}, - {"__round__", (PyCFunction)long_round, METH_VARARGS, - "Rounding an Integral returns itself.\n" - "Rounding with an ndigits argument also returns an integer."}, + INT___ROUND___METHODDEF INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF @@ -5690,7 +5640,8 @@ PyTypeObject PyLong_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_LONG_SUBCLASS | + _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ long_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -5753,9 +5704,8 @@ PyLong_GetInfo(void) } int -_PyLong_Init(PyThreadState *tstate) +_PyLong_Init(PyInterpreterState *interp) { -#if NSMALLNEGINTS + NSMALLPOSINTS > 0 for (Py_ssize_t i=0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) { sdigit ival = (sdigit)i - NSMALLNEGINTS; int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); @@ -5768,43 +5718,28 @@ _PyLong_Init(PyThreadState *tstate) Py_SET_SIZE(v, size); v->ob_digit[0] = (digit)abs(ival); - tstate->interp->small_ints[i] = v; + interp->small_ints[i] = v; } -#endif - - if (_Py_IsMainInterpreter(tstate)) { - _PyLong_Zero = PyLong_FromLong(0); - if (_PyLong_Zero == NULL) { - return 0; - } + return 0; +} - _PyLong_One = PyLong_FromLong(1); - if (_PyLong_One == NULL) { - return 0; - } - /* initialize int_info */ - if (Int_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { - return 0; - } +int +_PyLong_InitTypes(void) +{ + /* initialize int_info */ + if (Int_InfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { + return -1; } } - - return 1; + return 0; } void -_PyLong_Fini(PyThreadState *tstate) +_PyLong_Fini(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(tstate)) { - Py_CLEAR(_PyLong_One); - Py_CLEAR(_PyLong_Zero); - } - -#if NSMALLNEGINTS + NSMALLPOSINTS > 0 for (Py_ssize_t i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) { - Py_CLEAR(tstate->interp->small_ints[i]); + Py_CLEAR(interp->small_ints[i]); } -#endif } diff --git a/contrib/tools/python3/src/Objects/memoryobject.c b/contrib/tools/python3/src/Objects/memoryobject.c index 682bbe8a61e..913d3580622 100644 --- a/contrib/tools/python3/src/Objects/memoryobject.c +++ b/contrib/tools/python3/src/Objects/memoryobject.c @@ -238,12 +238,6 @@ PyTypeObject _PyManagedBuffer_Type = { #define REQ_FORMAT(flags) (flags&PyBUF_FORMAT) -PyDoc_STRVAR(memory_doc, -"memoryview(object)\n--\n\ -\n\ -Create a new memoryview object which references the given object."); - - /**************************************************************************/ /* Copy memoryview buffers */ /**************************************************************************/ @@ -961,18 +955,20 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order) } -static PyObject * -memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) -{ - PyObject *obj; - static char *kwlist[] = {"object", NULL}; +/*[clinic input] +@classmethod +memoryview.__new__ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist, - &obj)) { - return NULL; - } + object: object + +Create a new memoryview object which references the given object. +[clinic start generated code]*/ - return PyMemoryView_FromObject(obj); +static PyObject * +memoryview_impl(PyTypeObject *type, PyObject *object) +/*[clinic end generated code: output=7de78e184ed66db8 input=f04429eb0bdf8c6e]*/ +{ + return PyMemoryView_FromObject(object); } @@ -1062,8 +1058,15 @@ _memory_release(PyMemoryViewObject *self) return -1; } +/*[clinic input] +memoryview.release + +Release the underlying buffer exposed by the memoryview object. +[clinic start generated code]*/ + static PyObject * -memory_release(PyMemoryViewObject *self, PyObject *noargs) +memoryview_release_impl(PyMemoryViewObject *self) +/*[clinic end generated code: output=d0b7e3ba95b7fcb9 input=bc71d1d51f4a52f0]*/ { if (_memory_release(self) < 0) return NULL; @@ -1108,7 +1111,7 @@ memory_enter(PyObject *self, PyObject *args) static PyObject * memory_exit(PyObject *self, PyObject *args) { - return memory_release((PyMemoryViewObject *)self, NULL); + return memoryview_release_impl((PyMemoryViewObject *)self); } @@ -1352,26 +1355,25 @@ zero_in_shape(PyMemoryViewObject *mv) All casts must result in views that will have the exact byte size of the original input. Otherwise, an error is raised. */ +/*[clinic input] +memoryview.cast + + format: unicode + shape: object = NULL + +Cast a memoryview to a new format or shape. +[clinic start generated code]*/ + static PyObject * -memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) +memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format, + PyObject *shape) +/*[clinic end generated code: output=bae520b3a389cbab input=138936cc9041b1a3]*/ { - static char *kwlist[] = {"format", "shape", NULL}; PyMemoryViewObject *mv = NULL; - PyObject *shape = NULL; - PyObject *format; Py_ssize_t ndim = 1; CHECK_RELEASED(self); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, - &format, &shape)) { - return NULL; - } - if (!PyUnicode_Check(format)) { - PyErr_SetString(PyExc_TypeError, - "memoryview: format argument must be a string"); - return NULL; - } if (!MV_C_CONTIGUOUS(self->flags)) { PyErr_SetString(PyExc_TypeError, "memoryview: casts are restricted to C-contiguous views"); @@ -1415,8 +1417,15 @@ error: return NULL; } +/*[clinic input] +memoryview.toreadonly + +Return a readonly version of the memoryview. +[clinic start generated code]*/ + static PyObject * -memory_toreadonly(PyMemoryViewObject *self, PyObject *noargs) +memoryview_toreadonly_impl(PyMemoryViewObject *self) +/*[clinic end generated code: output=2c7e056f04c99e62 input=dc06d20f19ba236f]*/ { CHECK_RELEASED(self); /* Even if self is already readonly, we still need to create a new @@ -1578,7 +1587,7 @@ pylong_as_ld(PyObject *item) PyObject *tmp; long ld; - tmp = PyNumber_Index(item); + tmp = _PyNumber_Index(item); if (tmp == NULL) return -1; @@ -1593,7 +1602,7 @@ pylong_as_lu(PyObject *item) PyObject *tmp; unsigned long lu; - tmp = PyNumber_Index(item); + tmp = _PyNumber_Index(item); if (tmp == NULL) return (unsigned long)-1; @@ -1608,7 +1617,7 @@ pylong_as_lld(PyObject *item) PyObject *tmp; long long lld; - tmp = PyNumber_Index(item); + tmp = _PyNumber_Index(item); if (tmp == NULL) return -1; @@ -1623,7 +1632,7 @@ pylong_as_llu(PyObject *item) PyObject *tmp; unsigned long long llu; - tmp = PyNumber_Index(item); + tmp = _PyNumber_Index(item); if (tmp == NULL) return (unsigned long long)-1; @@ -1638,7 +1647,7 @@ pylong_as_zd(PyObject *item) PyObject *tmp; Py_ssize_t zd; - tmp = PyNumber_Index(item); + tmp = _PyNumber_Index(item); if (tmp == NULL) return -1; @@ -1653,7 +1662,7 @@ pylong_as_zu(PyObject *item) PyObject *tmp; size_t zu; - tmp = PyNumber_Index(item); + tmp = _PyNumber_Index(item); if (tmp == NULL) return (size_t)-1; @@ -2109,13 +2118,20 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, /* Return a list representation of the memoryview. Currently only buffers with native format strings are supported. */ +/*[clinic input] +memoryview.tolist + +Return the data in the buffer as a list of elements. +[clinic start generated code]*/ + static PyObject * -memory_tolist(PyMemoryViewObject *mv, PyObject *noargs) +memoryview_tolist_impl(PyMemoryViewObject *self) +/*[clinic end generated code: output=a6cda89214fd5a1b input=21e7d0c1860b211a]*/ { - const Py_buffer *view = &(mv->view); + const Py_buffer *view = &self->view; const char *fmt; - CHECK_RELEASED(mv); + CHECK_RELEASED(self); fmt = adjust_fmt(view); if (fmt == NULL) @@ -2135,21 +2151,30 @@ memory_tolist(PyMemoryViewObject *mv, PyObject *noargs) } } +/*[clinic input] +memoryview.tobytes + + order: str(accept={str, NoneType}, c_default="NULL") = 'C' + +Return the data in the buffer as a byte string. + +Order can be {'C', 'F', 'A'}. When order is 'C' or 'F', the data of the +original array is converted to C or Fortran order. For contiguous views, +'A' returns an exact copy of the physical memory. In particular, in-memory +Fortran order is preserved. For non-contiguous views, the data is converted +to C first. order=None is the same as order='C'. +[clinic start generated code]*/ + static PyObject * -memory_tobytes(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) +memoryview_tobytes_impl(PyMemoryViewObject *self, const char *order) +/*[clinic end generated code: output=1288b62560a32a23 input=0efa3ddaeda573a8]*/ { - static char *kwlist[] = {"order", NULL}; Py_buffer *src = VIEW_ADDR(self); - char *order = NULL; char ord = 'C'; PyObject *bytes; CHECK_RELEASED(self); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|z", kwlist, &order)) { - return NULL; - } - if (order) { if (strcmp(order, "F") == 0) { ord = 'F'; @@ -3122,43 +3147,125 @@ static PyGetSetDef memory_getsetlist[] = { {NULL, NULL, NULL, NULL}, }; -PyDoc_STRVAR(memory_release_doc, -"release($self, /)\n--\n\ -\n\ -Release the underlying buffer exposed by the memoryview object."); -PyDoc_STRVAR(memory_tobytes_doc, -"tobytes($self, /, order=None)\n--\n\ -\n\ -Return the data in the buffer as a byte string. Order can be {'C', 'F', 'A'}.\n\ -When order is 'C' or 'F', the data of the original array is converted to C or\n\ -Fortran order. For contiguous views, 'A' returns an exact copy of the physical\n\ -memory. In particular, in-memory Fortran order is preserved. For non-contiguous\n\ -views, the data is converted to C first. order=None is the same as order='C'."); -PyDoc_STRVAR(memory_tolist_doc, -"tolist($self, /)\n--\n\ -\n\ -Return the data in the buffer as a list of elements."); -PyDoc_STRVAR(memory_cast_doc, -"cast($self, /, format, *, shape)\n--\n\ -\n\ -Cast a memoryview to a new format or shape."); -PyDoc_STRVAR(memory_toreadonly_doc, -"toreadonly($self, /)\n--\n\ -\n\ -Return a readonly version of the memoryview."); static PyMethodDef memory_methods[] = { - {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc}, - {"tobytes", (PyCFunction)(void(*)(void))memory_tobytes, METH_VARARGS|METH_KEYWORDS, memory_tobytes_doc}, + MEMORYVIEW_RELEASE_METHODDEF + MEMORYVIEW_TOBYTES_METHODDEF MEMORYVIEW_HEX_METHODDEF - {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc}, - {"cast", (PyCFunction)(void(*)(void))memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc}, - {"toreadonly", (PyCFunction)memory_toreadonly, METH_NOARGS, memory_toreadonly_doc}, + MEMORYVIEW_TOLIST_METHODDEF + MEMORYVIEW_CAST_METHODDEF + MEMORYVIEW_TOREADONLY_METHODDEF {"__enter__", memory_enter, METH_NOARGS, NULL}, {"__exit__", memory_exit, METH_VARARGS, NULL}, {NULL, NULL} }; +/**************************************************************************/ +/* Memoryview Iterator */ +/**************************************************************************/ + +static PyTypeObject PyMemoryIter_Type; + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyMemoryViewObject *it_seq; // Set to NULL when iterator is exhausted + Py_ssize_t it_length; + const char *it_fmt; +} memoryiterobject; + +static void +memoryiter_dealloc(memoryiterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +memoryiter_traverse(memoryiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +memoryiter_next(memoryiterobject *it) +{ + PyMemoryViewObject *seq; + seq = it->it_seq; + if (seq == NULL) { + return NULL; + } + + if (it->it_index < it->it_length) { + CHECK_RELEASED(seq); + Py_buffer *view = &(seq->view); + char *ptr = (char *)seq->view.buf; + + ptr += view->strides[0] * it->it_index++; + ptr = ADJUST_PTR(ptr, view->suboffsets, 0); + if (ptr == NULL) { + return NULL; + } + return unpack_single(ptr, it->it_fmt); + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +memory_iter(PyObject *seq) +{ + if (!PyMemoryView_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + PyMemoryViewObject *obj = (PyMemoryViewObject *)seq; + int ndims = obj->view.ndim; + if (ndims == 0) { + PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory"); + return NULL; + } + if (ndims != 1) { + PyErr_SetString(PyExc_NotImplementedError, + "multi-dimensional sub-views are not implemented"); + return NULL; + } + + const char *fmt = adjust_fmt(&obj->view); + if (fmt == NULL) { + return NULL; + } + + memoryiterobject *it; + it = PyObject_GC_New(memoryiterobject, &PyMemoryIter_Type); + if (it == NULL) { + return NULL; + } + it->it_fmt = fmt; + it->it_length = memory_length(obj); + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = obj; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} + +static PyTypeObject PyMemoryIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "memory_iterator", + .tp_basicsize = sizeof(memoryiterobject), + // methods + .tp_dealloc = (destructor)memoryiter_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)memoryiter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)memoryiter_next, +}; PyTypeObject PyMemoryView_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -3180,13 +3287,14 @@ PyTypeObject PyMemoryView_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &memory_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - memory_doc, /* tp_doc */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_SEQUENCE, /* tp_flags */ + memoryview__doc__, /* tp_doc */ (traverseproc)memory_traverse, /* tp_traverse */ (inquiry)memory_clear, /* tp_clear */ memory_richcompare, /* tp_richcompare */ offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */ - 0, /* tp_iter */ + memory_iter, /* tp_iter */ 0, /* tp_iternext */ memory_methods, /* tp_methods */ 0, /* tp_members */ @@ -3198,5 +3306,5 @@ PyTypeObject PyMemoryView_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - memory_new, /* tp_new */ + memoryview, /* tp_new */ }; diff --git a/contrib/tools/python3/src/Objects/moduleobject.c b/contrib/tools/python3/src/Objects/moduleobject.c index ee4ed97588e..b69e5cedbb5 100644 --- a/contrib/tools/python3/src/Objects/moduleobject.c +++ b/contrib/tools/python3/src/Objects/moduleobject.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_moduleobject.h" // _PyModule_GetDef() #include "structmember.h" // PyMemberDef static Py_ssize_t max_module_number; @@ -11,15 +12,9 @@ static Py_ssize_t max_module_number; _Py_IDENTIFIER(__doc__); _Py_IDENTIFIER(__name__); _Py_IDENTIFIER(__spec__); - -typedef struct { - PyObject_HEAD - PyObject *md_dict; - struct PyModuleDef *md_def; - void *md_state; - PyObject *md_weaklist; - PyObject *md_name; /* for logging purposes after md_dict is cleared */ -} PyModuleObject; +_Py_IDENTIFIER(__dict__); +_Py_IDENTIFIER(__dir__); +_Py_IDENTIFIER(__annotations__); static PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, @@ -35,6 +30,19 @@ PyTypeObject PyModuleDef_Type = { }; +int +_PyModule_IsExtension(PyObject *obj) +{ + if (!PyModule_Check(obj)) { + return 0; + } + PyModuleObject *module = (PyModuleObject*)obj; + + struct PyModuleDef *def = module->md_def; + return (def != NULL && def->m_methods != NULL); +} + + PyObject* PyModuleDef_Init(struct PyModuleDef* def) { @@ -211,7 +219,7 @@ _PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version) return NULL; if (module->m_size > 0) { - m->md_state = PyMem_MALLOC(module->m_size); + m->md_state = PyMem_Malloc(module->m_size); if (!m->md_state) { PyErr_NoMemory(); Py_DECREF(m); @@ -377,7 +385,7 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def) if (md->md_state == NULL) { /* Always set a state pointer; this serves as a marker to skip * multiple initialization (importlib.reload() is no-op) */ - md->md_state = PyMem_MALLOC(def->m_size); + md->md_state = PyMem_Malloc(def->m_size); if (!md->md_state) { PyErr_NoMemory(); return -1; @@ -456,14 +464,11 @@ PyModule_SetDocString(PyObject *m, const char *doc) PyObject * PyModule_GetDict(PyObject *m) { - PyObject *d; if (!PyModule_Check(m)) { PyErr_BadInternalCall(); return NULL; } - d = ((PyModuleObject *)m) -> md_dict; - assert(d != NULL); - return d; + return _PyModule_GetDict(m); } PyObject* @@ -476,11 +481,13 @@ PyModule_GetNameObject(PyObject *m) return NULL; } d = ((PyModuleObject *)m)->md_dict; - if (d == NULL || - (name = _PyDict_GetItemId(d, &PyId___name__)) == NULL || + if (d == NULL || !PyDict_Check(d) || + (name = _PyDict_GetItemIdWithError(d, &PyId___name__)) == NULL || !PyUnicode_Check(name)) { - PyErr_SetString(PyExc_SystemError, "nameless module"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_SystemError, "nameless module"); + } return NULL; } Py_INCREF(name); @@ -509,10 +516,12 @@ PyModule_GetFilenameObject(PyObject *m) } d = ((PyModuleObject *)m)->md_dict; if (d == NULL || - (fileobj = _PyDict_GetItemId(d, &PyId___file__)) == NULL || + (fileobj = _PyDict_GetItemIdWithError(d, &PyId___file__)) == NULL || !PyUnicode_Check(fileobj)) { - PyErr_SetString(PyExc_SystemError, "module filename missing"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_SystemError, "module filename missing"); + } return NULL; } Py_INCREF(fileobj); @@ -539,7 +548,7 @@ PyModule_GetDef(PyObject* m) PyErr_BadArgument(); return NULL; } - return ((PyModuleObject *)m)->md_def; + return _PyModule_GetDef(m); } void* @@ -549,7 +558,7 @@ PyModule_GetState(PyObject* m) PyErr_BadArgument(); return NULL; } - return ((PyModuleObject *)m)->md_state; + return _PyModule_GetState(m); } void @@ -677,7 +686,7 @@ module_dealloc(PyModuleObject *m) Py_XDECREF(m->md_dict); Py_XDECREF(m->md_name); if (m->md_state != NULL) - PyMem_FREE(m->md_state); + PyMem_Free(m->md_state); Py_TYPE(m)->tp_free((PyObject *)m); } @@ -721,14 +730,21 @@ module_getattro(PyModuleObject *m, PyObject *name) PyErr_Clear(); if (m->md_dict) { _Py_IDENTIFIER(__getattr__); - getattr = _PyDict_GetItemId(m->md_dict, &PyId___getattr__); + getattr = _PyDict_GetItemIdWithError(m->md_dict, &PyId___getattr__); if (getattr) { return PyObject_CallOneArg(getattr, name); } - mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__); + if (PyErr_Occurred()) { + return NULL; + } + mod_name = _PyDict_GetItemIdWithError(m->md_dict, &PyId___name__); if (mod_name && PyUnicode_Check(mod_name)) { Py_INCREF(mod_name); - PyObject *spec = _PyDict_GetItemId(m->md_dict, &PyId___spec__); + PyObject *spec = _PyDict_GetItemIdWithError(m->md_dict, &PyId___spec__); + if (spec == NULL && PyErr_Occurred()) { + Py_DECREF(mod_name); + return NULL; + } Py_XINCREF(spec); if (_PyModuleSpec_IsInitializing(spec)) { PyErr_Format(PyExc_AttributeError, @@ -746,6 +762,9 @@ module_getattro(PyModuleObject *m, PyObject *name) Py_DECREF(mod_name); return NULL; } + else if (PyErr_Occurred()) { + return NULL; + } } PyErr_Format(PyExc_AttributeError, "module has no attribute '%U'", name); @@ -791,8 +810,6 @@ module_clear(PyModuleObject *m) static PyObject * module_dir(PyObject *self, PyObject *args) { - _Py_IDENTIFIER(__dict__); - _Py_IDENTIFIER(__dir__); PyObject *result = NULL; PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__); @@ -807,11 +824,7 @@ module_dir(PyObject *self, PyObject *args) } } else { - const char *name = PyModule_GetName(self); - if (name) - PyErr_Format(PyExc_TypeError, - "%.200s.__dict__ is not a dictionary", - name); + PyErr_Format(PyExc_TypeError, ".__dict__ is not a dictionary"); } } @@ -825,6 +838,78 @@ static PyMethodDef module_methods[] = { {0} }; +static PyObject * +module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored)) +{ + PyObject *dict = _PyObject_GetAttrId((PyObject *)m, &PyId___dict__); + + if ((dict == NULL) || !PyDict_Check(dict)) { + PyErr_Format(PyExc_TypeError, ".__dict__ is not a dictionary"); + Py_XDECREF(dict); + return NULL; + } + + PyObject *annotations; + /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */ + if (_PyDict_ContainsId(dict, &PyId___annotations__)) { + annotations = _PyDict_GetItemIdWithError(dict, &PyId___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 { + annotations = PyDict_New(); + if (annotations) { + int result = _PyDict_SetItemId(dict, &PyId___annotations__, annotations); + if (result) { + Py_CLEAR(annotations); + } + } + } + Py_DECREF(dict); + return annotations; +} + +static int +module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignored)) +{ + int ret = -1; + PyObject *dict = _PyObject_GetAttrId((PyObject *)m, &PyId___dict__); + + if ((dict == NULL) || !PyDict_Check(dict)) { + PyErr_Format(PyExc_TypeError, ".__dict__ is not a dictionary"); + goto exit; + } + + if (value != NULL) { + /* set */ + ret = _PyDict_SetItemId(dict, &PyId___annotations__, value); + goto exit; + } + + /* delete */ + if (!_PyDict_ContainsId(dict, &PyId___annotations__)) { + PyErr_Format(PyExc_AttributeError, "__annotations__"); + goto exit; + } + + ret = _PyDict_DelItemId(dict, &PyId___annotations__); + +exit: + Py_XDECREF(dict); + return ret; +} + + +static PyGetSetDef module_getsets[] = { + {"__annotations__", (getter)module_get_annotations, (setter)module_set_annotations}, + {NULL} +}; + PyTypeObject PyModule_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "module", /* tp_name */ @@ -856,7 +941,7 @@ PyTypeObject PyModule_Type = { 0, /* tp_iternext */ module_methods, /* tp_methods */ module_members, /* tp_members */ - 0, /* tp_getset */ + module_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ diff --git a/contrib/tools/python3/src/Objects/object.c b/contrib/tools/python3/src/Objects/object.c index 623ee52eb1e..47c352e3d64 100644 --- a/contrib/tools/python3/src/Objects/object.c +++ b/contrib/tools/python3/src/Objects/object.c @@ -10,9 +10,16 @@ #include "pycore_pylifecycle.h" #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_symtable.h" // PySTEntry_Type +#include "pycore_unionobject.h" // _PyUnion_Type #include "frameobject.h" #include "interpreteridobject.h" +#ifdef Py_LIMITED_API + // Prevent recursive call _Py_IncRef() <=> Py_INCREF() +# error "Py_LIMITED_API macro must not be defined" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -66,8 +73,7 @@ _Py_GetRefTotal(void) void _PyDebug_PrintTotalRefs(void) { fprintf(stderr, - "[%" PY_FORMAT_SIZE_T "d refs, " - "%" PY_FORMAT_SIZE_T "d blocks]\n", + "[%zd refs, %zd blocks]\n", _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); } #endif /* Py_REF_DEBUG */ @@ -137,36 +143,48 @@ Py_DecRef(PyObject *o) Py_XDECREF(o); } +void +_Py_IncRef(PyObject *o) +{ + Py_INCREF(o); +} + +void +_Py_DecRef(PyObject *o) +{ + Py_DECREF(o); +} + PyObject * PyObject_Init(PyObject *op, PyTypeObject *tp) { - /* Any changes should be reflected in PyObject_INIT() macro */ if (op == NULL) { return PyErr_NoMemory(); } - return PyObject_INIT(op, tp); + _PyObject_Init(op, tp); + return op; } PyVarObject * PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) { - /* Any changes should be reflected in PyObject_INIT_VAR() macro */ if (op == NULL) { return (PyVarObject *) PyErr_NoMemory(); } - return PyObject_INIT_VAR(op, tp, size); + _PyObject_InitVar(op, tp, size); + return op; } PyObject * _PyObject_New(PyTypeObject *tp) { - PyObject *op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp)); + PyObject *op = (PyObject *) PyObject_Malloc(_PyObject_SIZE(tp)); if (op == NULL) { return PyErr_NoMemory(); } - PyObject_INIT(op, tp); + _PyObject_Init(op, tp); return op; } @@ -175,10 +193,12 @@ _PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems) { PyVarObject *op; const size_t size = _PyObject_VAR_SIZE(tp, nitems); - op = (PyVarObject *) PyObject_MALLOC(size); - if (op == NULL) + op = (PyVarObject *) PyObject_Malloc(size); + if (op == NULL) { return (PyVarObject *)PyErr_NoMemory(); - return PyObject_INIT_VAR(op, tp, nitems); + } + _PyObject_InitVar(op, tp, nitems); + return op; } void @@ -854,50 +874,80 @@ _PyObject_GetAttrId(PyObject *v, _Py_Identifier *name) } int -_PyObject_HasAttrId(PyObject *v, _Py_Identifier *name) +_PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w) { int result; PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ if (!oname) return -1; - result = PyObject_HasAttr(v, oname); + result = PyObject_SetAttr(v, oname, w); return result; } -int -_PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w) +static inline int +set_attribute_error_context(PyObject* v, PyObject* name) { - int result; - PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ - if (!oname) - return -1; - result = PyObject_SetAttr(v, oname, w); - return result; + assert(PyErr_Occurred()); + _Py_IDENTIFIER(name); + _Py_IDENTIFIER(obj); + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + 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)) { + goto restore; + } + PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value; + // 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_SetAttrId(value, &PyId_name, name) || + _PyObject_SetAttrId(value, &PyId_obj, v)) { + return 1; + } +restore: + PyErr_Restore(type, value, traceback); + return 0; } PyObject * PyObject_GetAttr(PyObject *v, PyObject *name) { PyTypeObject *tp = Py_TYPE(v); - if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", Py_TYPE(name)->tp_name); return NULL; } - if (tp->tp_getattro != NULL) - return (*tp->tp_getattro)(v, name); - if (tp->tp_getattr != NULL) { + + PyObject* result = NULL; + if (tp->tp_getattro != NULL) { + result = (*tp->tp_getattro)(v, name); + } + else if (tp->tp_getattr != NULL) { const char *name_str = PyUnicode_AsUTF8(name); - if (name_str == NULL) + if (name_str == NULL) { return NULL; - return (*tp->tp_getattr)(v, (char *)name_str); + } + result = (*tp->tp_getattr)(v, (char *)name_str); } - PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", - tp->tp_name, name); - return NULL; + else { + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); + } + + if (result == NULL) { + set_attribute_error_context(v, name); + } + return result; } int @@ -1156,6 +1206,8 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%U'", tp->tp_name, name); + + set_attribute_error_context(obj, name); return 0; } @@ -1168,7 +1220,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, /* Make sure the logic of _PyObject_GetMethod is in sync with this method. - When suppress=1, this function suppress AttributeError. + When suppress=1, this function suppresses AttributeError. */ PyTypeObject *tp = Py_TYPE(obj); @@ -1386,7 +1438,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) } -/* Test a value used as condition, e.g., in a for or if statement. +/* Test a value used as condition, e.g., in a while or if statement. Return -1 if an error occurred */ int @@ -1738,82 +1790,109 @@ _PyTypes_Init(void) return status; } -#define INIT_TYPE(TYPE, NAME) \ +#define INIT_TYPE(TYPE) \ do { \ - if (PyType_Ready(TYPE) < 0) { \ - return _PyStatus_ERR("Can't initialize " NAME " type"); \ + if (PyType_Ready(&(TYPE)) < 0) { \ + return _PyStatus_ERR("Can't initialize " #TYPE " type"); \ } \ } while (0) - INIT_TYPE(&PyBaseObject_Type, "object"); - INIT_TYPE(&PyType_Type, "type"); - INIT_TYPE(&_PyWeakref_RefType, "weakref"); - INIT_TYPE(&_PyWeakref_CallableProxyType, "callable weakref proxy"); - INIT_TYPE(&_PyWeakref_ProxyType, "weakref proxy"); - INIT_TYPE(&PyLong_Type, "int"); - INIT_TYPE(&PyBool_Type, "bool"); - INIT_TYPE(&PyByteArray_Type, "bytearray"); - INIT_TYPE(&PyBytes_Type, "str"); - INIT_TYPE(&PyList_Type, "list"); - INIT_TYPE(&_PyNone_Type, "None"); - INIT_TYPE(&_PyNotImplemented_Type, "NotImplemented"); - INIT_TYPE(&PyTraceBack_Type, "traceback"); - INIT_TYPE(&PySuper_Type, "super"); - INIT_TYPE(&PyRange_Type, "range"); - INIT_TYPE(&PyDict_Type, "dict"); - INIT_TYPE(&PyDictKeys_Type, "dict keys"); - INIT_TYPE(&PyDictValues_Type, "dict values"); - INIT_TYPE(&PyDictItems_Type, "dict items"); - INIT_TYPE(&PyDictRevIterKey_Type, "reversed dict keys"); - INIT_TYPE(&PyDictRevIterValue_Type, "reversed dict values"); - INIT_TYPE(&PyDictRevIterItem_Type, "reversed dict items"); - INIT_TYPE(&PyODict_Type, "OrderedDict"); - INIT_TYPE(&PyODictKeys_Type, "odict_keys"); - INIT_TYPE(&PyODictItems_Type, "odict_items"); - INIT_TYPE(&PyODictValues_Type, "odict_values"); - INIT_TYPE(&PyODictIter_Type, "odict_keyiterator"); - INIT_TYPE(&PySet_Type, "set"); - INIT_TYPE(&PyUnicode_Type, "str"); - INIT_TYPE(&PySlice_Type, "slice"); - INIT_TYPE(&PyStaticMethod_Type, "static method"); - INIT_TYPE(&PyComplex_Type, "complex"); - INIT_TYPE(&PyFloat_Type, "float"); - INIT_TYPE(&PyFrozenSet_Type, "frozenset"); - INIT_TYPE(&PyProperty_Type, "property"); - INIT_TYPE(&_PyManagedBuffer_Type, "managed buffer"); - INIT_TYPE(&PyMemoryView_Type, "memoryview"); - INIT_TYPE(&PyTuple_Type, "tuple"); - INIT_TYPE(&PyEnum_Type, "enumerate"); - INIT_TYPE(&PyReversed_Type, "reversed"); - INIT_TYPE(&PyStdPrinter_Type, "StdPrinter"); - INIT_TYPE(&PyCode_Type, "code"); - INIT_TYPE(&PyFrame_Type, "frame"); - INIT_TYPE(&PyCFunction_Type, "builtin function"); - INIT_TYPE(&PyCMethod_Type, "builtin method"); - INIT_TYPE(&PyMethod_Type, "method"); - INIT_TYPE(&PyFunction_Type, "function"); - INIT_TYPE(&PyDictProxy_Type, "dict proxy"); - INIT_TYPE(&PyGen_Type, "generator"); - INIT_TYPE(&PyGetSetDescr_Type, "get-set descriptor"); - INIT_TYPE(&PyWrapperDescr_Type, "wrapper"); - INIT_TYPE(&_PyMethodWrapper_Type, "method wrapper"); - INIT_TYPE(&PyEllipsis_Type, "ellipsis"); - INIT_TYPE(&PyMemberDescr_Type, "member descriptor"); - INIT_TYPE(&_PyNamespace_Type, "namespace"); - INIT_TYPE(&PyCapsule_Type, "capsule"); - INIT_TYPE(&PyLongRangeIter_Type, "long range iterator"); - INIT_TYPE(&PyCell_Type, "cell"); - INIT_TYPE(&PyInstanceMethod_Type, "instance method"); - INIT_TYPE(&PyClassMethodDescr_Type, "class method descr"); - INIT_TYPE(&PyMethodDescr_Type, "method descr"); - INIT_TYPE(&PyCallIter_Type, "call iter"); - INIT_TYPE(&PySeqIter_Type, "sequence iterator"); - INIT_TYPE(&PyPickleBuffer_Type, "pickle.PickleBuffer"); - INIT_TYPE(&PyCoro_Type, "coroutine"); - INIT_TYPE(&_PyCoroWrapper_Type, "coroutine wrapper"); - INIT_TYPE(&_PyInterpreterID_Type, "interpreter ID"); - return _PyStatus_OK(); + // Base types + INIT_TYPE(PyBaseObject_Type); + INIT_TYPE(PyType_Type); + assert(PyBaseObject_Type.tp_base == NULL); + assert(PyType_Type.tp_base == &PyBaseObject_Type); + + // All other static types + INIT_TYPE(PyAsyncGen_Type); + INIT_TYPE(PyBool_Type); + INIT_TYPE(PyByteArrayIter_Type); + INIT_TYPE(PyByteArray_Type); + INIT_TYPE(PyBytesIter_Type); + INIT_TYPE(PyBytes_Type); + INIT_TYPE(PyCFunction_Type); + INIT_TYPE(PyCMethod_Type); + INIT_TYPE(PyCallIter_Type); + INIT_TYPE(PyCapsule_Type); + INIT_TYPE(PyCell_Type); + INIT_TYPE(PyClassMethodDescr_Type); + INIT_TYPE(PyClassMethod_Type); + INIT_TYPE(PyCode_Type); + INIT_TYPE(PyComplex_Type); + INIT_TYPE(PyCoro_Type); + INIT_TYPE(PyDictItems_Type); + INIT_TYPE(PyDictIterItem_Type); + INIT_TYPE(PyDictIterKey_Type); + INIT_TYPE(PyDictIterValue_Type); + INIT_TYPE(PyDictKeys_Type); + INIT_TYPE(PyDictProxy_Type); + INIT_TYPE(PyDictRevIterItem_Type); + INIT_TYPE(PyDictRevIterKey_Type); + INIT_TYPE(PyDictRevIterValue_Type); + INIT_TYPE(PyDictValues_Type); + INIT_TYPE(PyDict_Type); + INIT_TYPE(PyEllipsis_Type); + INIT_TYPE(PyEnum_Type); + INIT_TYPE(PyFloat_Type); + INIT_TYPE(PyFrame_Type); + INIT_TYPE(PyFrozenSet_Type); + INIT_TYPE(PyFunction_Type); + INIT_TYPE(PyGen_Type); + INIT_TYPE(PyGetSetDescr_Type); + INIT_TYPE(PyInstanceMethod_Type); + INIT_TYPE(PyListIter_Type); + INIT_TYPE(PyListRevIter_Type); + INIT_TYPE(PyList_Type); + INIT_TYPE(PyLongRangeIter_Type); + INIT_TYPE(PyLong_Type); + INIT_TYPE(PyMemberDescr_Type); + INIT_TYPE(PyMemoryView_Type); + INIT_TYPE(PyMethodDescr_Type); + INIT_TYPE(PyMethod_Type); + INIT_TYPE(PyModuleDef_Type); + INIT_TYPE(PyModule_Type); + INIT_TYPE(PyODictItems_Type); + INIT_TYPE(PyODictIter_Type); + INIT_TYPE(PyODictKeys_Type); + INIT_TYPE(PyODictValues_Type); + INIT_TYPE(PyODict_Type); + INIT_TYPE(PyPickleBuffer_Type); + INIT_TYPE(PyProperty_Type); + INIT_TYPE(PyRangeIter_Type); + INIT_TYPE(PyRange_Type); + INIT_TYPE(PyReversed_Type); + INIT_TYPE(PySTEntry_Type); + INIT_TYPE(PySeqIter_Type); + INIT_TYPE(PySetIter_Type); + INIT_TYPE(PySet_Type); + INIT_TYPE(PySlice_Type); + INIT_TYPE(PyStaticMethod_Type); + INIT_TYPE(PyStdPrinter_Type); + INIT_TYPE(PySuper_Type); + INIT_TYPE(PyTraceBack_Type); + INIT_TYPE(PyTupleIter_Type); + INIT_TYPE(PyTuple_Type); + INIT_TYPE(PyUnicodeIter_Type); + INIT_TYPE(PyUnicode_Type); + INIT_TYPE(PyWrapperDescr_Type); + INIT_TYPE(Py_GenericAliasType); + INIT_TYPE(_PyAnextAwaitable_Type); + INIT_TYPE(_PyAsyncGenASend_Type); + INIT_TYPE(_PyAsyncGenAThrow_Type); + INIT_TYPE(_PyAsyncGenWrappedValue_Type); + INIT_TYPE(_PyCoroWrapper_Type); + INIT_TYPE(_PyInterpreterID_Type); + INIT_TYPE(_PyManagedBuffer_Type); + INIT_TYPE(_PyMethodWrapper_Type); + INIT_TYPE(_PyNamespace_Type); + INIT_TYPE(_PyNone_Type); + INIT_TYPE(_PyNotImplemented_Type); + INIT_TYPE(_PyWeakref_CallableProxyType); + INIT_TYPE(_PyWeakref_ProxyType); + INIT_TYPE(_PyWeakref_RefType); + INIT_TYPE(_PyUnion_Type); + return _PyStatus_OK(); #undef INIT_TYPE } @@ -1876,9 +1955,10 @@ _Py_PrintReferences(FILE *fp) PyObject *op; fprintf(fp, "Remaining objects:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { - fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, Py_REFCNT(op)); - if (PyObject_Print(op, fp, 0) != 0) + fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op)); + if (PyObject_Print(op, fp, 0) != 0) { PyErr_Clear(); + } putc('\n', fp); } } @@ -1892,7 +1972,7 @@ _Py_PrintReferenceAddresses(FILE *fp) PyObject *op; fprintf(fp, "Remaining object addresses:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) - fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", (void *)op, + fprintf(fp, "%p [%zd] %s\n", (void *)op, Py_REFCNT(op), Py_TYPE(op)->tp_name); } @@ -2029,8 +2109,8 @@ finally: void _PyTrash_deposit_object(PyObject *op) { - PyThreadState *tstate = _PyThreadState_GET(); - struct _gc_runtime_state *gcstate = &tstate->interp->gc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _gc_runtime_state *gcstate = &interp->gc; _PyObject_ASSERT(op, _PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); @@ -2057,8 +2137,8 @@ _PyTrash_thread_deposit_object(PyObject *op) void _PyTrash_destroy_chain(void) { - PyThreadState *tstate = _PyThreadState_GET(); - struct _gc_runtime_state *gcstate = &tstate->interp->gc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _gc_runtime_state *gcstate = &interp->gc; while (gcstate->trash_delete_later) { PyObject *op = gcstate->trash_delete_later; @@ -2143,6 +2223,15 @@ _PyTrash_end(PyThreadState *tstate) } +/* bpo-40170: It's only be used in Py_TRASHCAN_BEGIN macro to hide + implementation details. */ +int +_PyTrash_cond(PyObject *op, destructor dealloc) +{ + return Py_TYPE(op)->tp_dealloc == dealloc; +} + + void _Py_NO_RETURN _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, const char *file, int line, const char *function) @@ -2217,6 +2306,49 @@ PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) } +#undef Py_NewRef +#undef Py_XNewRef + +// Export Py_NewRef() and Py_XNewRef() as regular functions for the stable ABI. +PyObject* +Py_NewRef(PyObject *obj) +{ + return _Py_NewRef(obj); +} + +PyObject* +Py_XNewRef(PyObject *obj) +{ + return _Py_XNewRef(obj); +} + +#undef Py_Is +#undef Py_IsNone +#undef Py_IsTrue +#undef Py_IsFalse + +// Export Py_Is(), Py_IsNone(), Py_IsTrue(), Py_IsFalse() as regular functions +// for the stable ABI. +int Py_Is(PyObject *x, PyObject *y) +{ + return (x == y); +} + +int Py_IsNone(PyObject *x) +{ + return Py_Is(x, Py_None); +} + +int Py_IsTrue(PyObject *x) +{ + return Py_Is(x, Py_True); +} + +int Py_IsFalse(PyObject *x) +{ + return Py_Is(x, Py_False); +} + #ifdef __cplusplus } #endif diff --git a/contrib/tools/python3/src/Objects/obmalloc.c b/contrib/tools/python3/src/Objects/obmalloc.c index 9f8e0d114ff..615703a963e 100644 --- a/contrib/tools/python3/src/Objects/obmalloc.c +++ b/contrib/tools/python3/src/Objects/obmalloc.c @@ -894,6 +894,22 @@ static int running_on_valgrind = -1; #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 blocks of memory (called arenas) aligned * on a page boundary. This is a reserved virtual address space for the @@ -907,18 +923,34 @@ static int running_on_valgrind = -1; * Arenas are allocated with mmap() on systems supporting anonymous memory * mappings to reduce heap fragmentation. */ -#define ARENA_SIZE (256 << 10) /* 256KB */ +#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. Should be a power of 2, - * between 1K and SYSTEM_PAGE_SIZE, that is: 1k, 2k, 4k. + * Size of the pools used for small blocks. Must be a power of 2. */ -#define POOL_SIZE SYSTEM_PAGE_SIZE /* must be 2^N */ -#define POOL_SIZE_MASK SYSTEM_PAGE_SIZE_MASK +#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 @@ -1233,6 +1265,264 @@ _Py_GetAllocatedBlocks(void) return n; } +#if WITH_PYMALLOC_RADIX_TREE +/*==========================================================================*/ +/* radix tree for tracking arena usage + + bit allocation for keys + + 64-bit pointers and 2^20 arena size: + 16 -> ignored (POINTER_BITS - ADDRESS_BITS) + 10 -> MAP_TOP + 10 -> MAP_MID + 8 -> MAP_BOT + 20 -> ideal aligned arena + ---- + 64 + + 32-bit pointers and 2^18 arena size: + 14 -> MAP_BOT + 18 -> ideal aligned arena + ---- + 32 + +*/ + +#if SIZEOF_VOID_P == 8 + +/* number of bits in a pointer */ +#define POINTER_BITS 64 + +/* Current 64-bit processors are limited to 48-bit physical addresses. For + * now, the top 17 bits of addresses will all be equal to bit 2**47. If that + * changes in the future, this must be adjusted upwards. + */ +#define ADDRESS_BITS 48 + +/* use the top and mid layers of the radix tree */ +#define USE_INTERIOR_NODES + +#elif SIZEOF_VOID_P == 4 + +#define POINTER_BITS 32 +#define ADDRESS_BITS 32 + +#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 + +#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 ADDRESS_BITS > POINTER_BITS +/* Return non-physical address bits of a pointer. Those bits should be same + * for all valid pointers if ADDRESS_BITS set correctly. Linux has support for + * 57-bit address space (Intel 5-level paging) but will not currently give + * those addresses to user space. + */ +#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 + +/* 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 +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; +#endif + +/* Return a pointer to a bottom tree node, return NULL if it doesn't exist or + * it cannot be created */ +static arena_map_bot_t * +arena_map_get(block *p, int create) +{ +#ifdef USE_INTERIOR_NODES + /* sanity check that ADDRESS_BITS is correct */ + assert(HIGH_BITS(p) == HIGH_BITS(&arena_map_root)); + int i1 = MAP_TOP_INDEX(p); + if (arena_map_root.ptrs[i1] == NULL) { + if (!create) { + return NULL; + } + arena_map_mid_t *n = PyMem_RawCalloc(1, sizeof(arena_map_mid_t)); + if (n == NULL) { + return NULL; + } + arena_map_root.ptrs[i1] = n; + arena_map_mid_count++; + } + int i2 = MAP_MID_INDEX(p); + if (arena_map_root.ptrs[i1]->ptrs[i2] == NULL) { + if (!create) { + return NULL; + } + arena_map_bot_t *n = PyMem_RawCalloc(1, sizeof(arena_map_bot_t)); + if (n == NULL) { + return NULL; + } + arena_map_root.ptrs[i1]->ptrs[i2] = n; + arena_map_bot_count++; + } + return arena_map_root.ptrs[i1]->ptrs[i2]; +#else + return &arena_map_root; +#endif +} + + +/* The radix tree only tracks arenas. So, for 16 MiB arenas, we throw + * away 24 bits of the address. That reduces the space requirement of + * the tree compared to similar radix tree page-map schemes. In + * exchange for slashing the space requirement, it needs more + * computation to check an address. + * + * Tracking coverage is done by "ideal" arena address. It is easier to + * explain in decimal so let's say that the arena size is 100 bytes. + * Then, ideal addresses are 100, 200, 300, etc. For checking if a + * pointer address is inside an actual arena, we have to check two ideal + * arena addresses. E.g. if pointer is 357, we need to check 200 and + * 300. In the rare case that an arena is aligned in the ideal way + * (e.g. base address of arena is 200) then we only have to check one + * ideal address. + * + * The tree nodes for 200 and 300 both store the address of arena. + * There are two cases: the arena starts at a lower ideal arena and + * extends to this one, or the arena starts in this arena and extends to + * the next ideal arena. The tail_lo and tail_hi members correspond to + * these two cases. + */ + + +/* mark or unmark addresses covered by arena */ +static int +arena_map_mark_used(uintptr_t arena_base, int is_used) +{ + /* sanity check that ADDRESS_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); + 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); + int32_t tail = (int32_t)(arena_base & ARENA_SIZE_MASK); + if (tail == 0) { + /* is ideal arena address */ + n_hi->arenas[i3].tail_hi = is_used ? -1 : 0; + } + else { + /* arena_base address is not ideal (aligned to arena size) and + * so it potentially covers two MAP_BOT nodes. Get the MAP_BOT node + * for the next arena. Note that it might be in different MAP_TOP + * and MAP_MID nodes as well so we need to call arena_map_get() + * again (do the full tree traversal). + */ + n_hi->arenas[i3].tail_hi = is_used ? tail : 0; + uintptr_t arena_base_next = arena_base + ARENA_SIZE; + /* If arena_base is a legit arena address, so is arena_base_next - 1 + * (last address in arena). If arena_base_next overflows then it + * 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); + if (n_lo == NULL) { + assert(is_used); /* otherwise should already exist */ + n_hi->arenas[i3].tail_hi = 0; + return 0; /* failed to allocate space for node */ + } + int i3_next = MAP_BOT_INDEX(arena_base_next); + n_lo->arenas[i3_next].tail_lo = is_used ? tail : 0; + } + return 1; +} + +/* 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_bot_t *n = arena_map_get(p, 0); + if (n == NULL) { + return 0; + } + int i3 = MAP_BOT_INDEX(p); + /* ARENA_BITS must be < 32 so that the tail is a non-negative int32_t. */ + int32_t hi = n->arenas[i3].tail_hi; + int32_t lo = n->arenas[i3].tail_lo; + int32_t tail = (int32_t)(AS_UINT(p) & ARENA_SIZE_MASK); + return (tail < lo) || (tail >= hi && hi != 0); +} + +/* end of radix tree logic */ +/*==========================================================================*/ +#endif /* WITH_PYMALLOC_RADIX_TREE */ + /* Allocate a new arena. If we run out of memory, return NULL. Else * allocate a new arena, and return the address of an arena_object @@ -1302,6 +1592,15 @@ new_arena(void) unused_arena_objects = arenaobj->nextarena; assert(arenaobj->address == 0); 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)) { + /* marking arena in radix tree failed, abort */ + _PyObject_Arena.free(_PyObject_Arena.ctx, address, ARENA_SIZE); + address = NULL; + } + } +#endif if (address == NULL) { /* The allocation failed: return NULL after putting the * arenaobj back. @@ -1332,6 +1631,17 @@ new_arena(void) } + +#if WITH_PYMALLOC_RADIX_TREE +/* Return true if and only if P is an address that was allocated by + pymalloc. When the radix tree is used, 'poolp' is unused. + */ +static bool +address_in_range(void *p, poolp pool) +{ + return arena_map_is_used(p); +} +#else /* address_in_range(P, POOL) @@ -1423,6 +1733,7 @@ address_in_range(void *p, poolp pool) arenas[arenaindex].address != 0; } +#endif /* !WITH_PYMALLOC_RADIX_TREE */ /*==========================================================================*/ @@ -1768,6 +2079,11 @@ insert_to_freepool(poolp pool) ao->nextarena = unused_arena_objects; unused_arena_objects = ao; +#if WITH_PYMALLOC_RADIX_TREE + /* mark arena region as not under control of obmalloc */ + arena_map_mark_used(ao->address, 0); +#endif + /* Free the entire arena. */ _PyObject_Arena.free(_PyObject_Arena.ctx, (void *)ao->address, ARENA_SIZE); @@ -2420,8 +2736,7 @@ _PyObject_DebugDumpAddress(const void *p) fprintf(stderr, " API '%c'\n", id); nbytes = read_size_t(q - 2*SST); - fprintf(stderr, " %" PY_FORMAT_SIZE_T "u bytes originally " - "requested\n", nbytes); + fprintf(stderr, " %zu bytes originally requested\n", nbytes); /* In case this is nuts, check the leading pad bytes first. */ fprintf(stderr, " The %d pad bytes at p-%d are ", SST-1, SST-1); @@ -2477,8 +2792,9 @@ _PyObject_DebugDumpAddress(const void *p) #ifdef PYMEM_DEBUG_SERIALNO size_t serial = read_size_t(tail + SST); - fprintf(stderr, " The block was made by call #%" PY_FORMAT_SIZE_T - "u to debug malloc/realloc.\n", serial); + fprintf(stderr, + " The block was made by call #%zu to debug malloc/realloc.\n", + serial); #endif if (nbytes > 0) { @@ -2553,7 +2869,7 @@ _PyDebugAllocatorStats(FILE *out, char buf1[128]; char buf2[128]; PyOS_snprintf(buf1, sizeof(buf1), - "%d %ss * %" PY_FORMAT_SIZE_T "d bytes each", + "%d %ss * %zd bytes each", num_blocks, block_name, sizeof_block); PyOS_snprintf(buf2, sizeof(buf2), "%48s ", buf1); @@ -2694,10 +3010,7 @@ _PyObject_DebugMallocStats(FILE *out) assert(b == 0 && f == 0); continue; } - fprintf(out, "%5u %6u " - "%11" PY_FORMAT_SIZE_T "u " - "%15" PY_FORMAT_SIZE_T "u " - "%13" PY_FORMAT_SIZE_T "u\n", + fprintf(out, "%5u %6u %11zu %15zu %13zu\n", i, size, p, b, f); allocated_bytes += b * size; available_bytes += f * size; @@ -2716,12 +3029,13 @@ _PyObject_DebugMallocStats(FILE *out) (void)printone(out, "# arenas allocated current", narenas); PyOS_snprintf(buf, sizeof(buf), - "%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena", - narenas, ARENA_SIZE); + "%zu arenas * %d bytes/arena", + narenas, ARENA_SIZE); (void)printone(out, buf, narenas * ARENA_SIZE); fputc('\n', out); + /* Account for what all of those arena bytes are being used for. */ total = printone(out, "# bytes in allocated blocks", allocated_bytes); total += printone(out, "# bytes in available blocks", available_bytes); @@ -2733,6 +3047,25 @@ _PyObject_DebugMallocStats(FILE *out) total += printone(out, "# bytes lost to quantization", quantization); total += printone(out, "# bytes lost to arena alignment", arena_alignment); (void)printone(out, "Total", total); + assert(narenas * ARENA_SIZE == total); + +#if WITH_PYMALLOC_RADIX_TREE + fputs("\narena map counts\n", out); +#ifdef USE_INTERIOR_NODES + (void)printone(out, "# arena map mid nodes", arena_map_mid_count); + (void)printone(out, "# arena map bot nodes", arena_map_bot_count); + fputc('\n', out); +#endif + total = printone(out, "# bytes lost to arena map root", sizeof(arena_map_root)); +#ifdef USE_INTERIOR_NODES + total += printone(out, "# bytes lost to arena map mid", + sizeof(arena_map_mid_t) * arena_map_mid_count); + total += printone(out, "# bytes lost to arena map bot", + sizeof(arena_map_bot_t) * arena_map_bot_count); + (void)printone(out, "Total", total); +#endif +#endif + return 1; } diff --git a/contrib/tools/python3/src/Objects/odictobject.c b/contrib/tools/python3/src/Objects/odictobject.c index f3980aba937..c0ccb16bc3d 100644 --- a/contrib/tools/python3/src/Objects/odictobject.c +++ b/contrib/tools/python3/src/Objects/odictobject.c @@ -459,7 +459,7 @@ later: - implement a fuller MutableMapping API in C? - move the MutableMapping implementation to abstract.c? - optimize mutablemapping_update -- use PyObject_MALLOC (small object allocator) for odict nodes? +- use PyObject_Malloc (small object allocator) for odict nodes? - support subclasses better (e.g. in odict_richcompare) */ @@ -567,14 +567,14 @@ _odict_resize(PyODictObject *od) i = _odict_get_index_raw(od, _odictnode_KEY(node), _odictnode_HASH(node)); if (i < 0) { - PyMem_FREE(fast_nodes); + PyMem_Free(fast_nodes); return -1; } fast_nodes[i] = node; } /* Replace the old fast nodes table. */ - PyMem_FREE(od->od_fast_nodes); + PyMem_Free(od->od_fast_nodes); od->od_fast_nodes = fast_nodes; od->od_fast_nodes_size = size; od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys; @@ -683,7 +683,7 @@ _odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash) } /* must not be added yet */ - node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode)); + node = (_ODictNode *)PyMem_Malloc(sizeof(_ODictNode)); if (node == NULL) { Py_DECREF(key); PyErr_NoMemory(); @@ -701,7 +701,7 @@ _odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash) #define _odictnode_DEALLOC(node) \ do { \ Py_DECREF(_odictnode_KEY(node)); \ - PyMem_FREE((void *)node); \ + PyMem_Free((void *)node); \ } while (0) /* Repeated calls on the same node are no-ops. */ @@ -776,7 +776,7 @@ _odict_clear_nodes(PyODictObject *od) { _ODictNode *node, *next; - PyMem_FREE(od->od_fast_nodes); + PyMem_Free(od->od_fast_nodes); od->od_fast_nodes = NULL; od->od_fast_nodes_size = 0; od->od_resize_sentinel = NULL; @@ -1045,30 +1045,28 @@ OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, /* pop() */ -PyDoc_STRVAR(odict_pop__doc__, -"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\ - value. If key is not found, d is returned if given, otherwise KeyError\n\ - is raised.\n\ -\n\ - "); - /* forward */ static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *); /* Skips __missing__() calls. */ -static PyObject * -odict_pop(PyObject *od, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"key", "default", 0}; - PyObject *key, *failobj = NULL; +/*[clinic input] +OrderedDict.pop - /* borrowed */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist, - &key, &failobj)) { - return NULL; - } + key: object + default: object = NULL + +od.pop(key[,default]) -> v, remove specified key and return the corresponding value. + +If the key is not found, return the default if given; otherwise, +raise a KeyError. +[clinic start generated code]*/ - return _odict_popkey(od, key, failobj); +static PyObject * +OrderedDict_pop_impl(PyODictObject *self, PyObject *key, + PyObject *default_value) +/*[clinic end generated code: output=7a6447d104e7494b input=7efe36601007dff7]*/ +{ + return _odict_popkey((PyObject *)self, key, default_value); } static PyObject * @@ -1363,8 +1361,7 @@ static PyMethodDef odict_methods[] = { {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS, odict_reduce__doc__}, ORDEREDDICT_SETDEFAULT_METHODDEF - {"pop", (PyCFunction)(void(*)(void))odict_pop, - METH_VARARGS | METH_KEYWORDS, odict_pop__doc__}, + ORDEREDDICT_POP_METHODDEF ORDEREDDICT_POPITEM_METHODDEF {"keys", odictkeys_new, METH_NOARGS, odict_keys__doc__}, diff --git a/contrib/tools/python3/src/Objects/rangeobject.c b/contrib/tools/python3/src/Objects/rangeobject.c index d7076ac8246..a848d67a651 100644 --- a/contrib/tools/python3/src/Objects/rangeobject.c +++ b/contrib/tools/python3/src/Objects/rangeobject.c @@ -1,8 +1,9 @@ /* Range object implementation */ #include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_tupleobject.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef /* Support objects whose length is > PY_SSIZE_T_MAX. @@ -105,10 +106,10 @@ range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args) if (!stop) { return NULL; } - Py_INCREF(_PyLong_Zero); - start = _PyLong_Zero; - Py_INCREF(_PyLong_One); - step = _PyLong_One; + start = _PyLong_GetZero(); + Py_INCREF(start); + step = _PyLong_GetOne(); + Py_INCREF(step); break; case 0: PyErr_SetString(PyExc_TypeError, @@ -170,7 +171,7 @@ range_dealloc(rangeobject *r) Py_DECREF(r->stop); Py_DECREF(r->step); Py_DECREF(r->length); - PyObject_Del(r); + PyObject_Free(r); } /* Return number of items in range (lo, hi, step) as a PyLong object, @@ -190,7 +191,10 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) PyObject *tmp1 = NULL, *tmp2 = NULL, *result; /* holds sub-expression evaluations */ - cmp_result = PyObject_RichCompareBool(step, _PyLong_Zero, Py_GT); + PyObject *zero = _PyLong_GetZero(); // borrowed reference + PyObject *one = _PyLong_GetOne(); // borrowed reference + + cmp_result = PyObject_RichCompareBool(step, zero, Py_GT); if (cmp_result == -1) return NULL; @@ -212,19 +216,21 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) Py_DECREF(step); if (cmp_result < 0) return NULL; - return PyLong_FromLong(0); + result = zero; + Py_INCREF(result); + return result; } if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) goto Fail; - if ((diff = PyNumber_Subtract(tmp1, _PyLong_One)) == NULL) + if ((diff = PyNumber_Subtract(tmp1, one)) == NULL) goto Fail; if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL) goto Fail; - if ((result = PyNumber_Add(tmp2, _PyLong_One)) == NULL) + if ((result = PyNumber_Add(tmp2, one)) == NULL) goto Fail; Py_DECREF(tmp2); @@ -254,17 +260,24 @@ compute_item(rangeobject *r, PyObject *i) /* PyLong equivalent to: * return r->start + (i * r->step) */ - incr = PyNumber_Multiply(i, r->step); - if (!incr) - return NULL; - result = PyNumber_Add(r->start, incr); - Py_DECREF(incr); + if (r->step == _PyLong_GetOne()) { + result = PyNumber_Add(r->start, i); + } + else { + incr = PyNumber_Multiply(i, r->step); + if (!incr) { + return NULL; + } + result = PyNumber_Add(r->start, incr); + Py_DECREF(incr); + } return result; } static PyObject * compute_range_item(rangeobject *r, PyObject *arg) { + PyObject *zero = _PyLong_GetZero(); // borrowed reference int cmp_result; PyObject *i, *result; @@ -275,7 +288,7 @@ compute_range_item(rangeobject *r, PyObject *arg) * i = arg * } */ - cmp_result = PyObject_RichCompareBool(arg, _PyLong_Zero, Py_LT); + cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT); if (cmp_result == -1) { return NULL; } @@ -294,7 +307,7 @@ compute_range_item(rangeobject *r, PyObject *arg) * * } */ - cmp_result = PyObject_RichCompareBool(i, _PyLong_Zero, Py_LT); + cmp_result = PyObject_RichCompareBool(i, zero, Py_LT); if (cmp_result == 0) { cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE); } @@ -369,6 +382,7 @@ fail: static int range_contains_long(rangeobject *r, PyObject *ob) { + PyObject *zero = _PyLong_GetZero(); // borrowed reference int cmp1, cmp2, cmp3; PyObject *tmp1 = NULL; PyObject *tmp2 = NULL; @@ -376,7 +390,7 @@ range_contains_long(rangeobject *r, PyObject *ob) /* Check if the value can possibly be in the range. */ - cmp1 = PyObject_RichCompareBool(r->step, _PyLong_Zero, Py_GT); + cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT); if (cmp1 == -1) goto end; if (cmp1 == 1) { /* positive steps: start <= ob < stop */ @@ -403,7 +417,7 @@ range_contains_long(rangeobject *r, PyObject *ob) if (tmp2 == NULL) goto end; /* result = ((int(ob) - start) % step) == 0 */ - result = PyObject_RichCompareBool(tmp2, _PyLong_Zero, Py_EQ); + result = PyObject_RichCompareBool(tmp2, zero, Py_EQ); end: Py_XDECREF(tmp1); Py_XDECREF(tmp2); @@ -454,7 +468,7 @@ range_equals(rangeobject *r0, rangeobject *r1) /* Return False or error to the caller. */ if (cmp_result != 1) return cmp_result; - cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_One, Py_EQ); + cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_GetOne(), Py_EQ); /* Return True or error to the caller. */ if (cmp_result != 0) return cmp_result; @@ -523,7 +537,7 @@ range_hash(rangeobject *r) else { Py_INCREF(r->start); PyTuple_SET_ITEM(t, 1, r->start); - cmp_result = PyObject_RichCompareBool(r->length, _PyLong_One, Py_EQ); + cmp_result = PyObject_RichCompareBool(r->length, _PyLong_GetOne(), Py_EQ); if (cmp_result == -1) goto end; if (cmp_result == 1) { @@ -576,13 +590,19 @@ range_index(rangeobject *r, PyObject *ob) return NULL; if (contains) { - PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start); - if (tmp == NULL) + PyObject *idx = PyNumber_Subtract(ob, r->start); + if (idx == NULL) { return NULL; + } + + if (r->step == _PyLong_GetOne()) { + return idx; + } + /* idx = (ob - r.start) // r.step */ - idx = PyNumber_FloorDivide(tmp, r->step); - Py_DECREF(tmp); - return idx; + PyObject *sidx = PyNumber_FloorDivide(idx, r->step); + Py_DECREF(idx); + return sidx; } /* object is not in the range */ @@ -715,7 +735,7 @@ PyTypeObject PyRange_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_SEQUENCE, /* tp_flags */ range_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -954,14 +974,15 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) static PyObject * longrangeiter_setstate(longrangeiterobject *r, PyObject *state) { + PyObject *zero = _PyLong_GetZero(); // borrowed reference int cmp; /* clip the value */ - cmp = PyObject_RichCompareBool(state, _PyLong_Zero, Py_LT); + cmp = PyObject_RichCompareBool(state, zero, Py_LT); if (cmp < 0) return NULL; if (cmp > 0) { - state = _PyLong_Zero; + state = zero; } else { cmp = PyObject_RichCompareBool(r->len, state, Py_LT); @@ -992,7 +1013,7 @@ longrangeiter_dealloc(longrangeiterobject *r) Py_XDECREF(r->start); Py_XDECREF(r->step); Py_XDECREF(r->len); - PyObject_Del(r); + PyObject_Free(r); } static PyObject * @@ -1002,7 +1023,7 @@ longrangeiter_next(longrangeiterobject *r) if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) return NULL; - new_index = PyNumber_Add(r->index, _PyLong_One); + new_index = PyNumber_Add(r->index, _PyLong_GetOne()); if (!new_index) return NULL; @@ -1109,7 +1130,7 @@ range_iter(PyObject *seq) it->start = r->start; it->step = r->step; it->len = r->length; - it->index = _PyLong_Zero; + it->index = _PyLong_GetZero(); Py_INCREF(it->start); Py_INCREF(it->step); Py_INCREF(it->len); @@ -1197,7 +1218,7 @@ long_range: it->len = range->length; Py_INCREF(it->len); - diff = PyNumber_Subtract(it->len, _PyLong_One); + diff = PyNumber_Subtract(it->len, _PyLong_GetOne()); if (!diff) goto create_failure; @@ -1216,7 +1237,7 @@ long_range: if (!it->step) goto create_failure; - it->index = _PyLong_Zero; + it->index = _PyLong_GetZero(); Py_INCREF(it->index); return (PyObject *)it; diff --git a/contrib/tools/python3/src/Objects/setobject.c b/contrib/tools/python3/src/Objects/setobject.c index 6d156bd4e08..e8ba32e5781 100644 --- a/contrib/tools/python3/src/Objects/setobject.c +++ b/contrib/tools/python3/src/Objects/setobject.c @@ -16,7 +16,7 @@ reduces the cost of hash collisions because consecutive memory accesses tend to be much cheaper than scattered probes. After LINEAR_PROBES steps, we then use more of the upper bits from the hash value and apply a simple - linear congruential random number genearator. This helps break-up long + linear congruential random number generator. This helps break-up long chains of collisions. All arithmetic on hash should ignore overflow. @@ -103,6 +103,7 @@ static int set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) { setentry *table; + setentry *freeslot; setentry *entry; size_t perturb; size_t mask; @@ -118,6 +119,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) mask = so->mask; i = (size_t)hash & mask; + freeslot = NULL; perturb = hash; while (1) { @@ -125,7 +127,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0; do { if (entry->hash == 0 && entry->key == NULL) - goto found_unused; + goto found_unused_or_dummy; if (entry->hash == hash) { PyObject *startkey = entry->key; assert(startkey != dummy); @@ -147,12 +149,24 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) goto restart; mask = so->mask; } + else if (entry->hash == -1) { + assert (entry->key == dummy); + freeslot = entry; + } entry++; } while (probes--); perturb >>= PERTURB_SHIFT; i = (i * 5 + 1 + perturb) & mask; } + found_unused_or_dummy: + if (freeslot == NULL) + goto found_unused; + so->used++; + freeslot->key = key; + freeslot->hash = hash; + return 0; + found_unused: so->fill++; so->used++; @@ -289,7 +303,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) } if (is_oldtable_malloced) - PyMem_DEL(oldtable); + PyMem_Free(oldtable); return 0; } @@ -424,7 +438,7 @@ set_clear_internal(PySetObject *so) } if (table_is_malloced) - PyMem_DEL(table); + PyMem_Free(table); return 0; } @@ -484,7 +498,7 @@ set_dealloc(PySetObject *so) } } if (so->table != so->smalltable) - PyMem_DEL(so->table); + PyMem_Free(so->table); Py_TYPE(so)->tp_free(so); Py_TRASHCAN_END } @@ -522,7 +536,7 @@ set_repr(PySetObject *so) goto done; listrepr = tmp; - if (!Py_IS_TYPE(so, &PySet_Type)) + if (!PySet_CheckExact(so)) result = PyUnicode_FromFormat("%s({%U})", Py_TYPE(so)->tp_name, listrepr); @@ -975,9 +989,6 @@ make_new_set_basetype(PyTypeObject *type, PyObject *iterable) return make_new_set(type, iterable); } -/* The empty frozenset is a singleton */ -static PyObject *emptyfrozenset = NULL; - static PyObject * make_new_frozenset(PyTypeObject *type, PyObject *iterable) { @@ -985,26 +996,12 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable) return make_new_set(type, iterable); } - if (iterable != NULL) { - if (PyFrozenSet_CheckExact(iterable)) { - /* frozenset(f) is idempotent */ - Py_INCREF(iterable); - return iterable; - } - PyObject *res = make_new_set((PyTypeObject *)type, iterable); - if (res == NULL || PySet_GET_SIZE(res) != 0) { - return res; - } - /* If the created frozenset is empty, return the empty frozenset singleton instead */ - Py_DECREF(res); - } - - // The empty frozenset is a singleton - if (emptyfrozenset == NULL) { - emptyfrozenset = make_new_set((PyTypeObject *)type, NULL); + if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) { + /* frozenset(f) is idempotent */ + Py_INCREF(iterable); + return iterable; } - Py_XINCREF(emptyfrozenset); - return emptyfrozenset; + return make_new_set((PyTypeObject *)type, iterable); } static PyObject * @@ -1530,7 +1527,7 @@ set_difference(PySetObject *so, PyObject *other) key = entry->key; hash = entry->hash; Py_INCREF(key); - rv = _PyDict_Contains(other, key, hash); + rv = _PyDict_Contains_KnownHash(other, key, hash); if (rv < 0) { Py_DECREF(result); Py_DECREF(key); @@ -2141,7 +2138,8 @@ PyTypeObject PySet_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | + _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ set_doc, /* tp_doc */ (traverseproc)set_traverse, /* tp_traverse */ (inquiry)set_clear_internal, /* tp_clear */ @@ -2241,7 +2239,8 @@ PyTypeObject PyFrozenSet_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | + _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ frozenset_doc, /* tp_doc */ (traverseproc)set_traverse, /* tp_traverse */ (inquiry)set_clear_internal, /* tp_clear */ @@ -2330,12 +2329,6 @@ PySet_Add(PyObject *anyset, PyObject *key) return set_add_key((PySetObject *)anyset, key); } -void -_PySet_Fini(void) -{ - Py_CLEAR(emptyfrozenset); -} - int _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash) { @@ -2558,4 +2551,3 @@ static PyObject _dummy_struct = { _PyObject_EXTRA_INIT 2, &_PySetDummy_Type }; - diff --git a/contrib/tools/python3/src/Objects/sliceobject.c b/contrib/tools/python3/src/Objects/sliceobject.c index 391711f711a..22fb7c61c35 100644 --- a/contrib/tools/python3/src/Objects/sliceobject.c +++ b/contrib/tools/python3/src/Objects/sliceobject.c @@ -15,7 +15,8 @@ this type and there is exactly one in existence. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_object.h" +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_object.h" // _PyObject_GC_TRACK() #include "structmember.h" // PyMemberDef static PyObject * @@ -95,16 +96,12 @@ PyObject _Py_EllipsisObject = { /* Slice object implementation */ -/* Using a cache is very effective since typically only a single slice is - * created and then deleted again - */ -static PySliceObject *slice_cache = NULL; -void _PySlice_Fini(void) +void _PySlice_Fini(PyInterpreterState *interp) { - PySliceObject *obj = slice_cache; + PySliceObject *obj = interp->slice_cache; if (obj != NULL) { - slice_cache = NULL; + interp->slice_cache = NULL; PyObject_GC_Del(obj); } } @@ -116,26 +113,35 @@ void _PySlice_Fini(void) 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; + } + + PyInterpreterState *interp = _PyInterpreterState_GET(); PySliceObject *obj; - if (slice_cache != NULL) { - obj = slice_cache; - slice_cache = NULL; + if (interp->slice_cache != NULL) { + obj = interp->slice_cache; + interp->slice_cache = NULL; _Py_NewReference((PyObject *)obj); - } else { + } + else { obj = PyObject_GC_New(PySliceObject, &PySlice_Type); - if (obj == NULL) + if (obj == NULL) { return NULL; + } } - if (step == NULL) step = Py_None; Py_INCREF(step); - if (start == NULL) start = Py_None; - Py_INCREF(start); - if (stop == NULL) stop = Py_None; - Py_INCREF(stop); - obj->step = step; + Py_INCREF(start); obj->start = start; + Py_INCREF(stop); obj->stop = stop; _PyObject_GC_TRACK(obj); @@ -324,14 +330,17 @@ Create a slice object. This is used for extended slicing (e.g. a[0:10:2])."); static void slice_dealloc(PySliceObject *r) { + PyInterpreterState *interp = _PyInterpreterState_GET(); _PyObject_GC_UNTRACK(r); Py_DECREF(r->step); Py_DECREF(r->start); Py_DECREF(r->stop); - if (slice_cache == NULL) - slice_cache = r; - else + if (interp->slice_cache == NULL) { + interp->slice_cache = r; + } + else { PyObject_GC_Del(r); + } } static PyObject * @@ -379,7 +388,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, /* Convert step to an integer; raise for zero step. */ if (self->step == Py_None) { - step = _PyLong_One; + step = _PyLong_GetOne(); Py_INCREF(step); step_is_negative = 0; } @@ -408,7 +417,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, goto error; } else { - lower = _PyLong_Zero; + lower = _PyLong_GetZero(); Py_INCREF(lower); upper = length; Py_INCREF(upper); diff --git a/contrib/tools/python3/src/Objects/stringlib/asciilib.h b/contrib/tools/python3/src/Objects/stringlib/asciilib.h index e69a2c076e3..7749e8fb339 100644 --- a/contrib/tools/python3/src/Objects/stringlib/asciilib.h +++ b/contrib/tools/python3/src/Objects/stringlib/asciilib.h @@ -11,7 +11,6 @@ #define STRINGLIB_CHAR Py_UCS1 #define STRINGLIB_TYPE_NAME "unicode" #define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_EMPTY unicode_empty #define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE #define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK #define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL diff --git a/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h b/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h index 8a3a060f12b..a5135a0cba0 100644 --- a/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h +++ b/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h @@ -33,11 +33,6 @@ stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } tabsize = _PyLong_AsInt(args[0]); if (tabsize == -1 && PyErr_Occurred()) { goto exit; @@ -73,14 +68,9 @@ stringlib_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ljust", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -134,14 +124,9 @@ stringlib_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("rjust", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -195,14 +180,9 @@ stringlib_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("center", nargs, 1, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[0]); + PyObject *iobj = _PyNumber_Index(args[0]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -252,14 +232,9 @@ stringlib_zfill(PyObject *self, PyObject *arg) PyObject *return_value = NULL; Py_ssize_t width; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(arg); + PyObject *iobj = _PyNumber_Index(arg); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -274,4 +249,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=15be047aef999b4e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2d9abc7b1cffeca6 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/stringlib/codecs.h b/contrib/tools/python3/src/Objects/stringlib/codecs.h index 9b2a29ba3b8..b17cda18f54 100644 --- a/contrib/tools/python3/src/Objects/stringlib/codecs.h +++ b/contrib/tools/python3/src/Objects/stringlib/codecs.h @@ -4,16 +4,16 @@ # error "codecs.h is specific to Unicode" #endif -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif /* 10xxxxxx */ @@ -26,7 +26,6 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, { Py_UCS4 ch; const char *s = *inptr; - const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); STRINGLIB_CHAR *p = dest + *outpos; while (s < end) { @@ -36,19 +35,19 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, /* Fast path for runs of ASCII characters. Given that common UTF-8 input will consist of an overwhelming majority of ASCII characters, we try to optimize for this case by checking - as many characters as a C 'long' can contain. + as many characters as a C 'size_t' can contain. First, check if we can do an aligned read, as most CPUs have a penalty for unaligned reads. */ - if (_Py_IS_ALIGNED(s, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(s, ALIGNOF_SIZE_T)) { /* Help register allocation */ const char *_s = s; STRINGLIB_CHAR *_p = p; - while (_s < aligned_end) { - /* Read a whole long at a time (either 4 or 8 bytes), + while (_s + SIZEOF_SIZE_T <= end) { + /* Read a whole size_t at a time (either 4 or 8 bytes), and do a fast unrolled copy if it only contains ASCII characters. */ - unsigned long value = *(const unsigned long *) _s; + size_t value = *(const size_t *) _s; if (value & ASCII_CHAR_MASK) break; #if PY_LITTLE_ENDIAN @@ -56,14 +55,14 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, _p[1] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu); _p[2] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu); _p[3] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu); -# if SIZEOF_LONG == 8 +# if SIZEOF_SIZE_T == 8 _p[4] = (STRINGLIB_CHAR)((value >> 32) & 0xFFu); _p[5] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); _p[6] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); _p[7] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); # endif #else -# if SIZEOF_LONG == 8 +# if SIZEOF_SIZE_T == 8 _p[0] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); _p[1] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); _p[2] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); @@ -79,8 +78,8 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, _p[3] = (STRINGLIB_CHAR)(value & 0xFFu); # endif #endif - _s += SIZEOF_LONG; - _p += SIZEOF_LONG; + _s += SIZEOF_SIZE_T; + _p += SIZEOF_SIZE_T; } s = _s; p = _p; @@ -496,8 +495,6 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, int native_ordering) { Py_UCS4 ch; - const unsigned char *aligned_end = - (const unsigned char *) _Py_ALIGN_DOWN(e, SIZEOF_LONG); const unsigned char *q = *inptr; STRINGLIB_CHAR *p = dest + *outpos; /* Offsets from q for retrieving byte pairs in the right order. */ @@ -512,10 +509,10 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, Py_UCS4 ch2; /* First check for possible aligned read of a C 'long'. Unaligned reads are more expensive, better to defer to another iteration. */ - if (_Py_IS_ALIGNED(q, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(q, ALIGNOF_LONG)) { /* Fast path for runs of in-range non-surrogate chars. */ const unsigned char *_q = q; - while (_q < aligned_end) { + while (_q + SIZEOF_LONG <= e) { unsigned long block = * (const unsigned long *) _q; if (native_ordering) { /* Can use buffer directly */ diff --git a/contrib/tools/python3/src/Objects/stringlib/fastsearch.h b/contrib/tools/python3/src/Objects/stringlib/fastsearch.h index 56a4467d353..6574720b609 100644 --- a/contrib/tools/python3/src/Objects/stringlib/fastsearch.h +++ b/contrib/tools/python3/src/Objects/stringlib/fastsearch.h @@ -9,10 +9,16 @@ /* note: fastsearch may access s[n], which isn't a problem when using Python's ordinary string types, but may cause problems if you're using this code in other contexts. also, the count mode returns -1 - if there cannot possible be a match in the target string, and 0 if + if there cannot possibly be a match in the target string, and 0 if it has actually checked for matches, but didn't find any. callers beware! */ +/* If the strings are long enough, use Crochemore and Perrin's Two-Way + 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. */ + #define FAST_COUNT 0 #define FAST_SEARCH 1 #define FAST_RSEARCH 2 @@ -160,6 +166,353 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) #undef MEMCHR_CUT_OFF +/* Change to a 1 to see logging comments walk through the algorithm. */ +#if 0 && STRINGLIB_SIZEOF_CHAR == 1 +# define LOG(...) printf(__VA_ARGS__) +# define LOG_STRING(s, n) printf("\"%.*s\"", n, s) +#else +# define LOG(...) +# define LOG_STRING(s, n) +#endif + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(_lex_search)(const STRINGLIB_CHAR *needle, Py_ssize_t len_needle, + Py_ssize_t *return_period, int invert_alphabet) +{ + /* Do a lexicographic search. Essentially this: + >>> max(needle[i:] for i in range(len(needle)+1)) + Also find the period of the right half. */ + Py_ssize_t max_suffix = 0; + Py_ssize_t candidate = 1; + Py_ssize_t k = 0; + // The period of the right half. + Py_ssize_t period = 1; + + while (candidate + k < len_needle) { + // each loop increases candidate + k + max_suffix + STRINGLIB_CHAR a = needle[candidate + k]; + STRINGLIB_CHAR b = needle[max_suffix + k]; + // check if the suffix at candidate is better than max_suffix + if (invert_alphabet ? (b < a) : (a < b)) { + // Fell short of max_suffix. + // The next k + 1 characters are non-increasing + // from candidate, so they won't start a maximal suffix. + candidate += k + 1; + k = 0; + // We've ruled out any period smaller than what's + // been scanned since max_suffix. + period = candidate - max_suffix; + } + else if (a == b) { + if (k + 1 != period) { + // Keep scanning the equal strings + k++; + } + else { + // Matched a whole period. + // Start matching the next period. + candidate += period; + k = 0; + } + } + else { + // Did better than max_suffix, so replace it. + max_suffix = candidate; + candidate++; + k = 0; + period = 1; + } + } + *return_period = period; + return max_suffix; +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(_factorize)(const STRINGLIB_CHAR *needle, + Py_ssize_t len_needle, + Py_ssize_t *return_period) +{ + /* Do a "critical factorization", making it so that: + >>> needle = (left := needle[:cut]) + (right := needle[cut:]) + where the "local period" of the cut is maximal. + + The local period of the cut is the minimal length of a string w + such that (left endswith w or w endswith left) + and (right startswith w or w startswith left). + + The Critical Factorization Theorem says that this maximal local + period is the global period of the string. + + Crochemore and Perrin (1991) show that this cut can be computed + as the later of two cuts: one that gives a lexicographically + maximal right half, and one that gives the same with the + with respect to a reversed alphabet-ordering. + + This is what we want to happen: + >>> x = "GCAGAGAG" + >>> cut, period = factorize(x) + >>> x[:cut], (right := x[cut:]) + ('GC', 'AGAGAG') + >>> period # right half period + 2 + >>> right[period:] == right[:-period] + True + + This is how the local period lines up in the above example: + GC | AGAGAG + AGAGAGC = AGAGAGC + The length of this minimal repetition is 7, which is indeed the + period of the original string. */ + + Py_ssize_t cut1, period1, cut2, period2, cut, period; + cut1 = STRINGLIB(_lex_search)(needle, len_needle, &period1, 0); + cut2 = STRINGLIB(_lex_search)(needle, len_needle, &period2, 1); + + // Take the later cut. + if (cut1 > cut2) { + period = period1; + cut = cut1; + } + else { + period = period2; + cut = cut2; + } + + LOG("split: "); LOG_STRING(needle, cut); + LOG(" + "); LOG_STRING(needle + cut, len_needle - cut); + LOG("\n"); + + *return_period = period; + return cut; +} + +#define SHIFT_TYPE uint8_t +#define NOT_FOUND ((1U<<(8*sizeof(SHIFT_TYPE))) - 1U) +#define SHIFT_OVERFLOW (NOT_FOUND - 1U) + +#define TABLE_SIZE_BITS 6 +#define TABLE_SIZE (1U << TABLE_SIZE_BITS) +#define TABLE_MASK (TABLE_SIZE - 1U) + +typedef struct STRINGLIB(_pre) { + const STRINGLIB_CHAR *needle; + Py_ssize_t len_needle; + Py_ssize_t cut; + Py_ssize_t period; + int is_periodic; + SHIFT_TYPE table[TABLE_SIZE]; +} STRINGLIB(prework); + + +Py_LOCAL_INLINE(void) +STRINGLIB(_preprocess)(const STRINGLIB_CHAR *needle, Py_ssize_t len_needle, + STRINGLIB(prework) *p) +{ + p->needle = needle; + p->len_needle = len_needle; + p->cut = STRINGLIB(_factorize)(needle, len_needle, &(p->period)); + assert(p->period + p->cut <= len_needle); + p->is_periodic = (0 == memcmp(needle, + needle + p->period, + p->cut * STRINGLIB_SIZEOF_CHAR)); + if (p->is_periodic) { + assert(p->cut <= len_needle/2); + assert(p->cut < p->period); + } + else { + // A lower bound on the period + p->period = Py_MAX(p->cut, len_needle - p->cut) + 1; + } + // Now fill up a table + memset(&(p->table[0]), 0xff, TABLE_SIZE*sizeof(SHIFT_TYPE)); + assert(p->table[0] == NOT_FOUND); + assert(p->table[TABLE_MASK] == NOT_FOUND); + for (Py_ssize_t i = 0; i < len_needle; i++) { + Py_ssize_t shift = len_needle - i; + if (shift > SHIFT_OVERFLOW) { + shift = SHIFT_OVERFLOW; + } + p->table[needle[i] & TABLE_MASK] = Py_SAFE_DOWNCAST(shift, + Py_ssize_t, + SHIFT_TYPE); + } +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack, + STRINGLIB(prework) *p) +{ + // Crochemore and Perrin's (1991) Two-Way algorithm. + // See http://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260 + Py_ssize_t len_needle = p->len_needle; + Py_ssize_t cut = p->cut; + Py_ssize_t period = p->period; + const STRINGLIB_CHAR *needle = p->needle; + const STRINGLIB_CHAR *window = haystack; + const STRINGLIB_CHAR *last_window = haystack + len_haystack - len_needle; + SHIFT_TYPE *table = p->table; + LOG("===== Two-way: \"%s\" in \"%s\". =====\n", needle, haystack); + + if (p->is_periodic) { + LOG("Needle is periodic.\n"); + Py_ssize_t memory = 0; + periodicwindowloop: + while (window <= last_window) { + Py_ssize_t i = Py_MAX(cut, memory); + + // Visualize the line-up: + LOG("> "); LOG_STRING(haystack, len_haystack); + LOG("\n> "); LOG("%*s", window - haystack, ""); + LOG_STRING(needle, len_needle); + LOG("\n> "); LOG("%*s", window - haystack + i, ""); + LOG(" ^ <-- cut\n"); + + if (window[i] != needle[i]) { + // Sunday's trick: if we're going to jump, we might + // as well jump to line up the character *after* the + // current window. + STRINGLIB_CHAR first_outside = window[len_needle]; + SHIFT_TYPE shift = table[first_outside & TABLE_MASK]; + if (shift == NOT_FOUND) { + LOG("\"%c\" not found. Skipping entirely.\n", + first_outside); + window += len_needle + 1; + } + else { + LOG("Shifting to line up \"%c\".\n", first_outside); + Py_ssize_t memory_shift = i - cut + 1; + window += Py_MAX(shift, memory_shift); + } + memory = 0; + goto periodicwindowloop; + } + for (i = i + 1; i < len_needle; i++) { + if (needle[i] != window[i]) { + LOG("Right half does not match. Jump ahead by %d.\n", + i - cut + 1); + window += i - cut + 1; + memory = 0; + goto periodicwindowloop; + } + } + for (i = memory; i < cut; i++) { + if (needle[i] != window[i]) { + LOG("Left half does not match. Jump ahead by period %d.\n", + period); + window += period; + memory = len_needle - period; + goto periodicwindowloop; + } + } + LOG("Left half matches. Returning %d.\n", + window - haystack); + return window - haystack; + } + } + else { + LOG("Needle is not periodic.\n"); + assert(cut < len_needle); + STRINGLIB_CHAR needle_cut = needle[cut]; + windowloop: + while (window <= last_window) { + + // Visualize the line-up: + LOG("> "); LOG_STRING(haystack, len_haystack); + LOG("\n> "); LOG("%*s", window - haystack, ""); + LOG_STRING(needle, len_needle); + LOG("\n> "); LOG("%*s", window - haystack + cut, ""); + LOG(" ^ <-- cut\n"); + + if (window[cut] != needle_cut) { + // Sunday's trick: if we're going to jump, we might + // as well jump to line up the character *after* the + // current window. + STRINGLIB_CHAR first_outside = window[len_needle]; + SHIFT_TYPE shift = table[first_outside & TABLE_MASK]; + if (shift == NOT_FOUND) { + LOG("\"%c\" not found. Skipping entirely.\n", + first_outside); + window += len_needle + 1; + } + else { + LOG("Shifting to line up \"%c\".\n", first_outside); + window += shift; + } + goto windowloop; + } + for (Py_ssize_t i = cut + 1; i < len_needle; i++) { + if (needle[i] != window[i]) { + LOG("Right half does not match. Advance by %d.\n", + i - cut + 1); + window += i - cut + 1; + goto windowloop; + } + } + for (Py_ssize_t i = 0; i < cut; i++) { + if (needle[i] != window[i]) { + LOG("Left half does not match. Advance by period %d.\n", + period); + window += period; + goto windowloop; + } + } + LOG("Left half matches. Returning %d.\n", window - haystack); + return window - haystack; + } + } + LOG("Not found. Returning -1.\n"); + return -1; +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(_two_way_find)(const STRINGLIB_CHAR *haystack, + Py_ssize_t len_haystack, + const STRINGLIB_CHAR *needle, + Py_ssize_t len_needle) +{ + LOG("###### Finding \"%s\" in \"%s\".\n", needle, haystack); + STRINGLIB(prework) p; + STRINGLIB(_preprocess)(needle, len_needle, &p); + return STRINGLIB(_two_way)(haystack, len_haystack, &p); +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(_two_way_count)(const STRINGLIB_CHAR *haystack, + Py_ssize_t len_haystack, + const STRINGLIB_CHAR *needle, + Py_ssize_t len_needle, + Py_ssize_t maxcount) +{ + LOG("###### Counting \"%s\" in \"%s\".\n", needle, haystack); + STRINGLIB(prework) p; + STRINGLIB(_preprocess)(needle, len_needle, &p); + Py_ssize_t index = 0, count = 0; + while (1) { + Py_ssize_t result; + result = STRINGLIB(_two_way)(haystack + index, + len_haystack - index, &p); + if (result == -1) { + return count; + } + count++; + if (count == maxcount) { + return maxcount; + } + index += result + len_needle; + } + return count; +} + +#undef SHIFT_TYPE +#undef NOT_FOUND +#undef SHIFT_OVERFLOW +#undef TABLE_SIZE_BITS +#undef TABLE_SIZE +#undef TABLE_MASK + +#undef LOG +#undef LOG_STRING + Py_LOCAL_INLINE(Py_ssize_t) FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n, const STRINGLIB_CHAR* p, Py_ssize_t m, @@ -195,10 +548,22 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n, } mlast = m - 1; - skip = mlast - 1; + skip = mlast; mask = 0; if (mode != FAST_RSEARCH) { + if (m >= 100 && w >= 2000 && w / m >= 5) { + /* For larger problems where the needle isn't a huge + percentage of the size of the haystack, the relatively + expensive O(m) startup cost of the two-way algorithm + will surely pay off. */ + if (mode == FAST_SEARCH) { + return STRINGLIB(_two_way_find)(s, n, p, m); + } + else { + return STRINGLIB(_two_way_count)(s, n, p, m, maxcount); + } + } const STRINGLIB_CHAR *ss = s + m - 1; const STRINGLIB_CHAR *pp = p + m - 1; @@ -207,41 +572,118 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n, /* process pattern[:-1] */ for (i = 0; i < mlast; i++) { STRINGLIB_BLOOM_ADD(mask, p[i]); - if (p[i] == p[mlast]) + if (p[i] == p[mlast]) { skip = mlast - i - 1; + } } /* process pattern[-1] outside the loop */ STRINGLIB_BLOOM_ADD(mask, p[mlast]); + if (m >= 100 && w >= 8000) { + /* To ensure that we have good worst-case behavior, + here's an adaptive version of the algorithm, where if + we match O(m) characters without any matches of the + entire needle, then we predict that the startup cost of + the two-way algorithm will probably be worth it. */ + Py_ssize_t hits = 0; + for (i = 0; i <= w; i++) { + if (ss[i] == pp[0]) { + /* candidate match */ + for (j = 0; j < mlast; j++) { + if (s[i+j] != p[j]) { + break; + } + } + if (j == mlast) { + /* got a match! */ + if (mode != FAST_COUNT) { + return i; + } + count++; + if (count == maxcount) { + return maxcount; + } + i = i + mlast; + continue; + } + /* miss: check if next character is part of pattern */ + if (!STRINGLIB_BLOOM(mask, ss[i+1])) { + i = i + m; + } + else { + i = i + skip; + } + hits += j + 1; + if (hits >= m / 4 && i < w - 1000) { + /* We've done O(m) fruitless comparisons + anyway, so spend the O(m) cost on the + setup for the two-way algorithm. */ + Py_ssize_t res; + if (mode == FAST_COUNT) { + res = STRINGLIB(_two_way_count)( + s+i, n-i, p, m, maxcount-count); + return count + res; + } + else { + res = STRINGLIB(_two_way_find)(s+i, n-i, p, m); + if (res == -1) { + return -1; + } + return i + res; + } + } + } + else { + /* skip: check if next character is part of pattern */ + if (!STRINGLIB_BLOOM(mask, ss[i+1])) { + i = i + m; + } + } + } + if (mode != FAST_COUNT) { + return -1; + } + return count; + } + /* The standard, non-adaptive version of the algorithm. */ for (i = 0; i <= w; i++) { /* note: using mlast in the skip path slows things down on x86 */ if (ss[i] == pp[0]) { /* candidate match */ - for (j = 0; j < mlast; j++) - if (s[i+j] != p[j]) + for (j = 0; j < mlast; j++) { + if (s[i+j] != p[j]) { break; + } + } if (j == mlast) { /* got a match! */ - if (mode != FAST_COUNT) + if (mode != FAST_COUNT) { return i; + } count++; - if (count == maxcount) + if (count == maxcount) { return maxcount; + } i = i + mlast; continue; } /* miss: check if next character is part of pattern */ - if (!STRINGLIB_BLOOM(mask, ss[i+1])) + if (!STRINGLIB_BLOOM(mask, ss[i+1])) { i = i + m; - else + } + else { i = i + skip; - } else { + } + } + else { /* skip: check if next character is part of pattern */ - if (!STRINGLIB_BLOOM(mask, ss[i+1])) + if (!STRINGLIB_BLOOM(mask, ss[i+1])) { i = i + m; + } } } - } else { /* FAST_RSEARCH */ + } + else { /* FAST_RSEARCH */ /* create compressed boyer-moore delta 1 table */ @@ -250,28 +692,36 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n, /* process pattern[:0:-1] */ for (i = mlast; i > 0; i--) { STRINGLIB_BLOOM_ADD(mask, p[i]); - if (p[i] == p[0]) + if (p[i] == p[0]) { skip = i - 1; + } } for (i = w; i >= 0; i--) { if (s[i] == p[0]) { /* candidate match */ - for (j = mlast; j > 0; j--) - if (s[i+j] != p[j]) + for (j = mlast; j > 0; j--) { + if (s[i+j] != p[j]) { break; - if (j == 0) + } + } + if (j == 0) { /* got a match! */ return i; + } /* miss: check if previous character is part of pattern */ - if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1])) + if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1])) { i = i - m; - else + } + else { i = i - skip; - } else { + } + } + else { /* skip: check if previous character is part of pattern */ - if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1])) + if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1])) { i = i - m; + } } } } diff --git a/contrib/tools/python3/src/Objects/stringlib/find_max_char.h b/contrib/tools/python3/src/Objects/stringlib/find_max_char.h index f4e0a7761d3..b9ffdfc2e35 100644 --- a/contrib/tools/python3/src/Objects/stringlib/find_max_char.h +++ b/contrib/tools/python3/src/Objects/stringlib/find_max_char.h @@ -4,14 +4,14 @@ # error "find_max_char.h is specific to Unicode" #endif -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define UCS1_ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define UCS1_ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define UCS1_ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define UCS1_ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif #if STRINGLIB_SIZEOF_CHAR == 1 @@ -20,18 +20,16 @@ Py_LOCAL_INLINE(Py_UCS4) STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) { const unsigned char *p = (const unsigned char *) begin; - const unsigned char *aligned_end = - (const unsigned char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); while (p < end) { - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(p, ALIGNOF_SIZE_T)) { /* Help register allocation */ const unsigned char *_p = p; - while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + while (_p + SIZEOF_SIZE_T <= end) { + size_t value = *(const size_t *) _p; if (value & UCS1_ASCII_CHAR_MASK) return 255; - _p += SIZEOF_LONG; + _p += SIZEOF_SIZE_T; } p = _p; if (p == end) diff --git a/contrib/tools/python3/src/Objects/stringlib/join.h b/contrib/tools/python3/src/Objects/stringlib/join.h index 53bcbdea7ad..62e4c98de7f 100644 --- a/contrib/tools/python3/src/Objects/stringlib/join.h +++ b/contrib/tools/python3/src/Objects/stringlib/join.h @@ -155,7 +155,7 @@ done: for (i = 0; i < nbufs; i++) PyBuffer_Release(&buffers[i]); if (buffers != static_buffers) - PyMem_FREE(buffers); + PyMem_Free(buffers); return res; } diff --git a/contrib/tools/python3/src/Objects/stringlib/partition.h b/contrib/tools/python3/src/Objects/stringlib/partition.h index ed32a6f2b38..bcc217697b2 100644 --- a/contrib/tools/python3/src/Objects/stringlib/partition.h +++ b/contrib/tools/python3/src/Objects/stringlib/partition.h @@ -1,9 +1,14 @@ /* stringlib: partition implementation */ #ifndef STRINGLIB_FASTSEARCH_H -#error must include "stringlib/fastsearch.h" before including this module +# error must include "stringlib/fastsearch.h" before including this module #endif +#if !STRINGLIB_MUTABLE && !defined(STRINGLIB_GET_EMPTY) +# error "STRINGLIB_GET_EMPTY must be defined if STRINGLIB_MUTABLE is zero" +#endif + + Py_LOCAL_INLINE(PyObject*) STRINGLIB(partition)(PyObject* str_obj, const STRINGLIB_CHAR* str, Py_ssize_t str_len, @@ -37,10 +42,12 @@ STRINGLIB(partition)(PyObject* str_obj, #else Py_INCREF(str_obj); PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj); - Py_INCREF(STRINGLIB_EMPTY); - PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY); - Py_INCREF(STRINGLIB_EMPTY); - PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY); + PyObject *empty = (PyObject*)STRINGLIB_GET_EMPTY(); + assert(empty != NULL); + Py_INCREF(empty); + PyTuple_SET_ITEM(out, 1, empty); + Py_INCREF(empty); + PyTuple_SET_ITEM(out, 2, empty); #endif return out; } @@ -90,10 +97,12 @@ STRINGLIB(rpartition)(PyObject* str_obj, return NULL; } #else - Py_INCREF(STRINGLIB_EMPTY); - PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY); - Py_INCREF(STRINGLIB_EMPTY); - PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY); + PyObject *empty = (PyObject*)STRINGLIB_GET_EMPTY(); + assert(empty != NULL); + Py_INCREF(empty); + PyTuple_SET_ITEM(out, 0, empty); + Py_INCREF(empty); + PyTuple_SET_ITEM(out, 1, empty); Py_INCREF(str_obj); PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj); #endif diff --git a/contrib/tools/python3/src/Objects/stringlib/stringdefs.h b/contrib/tools/python3/src/Objects/stringlib/stringdefs.h index ce27f3e4081..88641b25d47 100644 --- a/contrib/tools/python3/src/Objects/stringlib/stringdefs.h +++ b/contrib/tools/python3/src/Objects/stringlib/stringdefs.h @@ -13,7 +13,6 @@ #define STRINGLIB_CHAR char #define STRINGLIB_TYPE_NAME "string" #define STRINGLIB_PARSE_CODE "S" -#define STRINGLIB_EMPTY nullstring #define STRINGLIB_ISSPACE Py_ISSPACE #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) #define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9')) diff --git a/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h b/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h index bc4b104f112..5b0b8a025e8 100644 --- a/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h +++ b/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h @@ -11,7 +11,6 @@ #define STRINGLIB_CHAR Py_UCS1 #define STRINGLIB_TYPE_NAME "unicode" #define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_EMPTY unicode_empty #define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE #define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK #define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL diff --git a/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h b/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h index 86a1dff1b56..6af01511c5f 100644 --- a/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h +++ b/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h @@ -11,7 +11,6 @@ #define STRINGLIB_CHAR Py_UCS2 #define STRINGLIB_TYPE_NAME "unicode" #define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_EMPTY unicode_empty #define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE #define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK #define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL diff --git a/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h b/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h index 3c32a93c96a..39071a0cdf0 100644 --- a/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h +++ b/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h @@ -11,7 +11,6 @@ #define STRINGLIB_CHAR Py_UCS4 #define STRINGLIB_TYPE_NAME "unicode" #define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_EMPTY unicode_empty #define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE #define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK #define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL diff --git a/contrib/tools/python3/src/Objects/stringlib/unicode_format.h b/contrib/tools/python3/src/Objects/stringlib/unicode_format.h index b526ad21b82..7152ec6ebe7 100644 --- a/contrib/tools/python3/src/Objects/stringlib/unicode_format.h +++ b/contrib/tools/python3/src/Objects/stringlib/unicode_format.h @@ -983,7 +983,7 @@ static void formatteriter_dealloc(formatteriterobject *it) { Py_XDECREF(it->str); - PyObject_FREE(it); + PyObject_Free(it); } /* returns a tuple: @@ -1147,7 +1147,7 @@ static void fieldnameiter_dealloc(fieldnameiterobject *it) { Py_XDECREF(it->str); - PyObject_FREE(it); + PyObject_Free(it); } /* returns a tuple: diff --git a/contrib/tools/python3/src/Objects/stringlib/unicodedefs.h b/contrib/tools/python3/src/Objects/stringlib/unicodedefs.h index 3db5629e11f..5ea79cd4f50 100644 --- a/contrib/tools/python3/src/Objects/stringlib/unicodedefs.h +++ b/contrib/tools/python3/src/Objects/stringlib/unicodedefs.h @@ -13,7 +13,6 @@ #define STRINGLIB_CHAR Py_UNICODE #define STRINGLIB_TYPE_NAME "unicode" #define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_EMPTY unicode_empty #define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE #define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK #define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL diff --git a/contrib/tools/python3/src/Objects/structseq.c b/contrib/tools/python3/src/Objects/structseq.c index 5a493c91e87..73795b677b4 100644 --- a/contrib/tools/python3/src/Objects/structseq.c +++ b/contrib/tools/python3/src/Objects/structseq.c @@ -8,31 +8,46 @@ */ #include "Python.h" -#include "pycore_tupleobject.h" -#include "pycore_object.h" +#include "pycore_tuple.h" // _PyTuple_FromArray() +#include "pycore_object.h" // _PyObject_GC_TRACK() #include "structmember.h" // PyMemberDef +#include "pycore_structseq.h" // PyStructSequence_InitType() static const char visible_length_key[] = "n_sequence_fields"; static const char real_length_key[] = "n_fields"; static const char unnamed_fields_key[] = "n_unnamed_fields"; +static const char match_args_key[] = "__match_args__"; /* Fields with this name have only a field index, not a field name. They are only allowed for indices < n_visible_fields. */ const char * const PyStructSequence_UnnamedField = "unnamed field"; + _Py_IDENTIFIER(n_sequence_fields); _Py_IDENTIFIER(n_fields); _Py_IDENTIFIER(n_unnamed_fields); -#define VISIBLE_SIZE(op) Py_SIZE(op) -#define VISIBLE_SIZE_TP(tp) PyLong_AsSsize_t( \ - _PyDict_GetItemId((tp)->tp_dict, &PyId_n_sequence_fields)) +static Py_ssize_t +get_type_attr_as_size(PyTypeObject *tp, _Py_Identifier *id) +{ + PyObject *name = _PyUnicode_FromId(id); + if (name == NULL) { + return -1; + } + PyObject *v = PyDict_GetItemWithError(tp->tp_dict, name); + if (v == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "Missed attribute '%U' of type %s", + name, tp->tp_name); + } + return PyLong_AsSsize_t(v); +} -#define REAL_SIZE_TP(tp) PyLong_AsSsize_t( \ - _PyDict_GetItemId((tp)->tp_dict, &PyId_n_fields)) +#define VISIBLE_SIZE(op) Py_SIZE(op) +#define VISIBLE_SIZE_TP(tp) get_type_attr_as_size(tp, &PyId_n_sequence_fields) +#define REAL_SIZE_TP(tp) get_type_attr_as_size(tp, &PyId_n_fields) #define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op)) -#define UNNAMED_FIELDS_TP(tp) PyLong_AsSsize_t( \ - _PyDict_GetItemId((tp)->tp_dict, &PyId_n_unnamed_fields)) +#define UNNAMED_FIELDS_TP(tp) get_type_attr_as_size(tp, &PyId_n_unnamed_fields) #define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op)) @@ -41,13 +56,20 @@ PyStructSequence_New(PyTypeObject *type) { PyStructSequence *obj; Py_ssize_t size = REAL_SIZE_TP(type), i; + if (size < 0) { + return NULL; + } + Py_ssize_t vsize = VISIBLE_SIZE_TP(type); + if (vsize < 0) { + return NULL; + } obj = PyObject_GC_NewVar(PyStructSequence, type, size); if (obj == NULL) return NULL; /* Hack the size of the variable object, so invisible fields don't appear to Python code. */ - Py_SET_SIZE(obj, VISIBLE_SIZE_TP(type)); + Py_SET_SIZE(obj, vsize); for (i = 0; i < size; i++) obj->ob_item[i] = NULL; @@ -94,7 +116,7 @@ structseq_dealloc(PyStructSequence *obj) Py_XDECREF(obj->ob_item[i]); } PyObject_GC_Del(obj); - if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { Py_DECREF(tp); } } @@ -121,6 +143,19 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) PyStructSequence *res = NULL; Py_ssize_t len, min_len, max_len, i, n_unnamed_fields; + min_len = VISIBLE_SIZE_TP(type); + if (min_len < 0) { + return NULL; + } + max_len = REAL_SIZE_TP(type); + if (max_len < 0) { + return NULL; + } + n_unnamed_fields = UNNAMED_FIELDS_TP(type); + if (n_unnamed_fields < 0) { + return NULL; + } + arg = PySequence_Fast(arg, "constructor requires a sequence"); if (!arg) { @@ -136,10 +171,6 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) } len = PySequence_Fast_GET_SIZE(arg); - min_len = VISIBLE_SIZE_TP(type); - max_len = REAL_SIZE_TP(type); - n_unnamed_fields = UNNAMED_FIELDS_TP(type); - if (min_len != max_len) { if (len < min_len) { PyErr_Format(PyExc_TypeError, @@ -177,18 +208,26 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) Py_INCREF(v); res->ob_item[i] = v; } + Py_DECREF(arg); for (; i < max_len; ++i) { - if (dict && (ob = PyDict_GetItemString( - dict, type->tp_members[i-n_unnamed_fields].name))) { + if (dict == NULL) { + ob = Py_None; } else { - ob = Py_None; + ob = _PyDict_GetItemStringWithError(dict, + type->tp_members[i-n_unnamed_fields].name); + if (ob == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(res); + return NULL; + } + ob = Py_None; + } } Py_INCREF(ob); res->ob_item[i] = ob; } - Py_DECREF(arg); _PyObject_GC_TRACK(res); return (PyObject*) res; } @@ -288,8 +327,14 @@ structseq_reduce(PyStructSequence* self, PyObject *Py_UNUSED(ignored)) Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields, i; n_fields = REAL_SIZE(self); + if (n_fields < 0) { + return NULL; + } n_visible_fields = VISIBLE_SIZE(self); n_unnamed_fields = UNNAMED_FIELDS(self); + if (n_unnamed_fields < 0) { + return NULL; + } tup = _PyTuple_FromArray(self->ob_item, n_visible_fields); if (!tup) goto error; @@ -356,7 +401,40 @@ initialize_structseq_dict(PyStructSequence_Desc *desc, PyObject* dict, SET_DICT_FROM_SIZE(visible_length_key, desc->n_in_sequence); SET_DICT_FROM_SIZE(real_length_key, n_members); SET_DICT_FROM_SIZE(unnamed_fields_key, n_unnamed_members); + + // Prepare and set __match_args__ + Py_ssize_t i, k; + PyObject* keys = PyTuple_New(desc->n_in_sequence); + if (keys == NULL) { + return -1; + } + + for (i = k = 0; i < desc->n_in_sequence; ++i) { + if (desc->fields[i].name == PyStructSequence_UnnamedField) { + continue; + } + PyObject* new_member = PyUnicode_FromString(desc->fields[i].name); + if (new_member == NULL) { + goto error; + } + PyTuple_SET_ITEM(keys, k, new_member); + k++; + } + + if (_PyTuple_Resize(&keys, k) == -1) { + goto error; + } + + if (PyDict_SetItemString(dict, match_args_key, keys) < 0) { + goto error; + } + + Py_DECREF(keys); return 0; + +error: + Py_DECREF(keys); + return -1; } static void @@ -382,8 +460,10 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, members[k].name = NULL; } + int -PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) +_PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, + unsigned long tp_flags) { PyMemberDef *members; Py_ssize_t n_members, n_unnamed_members; @@ -411,7 +491,7 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) type->tp_base = &PyTuple_Type; type->tp_methods = structseq_methods; type->tp_new = structseq_new; - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC; + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; type->tp_traverse = (traverseproc) structseq_traverse; n_members = count_members(desc, &n_unnamed_members); @@ -424,14 +504,14 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) type->tp_members = members; if (PyType_Ready(type) < 0) { - PyMem_FREE(members); + 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); + PyMem_Free(members); Py_DECREF(type); return -1; } @@ -439,6 +519,12 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) return 0; } +int +PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) +{ + return _PyStructSequence_InitType(type, desc, 0); +} + void PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) { @@ -449,7 +535,6 @@ PyTypeObject * PyStructSequence_NewType(PyStructSequence_Desc *desc) { PyMemberDef *members; - PyObject *bases; PyTypeObject *type; PyType_Slot slots[8]; PyType_Spec spec; @@ -467,17 +552,12 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) /* Initialize Slots */ slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc}; slots[1] = (PyType_Slot){Py_tp_repr, (reprfunc)structseq_repr}; - slots[2] = (PyType_Slot){Py_tp_methods, structseq_methods}; - slots[3] = (PyType_Slot){Py_tp_new, structseq_new}; - slots[4] = (PyType_Slot){Py_tp_members, members}; - slots[5] = (PyType_Slot){Py_tp_traverse, (traverseproc)structseq_traverse}; - if (desc->doc) { - slots[6] = (PyType_Slot){Py_tp_doc, (void *)desc->doc}; - slots[7] = (PyType_Slot){0, 0}; - } - else { - slots[6] = (PyType_Slot){0, 0}; - } + slots[2] = (PyType_Slot){Py_tp_doc, (void *)desc->doc}; + slots[3] = (PyType_Slot){Py_tp_methods, structseq_methods}; + slots[4] = (PyType_Slot){Py_tp_new, structseq_new}; + slots[5] = (PyType_Slot){Py_tp_members, members}; + slots[6] = (PyType_Slot){Py_tp_traverse, (traverseproc)structseq_traverse}; + slots[7] = (PyType_Slot){0, 0}; /* Initialize Spec */ /* The name in this PyType_Spec is statically allocated so it is */ @@ -488,14 +568,8 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC; spec.slots = slots; - bases = PyTuple_Pack(1, &PyTuple_Type); - if (bases == NULL) { - PyMem_FREE(members); - return NULL; - } - type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, bases); - Py_DECREF(bases); - PyMem_FREE(members); + type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, (PyObject *)&PyTuple_Type); + PyMem_Free(members); if (type == NULL) { return NULL; } @@ -514,7 +588,8 @@ int _PyStructSequence_Init(void) if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL || _PyUnicode_FromId(&PyId_n_fields) == NULL || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL) + { return -1; - + } return 0; } diff --git a/contrib/tools/python3/src/Objects/tupleobject.c b/contrib/tools/python3/src/Objects/tupleobject.c index 9092c9f8bee..6b1ab740121 100644 --- a/contrib/tools/python3/src/Objects/tupleobject.c +++ b/contrib/tools/python3/src/Objects/tupleobject.c @@ -2,10 +2,10 @@ /* Tuple object implementation */ #include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_accu.h" -#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() -#include "pycore_object.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_object.h" // _PyObject_GC_TRACK() /*[clinic input] class tuple "PyTupleObject *" "&PyTuple_Type" @@ -14,41 +14,36 @@ class tuple "PyTupleObject *" "&PyTuple_Type" #include "clinic/tupleobject.c.h" -/* Speed optimization to avoid frequent malloc/free of small tuples */ -#ifndef PyTuple_MAXSAVESIZE -#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */ -#endif -#ifndef PyTuple_MAXFREELIST -#define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */ -#endif #if PyTuple_MAXSAVESIZE > 0 -/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty - tuple () of which at most one instance will be allocated. -*/ -static PyTupleObject *free_list[PyTuple_MAXSAVESIZE]; -static int numfree[PyTuple_MAXSAVESIZE]; +static struct _Py_tuple_state * +get_tuple_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->tuple; +} #endif + static inline void tuple_gc_track(PyTupleObject *op) { _PyObject_GC_TRACK(op); } + /* Print summary info about the state of the optimized allocator */ void _PyTuple_DebugMallocStats(FILE *out) { #if PyTuple_MAXSAVESIZE > 0 - int i; - char buf[128]; - for (i = 1; i < PyTuple_MAXSAVESIZE; i++) { + struct _Py_tuple_state *state = get_tuple_state(); + for (int i = 1; i < PyTuple_MAXSAVESIZE; i++) { + char buf[128]; PyOS_snprintf(buf, sizeof(buf), "free %d-sized PyTupleObject", i); - _PyDebugAllocatorStats(out, - buf, - numfree[i], _PyObject_VAR_SIZE(&PyTuple_Type, i)); + _PyDebugAllocatorStats(out, buf, state->numfree[i], + _PyObject_VAR_SIZE(&PyTuple_Type, i)); } #endif } @@ -65,19 +60,30 @@ static PyTupleObject * tuple_alloc(Py_ssize_t size) { PyTupleObject *op; +#if PyTuple_MAXSAVESIZE > 0 + // If Python is built with the empty tuple singleton, + // tuple_alloc(0) must not be called. + assert(size != 0); +#endif if (size < 0) { PyErr_BadInternalCall(); return NULL; } + #if PyTuple_MAXSAVESIZE > 0 - if (size < PyTuple_MAXSAVESIZE && (op = free_list[size]) != NULL) { + struct _Py_tuple_state *state = get_tuple_state(); +#ifdef Py_DEBUG + // tuple_alloc() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif + if (size < PyTuple_MAXSAVESIZE && (op = state->free_list[size]) != NULL) { assert(size != 0); - free_list[size] = (PyTupleObject *) op->ob_item[0]; - numfree[size]--; - /* Inline PyObject_InitVar */ + state->free_list[size] = (PyTupleObject *) op->ob_item[0]; + state->numfree[size]--; + /* Inlined _PyObject_InitVar() without _PyType_HasFeature() test */ #ifdef Py_TRACE_REFS - Py_SIZE(op) = size; - Py_TYPE(op) = &PyTuple_Type; + Py_SET_SIZE(op, size); + Py_SET_TYPE(op, &PyTuple_Type); #endif _Py_NewReference((PyObject *)op); } @@ -96,15 +102,56 @@ tuple_alloc(Py_ssize_t size) return op; } +static int +tuple_create_empty_tuple_singleton(struct _Py_tuple_state *state) +{ +#if PyTuple_MAXSAVESIZE > 0 + assert(state->free_list[0] == NULL); + + PyTupleObject *op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, 0); + if (op == NULL) { + return -1; + } + // The empty tuple singleton is not tracked by the GC. + // It does not contain any Python object. + + state->free_list[0] = op; + state->numfree[0]++; + + assert(state->numfree[0] == 1); +#endif + return 0; +} + + +static PyObject * +tuple_get_empty(void) +{ +#if PyTuple_MAXSAVESIZE > 0 + struct _Py_tuple_state *state = get_tuple_state(); + PyTupleObject *op = state->free_list[0]; + // tuple_get_empty() must not be called before _PyTuple_Init() + // or after _PyTuple_Fini() + assert(op != NULL); +#ifdef Py_DEBUG + assert(state->numfree[0] != -1); +#endif + + Py_INCREF(op); + return (PyObject *) op; +#else + return PyTuple_New(0); +#endif +} + + PyObject * PyTuple_New(Py_ssize_t size) { PyTupleObject *op; #if PyTuple_MAXSAVESIZE > 0 - if (size == 0 && free_list[0]) { - op = free_list[0]; - Py_INCREF(op); - return (PyObject *) op; + if (size == 0) { + return tuple_get_empty(); } #endif op = tuple_alloc(size); @@ -114,13 +161,6 @@ PyTuple_New(Py_ssize_t size) for (Py_ssize_t i = 0; i < size; i++) { op->ob_item[i] = NULL; } -#if PyTuple_MAXSAVESIZE > 0 - if (size == 0) { - free_list[0] = op; - ++numfree[0]; - Py_INCREF(op); /* extra INCREF so that this is never freed */ - } -#endif tuple_gc_track(op); return (PyObject *) op; } @@ -201,7 +241,7 @@ PyTuple_Pack(Py_ssize_t n, ...) va_list vargs; if (n == 0) { - return PyTuple_New(0); + return tuple_get_empty(); } va_start(vargs, n); @@ -227,27 +267,33 @@ PyTuple_Pack(Py_ssize_t n, ...) static void tupledealloc(PyTupleObject *op) { - Py_ssize_t i; Py_ssize_t len = Py_SIZE(op); PyObject_GC_UnTrack(op); Py_TRASHCAN_BEGIN(op, tupledealloc) if (len > 0) { - i = len; - while (--i >= 0) + Py_ssize_t i = len; + while (--i >= 0) { Py_XDECREF(op->ob_item[i]); + } #if PyTuple_MAXSAVESIZE > 0 - if (len < PyTuple_MAXSAVESIZE && - numfree[len] < PyTuple_MAXFREELIST && - Py_IS_TYPE(op, &PyTuple_Type)) + struct _Py_tuple_state *state = get_tuple_state(); +#ifdef Py_DEBUG + // tupledealloc() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif + if (len < PyTuple_MAXSAVESIZE + && state->numfree[len] < PyTuple_MAXFREELIST + && Py_IS_TYPE(op, &PyTuple_Type)) { - op->ob_item[0] = (PyObject *) free_list[len]; - numfree[len]++; - free_list[len] = op; + op->ob_item[0] = (PyObject *) state->free_list[len]; + state->numfree[len]++; + state->free_list[len] = op; goto done; /* return */ } #endif } Py_TYPE(op)->tp_free((PyObject *)op); + #if PyTuple_MAXSAVESIZE > 0 done: #endif @@ -414,7 +460,7 @@ PyObject * _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) { if (n == 0) { - return PyTuple_New(0); + return tuple_get_empty(); } PyTupleObject *tuple = tuple_alloc(n); @@ -475,16 +521,16 @@ tupleconcat(PyTupleObject *a, PyObject *bb) Py_TYPE(bb)->tp_name); return NULL; } -#define b ((PyTupleObject *)bb) + PyTupleObject *b = (PyTupleObject *)bb; + if (Py_SIZE(b) == 0 && PyTuple_CheckExact(a)) { Py_INCREF(a); return (PyObject *)a; } - if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) - return PyErr_NoMemory(); + assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX); size = Py_SIZE(a) + Py_SIZE(b); if (size == 0) { - return PyTuple_New(0); + return tuple_get_empty(); } np = tuple_alloc(size); @@ -507,7 +553,6 @@ tupleconcat(PyTupleObject *a, PyObject *bb) } tuple_gc_track(np); return (PyObject *)np; -#undef b } static PyObject * @@ -526,7 +571,7 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n) } } if (Py_SIZE(a) == 0 || n <= 0) { - return PyTuple_New(0); + return tuple_get_empty(); } if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) return PyErr_NoMemory(); @@ -702,10 +747,12 @@ tuple_new_impl(PyTypeObject *type, PyObject *iterable) if (type != &PyTuple_Type) return tuple_subtype_new(type, iterable); - if (iterable == NULL) - return PyTuple_New(0); - else + if (iterable == NULL) { + return tuple_get_empty(); + } + else { return PySequence_Tuple(iterable); + } } static PyObject * @@ -724,7 +771,9 @@ tuple_vectorcall(PyObject *type, PyObject * const*args, if (nargs) { return tuple_new_impl((PyTypeObject *)type, args[0]); } - return PyTuple_New(0); + else { + return tuple_get_empty(); + } } static PyObject * @@ -787,7 +836,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) &stop, step); if (slicelength <= 0) { - return PyTuple_New(0); + return tuple_get_empty(); } else if (start == 0 && step == 1 && slicelength == PyTuple_GET_SIZE(self) && @@ -868,7 +917,8 @@ PyTypeObject PyTuple_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS | + _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE, /* tp_flags */ tuple_new__doc__, /* tp_doc */ (traverseproc)tupletraverse, /* tp_traverse */ 0, /* tp_clear */ @@ -958,13 +1008,14 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } void -_PyTuple_ClearFreeList(void) +_PyTuple_ClearFreeList(PyInterpreterState *interp) { #if PyTuple_MAXSAVESIZE > 0 + struct _Py_tuple_state *state = &interp->tuple; for (Py_ssize_t i = 1; i < PyTuple_MAXSAVESIZE; i++) { - PyTupleObject *p = free_list[i]; - free_list[i] = NULL; - numfree[i] = 0; + PyTupleObject *p = state->free_list[i]; + state->free_list[i] = NULL; + state->numfree[i] = 0; while (p) { PyTupleObject *q = p; p = (PyTupleObject *)(p->ob_item[0]); @@ -975,15 +1026,30 @@ _PyTuple_ClearFreeList(void) #endif } + +PyStatus +_PyTuple_Init(PyInterpreterState *interp) +{ + struct _Py_tuple_state *state = &interp->tuple; + if (tuple_create_empty_tuple_singleton(state) < 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} + + void -_PyTuple_Fini(void) +_PyTuple_Fini(PyInterpreterState *interp) { #if PyTuple_MAXSAVESIZE > 0 - /* empty tuples are used all over the place and applications may - * rely on the fact that an empty tuple is a singleton. */ - Py_CLEAR(free_list[0]); - - _PyTuple_ClearFreeList(); + struct _Py_tuple_state *state = &interp->tuple; + // The empty tuple singleton must not be tracked by the GC + assert(!_PyObject_GC_IS_TRACKED(state->free_list[0])); + Py_CLEAR(state->free_list[0]); + _PyTuple_ClearFreeList(interp); +#ifdef Py_DEBUG + state->numfree[0] = -1; +#endif #endif } diff --git a/contrib/tools/python3/src/Objects/typeobject.c b/contrib/tools/python3/src/Objects/typeobject.c index cb0bb46145c..b3ba1208eb2 100644 --- a/contrib/tools/python3/src/Objects/typeobject.c +++ b/contrib/tools/python3/src/Objects/typeobject.c @@ -2,10 +2,13 @@ #include "Python.h" #include "pycore_call.h" +#include "pycore_compile.h" // _Py_Mangle() #include "pycore_initconfig.h" +#include "pycore_moduleobject.h" // _PyModule_GetDef() #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_unionobject.h" // _Py_union_type_or #include "frameobject.h" #include "structmember.h" // PyMemberDef @@ -19,53 +22,45 @@ class object "PyObject *" "&PyBaseObject_Type" #include "clinic/typeobject.c.h" -#define MCACHE - -#ifdef MCACHE -/* Support type attribute cache */ +/* Support type attribute lookup cache */ /* The cache can keep references to the names alive for longer than they normally would. This is why the maximum size is limited to MCACHE_MAX_ATTR_SIZE, since it might be a problem if very large strings are used as attribute names. */ #define MCACHE_MAX_ATTR_SIZE 100 -#define MCACHE_SIZE_EXP 12 #define MCACHE_HASH(version, name_hash) \ (((unsigned int)(version) ^ (unsigned int)(name_hash)) \ & ((1 << MCACHE_SIZE_EXP) - 1)) #define MCACHE_HASH_METHOD(type, name) \ - MCACHE_HASH((type)->tp_version_tag, \ - ((PyASCIIObject *)(name))->hash) + MCACHE_HASH((type)->tp_version_tag, ((Py_ssize_t)(name)) >> 3) #define MCACHE_CACHEABLE_NAME(name) \ PyUnicode_CheckExact(name) && \ PyUnicode_IS_READY(name) && \ - PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE - -struct method_cache_entry { - unsigned int version; - PyObject *name; /* reference to exactly a str or None */ - PyObject *value; /* borrowed */ -}; + (PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE) -static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP]; +// 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 = 0; -#endif -#define MCACHE_STATS 0 +typedef struct PySlot_Offset { + short subslot_offset; + short slot_offset; +} PySlot_Offset; -#if MCACHE_STATS -static size_t method_cache_hits = 0; -static size_t method_cache_misses = 0; -static size_t method_cache_collisions = 0; -#endif -#define INTERN_NAME_STRINGS +/* bpo-40521: Interned strings are shared by all subinterpreters */ +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS +# define INTERN_NAME_STRINGS +#endif /* alphabetical order */ _Py_IDENTIFIER(__abstractmethods__); +_Py_IDENTIFIER(__annotations__); _Py_IDENTIFIER(__class__); _Py_IDENTIFIER(__class_getitem__); +_Py_IDENTIFIER(__classcell__); _Py_IDENTIFIER(__delitem__); _Py_IDENTIFIER(__dict__); _Py_IDENTIFIER(__doc__); @@ -77,8 +72,10 @@ _Py_IDENTIFIER(__len__); _Py_IDENTIFIER(__module__); _Py_IDENTIFIER(__name__); _Py_IDENTIFIER(__new__); +_Py_IDENTIFIER(__qualname__); _Py_IDENTIFIER(__set_name__); _Py_IDENTIFIER(__setitem__); +_Py_IDENTIFIER(__weakref__); _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(mro); @@ -166,6 +163,11 @@ _PyType_CheckConsistency(PyTypeObject *type) CHECK(!(type->tp_flags & Py_TPFLAGS_READYING)); CHECK(type->tp_dict != NULL); + if (type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION) { + CHECK(type->tp_new == NULL); + CHECK(_PyDict_ContainsId(type->tp_dict, &PyId___new__) == 0); + } + return 1; #undef CHECK } @@ -217,46 +219,99 @@ _PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_d return PyUnicode_FromStringAndSize(start, end - start); } -unsigned int -PyType_ClearCache(void) + +static struct type_cache* +get_type_cache(void) { -#ifdef MCACHE - Py_ssize_t i; - unsigned int cur_version_tag = next_version_tag - 1; + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->type_cache; +} + + +static void +type_cache_clear(struct type_cache *cache, int use_none) +{ + for (Py_ssize_t i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { + struct type_cache_entry *entry = &cache->hashtable[i]; + entry->version = 0; + if (use_none) { + // Set to None so _PyType_Lookup() can use Py_SETREF(), + // rather than using slower Py_XSETREF(). + Py_XSETREF(entry->name, Py_NewRef(Py_None)); + } + else { + Py_CLEAR(entry->name); + } + entry->value = NULL; + } + + // Mark all version tags as invalid + PyType_Modified(&PyBaseObject_Type); +} + + +void +_PyType_InitCache(PyInterpreterState *interp) +{ + struct type_cache *cache = &interp->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); + + 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->value = NULL; + } +} + +static unsigned int +_PyType_ClearCache(PyInterpreterState *interp) +{ + struct type_cache *cache = &interp->type_cache; #if MCACHE_STATS - size_t total = method_cache_hits + method_cache_collisions + method_cache_misses; + size_t total = cache->hits + cache->collisions + cache->misses; fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n", - method_cache_hits, (int) (100.0 * method_cache_hits / total)); + cache->hits, (int) (100.0 * cache->hits / total)); fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n", - method_cache_misses, (int) (100.0 * method_cache_misses / total)); + cache->misses, (int) (100.0 * cache->misses / total)); fprintf(stderr, "-- Method cache collisions = %zd (%d%%)\n", - method_cache_collisions, (int) (100.0 * method_cache_collisions / total)); + cache->collisions, (int) (100.0 * cache->collisions / total)); fprintf(stderr, "-- Method cache size = %zd KiB\n", - sizeof(method_cache) / 1024); + sizeof(cache->hashtable) / 1024); #endif - for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { - method_cache[i].version = 0; - Py_CLEAR(method_cache[i].name); - method_cache[i].value = NULL; + unsigned int cur_version_tag = next_version_tag - 1; + if (_Py_IsMainInterpreter(interp)) { + next_version_tag = 0; } - next_version_tag = 0; - /* mark all version tags as invalid */ - PyType_Modified(&PyBaseObject_Type); + + type_cache_clear(cache, 0); + return cur_version_tag; -#else - return 0; -#endif } + +unsigned int +PyType_ClearCache(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return _PyType_ClearCache(interp); +} + + void -_PyType_Fini(void) +_PyType_Fini(PyInterpreterState *interp) { - PyType_ClearCache(); - clear_slotdefs(); + _PyType_ClearCache(interp); + if (_Py_IsMainInterpreter(interp)) { + clear_slotdefs(); + } } + void PyType_Modified(PyTypeObject *type) { @@ -266,10 +321,6 @@ PyType_Modified(PyTypeObject *type) Invariants: - - Py_TPFLAGS_VALID_VERSION_TAG is never set if - Py_TPFLAGS_HAVE_VERSION_TAG is not set (in case of a - bizarre MRO, see type_mro_modified()). - - before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type, it must first be set on all super types. @@ -298,6 +349,7 @@ PyType_Modified(PyTypeObject *type) } } type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; + type->tp_version_tag = 0; /* 0 is not a valid version tag */ } static void @@ -320,9 +372,6 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { PyObject *mro_meth = NULL; PyObject *type_mro_meth = NULL; - if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) - return; - if (custom) { mro_meth = lookup_maybe_method( (PyObject *)type, &PyId_mro, &unbound); @@ -345,8 +394,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { assert(PyType_Check(b)); cls = (PyTypeObject *)b; - if (!_PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) || - !PyType_IsSubtype(type, cls)) { + if (!PyType_IsSubtype(type, cls)) { goto clear; } } @@ -354,13 +402,12 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { clear: Py_XDECREF(mro_meth); Py_XDECREF(type_mro_meth); - type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG| - Py_TPFLAGS_VALID_VERSION_TAG); + type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; + type->tp_version_tag = 0; /* 0 is not a valid version tag */ } -#ifdef MCACHE static int -assign_version_tag(PyTypeObject *type) +assign_version_tag(struct type_cache *cache, PyTypeObject *type) { /* Ensure that the tp_version_tag is valid and set Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this @@ -372,8 +419,6 @@ assign_version_tag(PyTypeObject *type) if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) return 1; - if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) - return 0; if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) return 0; @@ -381,31 +426,22 @@ assign_version_tag(PyTypeObject *type) /* for stress-testing: next_version_tag &= 0xFF; */ if (type->tp_version_tag == 0) { - /* wrap-around or just starting Python - clear the whole - cache by filling names with references to Py_None. - Values are also set to NULL for added protection, as they - are borrowed reference */ - for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { - method_cache[i].value = NULL; - Py_INCREF(Py_None); - Py_XSETREF(method_cache[i].name, Py_None); - } - /* mark all version tags as invalid */ - PyType_Modified(&PyBaseObject_Type); - return 1; + // Wrap-around or just starting Python - clear the whole cache + type_cache_clear(cache, 1); + return 0; } + bases = type->tp_bases; n = PyTuple_GET_SIZE(bases); for (i = 0; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); assert(PyType_Check(b)); - if (!assign_version_tag((PyTypeObject *)b)) + if (!assign_version_tag(cache, (PyTypeObject *)b)) return 0; } type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; return 1; } -#endif static PyMemberDef type_members[] = { @@ -424,14 +460,16 @@ static PyMemberDef type_members[] = { static int check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *name) { - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, - "can't set %s.%s", type->tp_name, name); + "cannot set '%s' attribute of immutable type '%s'", + name, type->tp_name); return 0; } if (!value) { PyErr_Format(PyExc_TypeError, - "can't delete %s.%s", type->tp_name, name); + "cannot delete '%s' attribute of immutable type '%s'", + name, type->tp_name); return 0; } @@ -894,6 +932,75 @@ type_set_doc(PyTypeObject *type, PyObject *value, void *context) return _PyDict_SetItemId(type->tp_dict, &PyId___doc__, value); } +static PyObject * +type_get_annotations(PyTypeObject *type, void *context) +{ + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '__annotations__'", type->tp_name); + return NULL; + } + + PyObject *annotations; + /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */ + if (_PyDict_ContainsId(type->tp_dict, &PyId___annotations__)) { + annotations = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___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) { + if (Py_TYPE(annotations)->tp_descr_get) { + annotations = Py_TYPE(annotations)->tp_descr_get(annotations, NULL, + (PyObject *)type); + } else { + Py_INCREF(annotations); + } + } + } else { + annotations = PyDict_New(); + if (annotations) { + int result = _PyDict_SetItemId(type->tp_dict, &PyId___annotations__, annotations); + if (result) { + Py_CLEAR(annotations); + } else { + PyType_Modified(type); + } + } + } + return annotations; +} + +static int +type_set_annotations(PyTypeObject *type, PyObject *value, void *context) +{ + if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { + PyErr_Format(PyExc_TypeError, + "cannot set '__annotations__' attribute of immutable type '%s'", + type->tp_name); + return -1; + } + + int result; + if (value != NULL) { + /* set */ + result = _PyDict_SetItemId(type->tp_dict, &PyId___annotations__, value); + } else { + /* delete */ + if (!_PyDict_ContainsId(type->tp_dict, &PyId___annotations__)) { + PyErr_Format(PyExc_AttributeError, "__annotations__"); + return -1; + } + result = _PyDict_DelItemId(type->tp_dict, &PyId___annotations__); + } + + if (result == 0) { + PyType_Modified(type); + } + return result; +} + + /*[clinic input] type.__instancecheck__ -> bool @@ -937,6 +1044,7 @@ static PyGetSetDef type_getsets[] = { {"__dict__", (getter)type_dict, NULL, NULL}, {"__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}, {0} }; @@ -1006,8 +1114,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) if (type->tp_new == NULL) { _PyErr_Format(tstate, PyExc_TypeError, - "cannot create '%.100s' instances", - type->tp_name); + "cannot create '%s' instances", type->tp_name); return NULL; } @@ -1047,7 +1154,7 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) obj = _PyObject_GC_Malloc(size); } else { - obj = (PyObject *)PyObject_MALLOC(size); + obj = (PyObject *)PyObject_Malloc(size); } if (obj == NULL) { @@ -1057,10 +1164,10 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) memset(obj, '\0', size); if (type->tp_itemsize == 0) { - (void)PyObject_INIT(obj, type); + _PyObject_Init(obj, type); } else { - (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); + _PyObject_InitVar((PyVarObject *)obj, type, nitems); } if (_PyType_IS_GC(type)) { @@ -1782,7 +1889,7 @@ pmerge(PyObject *acc, PyObject **to_merge, Py_ssize_t to_merge_size) } out: - PyMem_Del(remain); + PyMem_Free(remain); return res; } @@ -1795,7 +1902,7 @@ mro_implementation(PyTypeObject *type) PyObject **to_merge; Py_ssize_t i, n; - if (type->tp_dict == NULL) { + if (!_PyType_IsReady(type)) { if (PyType_Ready(type) < 0) return NULL; } @@ -1862,7 +1969,7 @@ mro_implementation(PyTypeObject *type) result = PyList_New(1); if (result == NULL) { - PyMem_Del(to_merge); + PyMem_Free(to_merge); return NULL; } @@ -1872,7 +1979,7 @@ mro_implementation(PyTypeObject *type) Py_CLEAR(result); } - PyMem_Del(to_merge); + PyMem_Free(to_merge); return result; } @@ -1967,14 +2074,20 @@ mro_invoke(PyTypeObject *type) new_mro = PySequence_Tuple(mro_result); Py_DECREF(mro_result); - if (new_mro == NULL) + if (new_mro == NULL) { return NULL; + } - if (custom && mro_check(type, new_mro) < 0) { + if (PyTuple_GET_SIZE(new_mro) == 0) { Py_DECREF(new_mro); + PyErr_Format(PyExc_TypeError, "type MRO must not be empty"); return NULL; } + if (custom && mro_check(type, new_mro) < 0) { + Py_DECREF(new_mro); + return NULL; + } return new_mro; } @@ -2014,8 +2127,9 @@ mro_internal(PyTypeObject *type, PyObject **p_old_mro) new_mro = mro_invoke(type); /* might cause reentrance */ reent = (type->tp_mro != old_mro); Py_XDECREF(old_mro); - if (new_mro == NULL) + if (new_mro == NULL) { return -1; + } if (reent) { Py_DECREF(new_mro); @@ -2064,7 +2178,7 @@ best_base(PyObject *bases) return NULL; } base_i = (PyTypeObject *)base_proto; - if (base_i->tp_dict == NULL) { + if (!_PyType_IsReady(base_i)) { if (PyType_Ready(base_i) < 0) return NULL; } @@ -2141,8 +2255,8 @@ static void object_dealloc(PyObject *); static int object_init(PyObject *, PyObject *, PyObject *); static int update_slot(PyTypeObject *, PyObject *); static void fixup_slot_dispatchers(PyTypeObject *); -static int set_names(PyTypeObject *); -static int init_subclass(PyTypeObject *, PyObject *); +static int type_new_set_names(PyTypeObject *); +static int type_new_init_subclass(PyTypeObject *, PyObject *); /* * Helpers for __dict__ descriptor. We don't want to expose the dicts @@ -2387,398 +2501,467 @@ _PyType_CalculateMetaclass(PyTypeObject *metatype, PyObject *bases) return winner; } + +// Forward declaration static PyObject * -type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) -{ - PyObject *name, *bases = NULL, *orig_dict, *dict = NULL; - PyObject *qualname, *slots = NULL, *tmp, *newslots, *cell; - PyTypeObject *type = NULL, *base, *tmptype, *winner; - PyHeapTypeObject *et; - PyMemberDef *mp; - Py_ssize_t i, nbases, nslots, slotoffset, name_size; - int j, may_add_dict, may_add_weak, add_dict, add_weak; - _Py_IDENTIFIER(__qualname__); - _Py_IDENTIFIER(__slots__); - _Py_IDENTIFIER(__classcell__); +type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds); - assert(args != NULL && PyTuple_Check(args)); - assert(kwds == NULL || PyDict_Check(kwds)); +typedef struct { + PyTypeObject *metatype; + PyObject *args; + PyObject *kwds; + PyObject *orig_dict; + PyObject *name; + PyObject *bases; + PyTypeObject *base; + PyObject *slots; + Py_ssize_t nslot; + int add_dict; + int add_weak; + int may_add_dict; + int may_add_weak; +} type_new_ctx; - /* Check arguments: (name, bases, dict) */ - if (!PyArg_ParseTuple(args, "UO!O!:type.__new__", &name, &PyTuple_Type, - &bases, &PyDict_Type, &orig_dict)) - return NULL; - /* Adjust for empty tuple bases */ - nbases = PyTuple_GET_SIZE(bases); - if (nbases == 0) { - base = &PyBaseObject_Type; - bases = PyTuple_Pack(1, base); - if (bases == NULL) - return NULL; - nbases = 1; - } - else { - _Py_IDENTIFIER(__mro_entries__); - for (i = 0; i < nbases; i++) { - tmp = PyTuple_GET_ITEM(bases, i); - if (PyType_Check(tmp)) { - continue; - } - if (_PyObject_LookupAttrId(tmp, &PyId___mro_entries__, &tmp) < 0) { - return NULL; - } - if (tmp != NULL) { +/* Check for valid slot names and two special cases */ +static int +type_new_visit_slots(type_new_ctx *ctx) +{ + PyObject *slots = ctx->slots; + Py_ssize_t nslot = ctx->nslot; + for (Py_ssize_t i = 0; i < nslot; i++) { + PyObject *name = PyTuple_GET_ITEM(slots, i); + if (!valid_identifier(name)) { + return -1; + } + assert(PyUnicode_Check(name)); + if (_PyUnicode_EqualToASCIIId(name, &PyId___dict__)) { + if (!ctx->may_add_dict || ctx->add_dict != 0) { PyErr_SetString(PyExc_TypeError, - "type() doesn't support MRO entry resolution; " - "use types.new_class()"); - Py_DECREF(tmp); - return NULL; + "__dict__ slot disallowed: " + "we already got one"); + return -1; } + ctx->add_dict++; } - /* Search the bases for the proper metatype to deal with this: */ - winner = _PyType_CalculateMetaclass(metatype, bases); - if (winner == NULL) { - return NULL; - } - - if (winner != metatype) { - if (winner->tp_new != type_new) /* Pass it to the winner */ - return winner->tp_new(winner, args, kwds); - metatype = winner; - } - - /* Calculate best base, and check that all bases are type objects */ - base = best_base(bases); - if (base == NULL) { - return NULL; + if (_PyUnicode_EqualToASCIIId(name, &PyId___weakref__)) { + if (!ctx->may_add_weak || ctx->add_weak != 0) { + PyErr_SetString(PyExc_TypeError, + "__weakref__ slot disallowed: " + "either we already got one, " + "or __itemsize__ != 0"); + return -1; + } + ctx->add_weak++; } - - Py_INCREF(bases); } + return 0; +} - /* Use "goto error" from this point on as we now own the reference to "bases". */ - dict = PyDict_Copy(orig_dict); - if (dict == NULL) - goto error; +/* Copy slots into a list, mangle names and sort them. + Sorted names are needed for __class__ assignment. + Convert them back to tuple at the end. +*/ +static PyObject* +type_new_copy_slots(type_new_ctx *ctx, PyObject *dict) +{ + PyObject *slots = ctx->slots; + Py_ssize_t nslot = ctx->nslot; - /* Check for a __slots__ sequence variable in dict, and count it */ - slots = _PyDict_GetItemIdWithError(dict, &PyId___slots__); - nslots = 0; - add_dict = 0; - add_weak = 0; - may_add_dict = base->tp_dictoffset == 0; - may_add_weak = base->tp_weaklistoffset == 0 && base->tp_itemsize == 0; - if (slots == NULL) { - if (PyErr_Occurred()) { - goto error; - } - if (may_add_dict) { - add_dict++; - } - if (may_add_weak) { - add_weak++; - } + Py_ssize_t new_nslot = nslot - ctx->add_dict - ctx->add_weak; + PyObject *new_slots = PyList_New(new_nslot); + if (new_slots == NULL) { + return NULL; } - else { - /* Have slots */ - - /* Make it into a tuple */ - if (PyUnicode_Check(slots)) - slots = PyTuple_Pack(1, slots); - else - slots = PySequence_Tuple(slots); - if (slots == NULL) - goto error; - assert(PyTuple_Check(slots)); - /* Are slots allowed? */ - nslots = PyTuple_GET_SIZE(slots); - if (nslots > 0 && base->tp_itemsize != 0) { - PyErr_Format(PyExc_TypeError, - "nonempty __slots__ " - "not supported for subtype of '%s'", - base->tp_name); - goto error; + Py_ssize_t j = 0; + for (Py_ssize_t i = 0; i < nslot; i++) { + PyObject *slot = PyTuple_GET_ITEM(slots, i); + if ((ctx->add_dict && + _PyUnicode_EqualToASCIIId(slot, &PyId___dict__)) || + (ctx->add_weak && + _PyUnicode_EqualToASCIIString(slot, "__weakref__"))) + { + continue; } - /* Check for valid slot names and two special cases */ - for (i = 0; i < nslots; i++) { - PyObject *tmp = PyTuple_GET_ITEM(slots, i); - if (!valid_identifier(tmp)) - goto error; - assert(PyUnicode_Check(tmp)); - if (_PyUnicode_EqualToASCIIId(tmp, &PyId___dict__)) { - if (!may_add_dict || add_dict) { - PyErr_SetString(PyExc_TypeError, - "__dict__ slot disallowed: " - "we already got one"); - goto error; - } - add_dict++; - } - if (_PyUnicode_EqualToASCIIString(tmp, "__weakref__")) { - if (!may_add_weak || add_weak) { - PyErr_SetString(PyExc_TypeError, - "__weakref__ slot disallowed: " - "either we already got one, " - "or __itemsize__ != 0"); - goto error; - } - add_weak++; - } + slot =_Py_Mangle(ctx->name, slot); + if (!slot) { + goto error; } + PyList_SET_ITEM(new_slots, j, slot); - /* Copy slots into a list, mangle names and sort them. - Sorted names are needed for __class__ assignment. - Convert them back to tuple at the end. - */ - newslots = PyList_New(nslots - add_dict - add_weak); - if (newslots == NULL) + int r = PyDict_Contains(dict, slot); + if (r < 0) { goto error; - for (i = j = 0; i < nslots; i++) { - tmp = PyTuple_GET_ITEM(slots, i); - if ((add_dict && - _PyUnicode_EqualToASCIIId(tmp, &PyId___dict__)) || - (add_weak && - _PyUnicode_EqualToASCIIString(tmp, "__weakref__"))) - continue; - tmp =_Py_Mangle(name, tmp); - if (!tmp) { - Py_DECREF(newslots); - goto error; - } - PyList_SET_ITEM(newslots, j, tmp); - if (PyDict_GetItemWithError(dict, tmp)) { - /* CPython inserts __qualname__ and __classcell__ (when needed) - into the namespace when creating a class. They will be deleted - below so won't act as class variables. */ - if (!_PyUnicode_EqualToASCIIId(tmp, &PyId___qualname__) && - !_PyUnicode_EqualToASCIIId(tmp, &PyId___classcell__)) { - PyErr_Format(PyExc_ValueError, - "%R in __slots__ conflicts with class variable", - tmp); - Py_DECREF(newslots); - goto error; - } - } - else if (PyErr_Occurred()) { - Py_DECREF(newslots); + } + if (r > 0) { + /* CPython inserts __qualname__ and __classcell__ (when needed) + into the namespace when creating a class. They will be deleted + below so won't act as class variables. */ + if (!_PyUnicode_EqualToASCIIId(slot, &PyId___qualname__) && + !_PyUnicode_EqualToASCIIId(slot, &PyId___classcell__)) + { + PyErr_Format(PyExc_ValueError, + "%R in __slots__ conflicts with class variable", + slot); goto error; } - j++; - } - assert(j == nslots - add_dict - add_weak); - nslots = j; - Py_CLEAR(slots); - if (PyList_Sort(newslots) == -1) { - Py_DECREF(newslots); - goto error; } - slots = PyList_AsTuple(newslots); - Py_DECREF(newslots); - if (slots == NULL) - goto error; - /* Secondary bases may provide weakrefs or dict */ - if (nbases > 1 && - ((may_add_dict && !add_dict) || - (may_add_weak && !add_weak))) { - for (i = 0; i < nbases; i++) { - tmp = PyTuple_GET_ITEM(bases, i); - if (tmp == (PyObject *)base) - continue; /* Skip primary base */ - assert(PyType_Check(tmp)); - tmptype = (PyTypeObject *)tmp; - if (may_add_dict && !add_dict && - tmptype->tp_dictoffset != 0) - add_dict++; - if (may_add_weak && !add_weak && - tmptype->tp_weaklistoffset != 0) - add_weak++; - if (may_add_dict && !add_dict) - continue; - if (may_add_weak && !add_weak) - continue; - /* Nothing more to check */ - break; - } - } + j++; } + assert(j == new_nslot); - /* Allocate the type object */ - type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots); - if (type == NULL) + if (PyList_Sort(new_slots) == -1) { goto error; + } - /* Keep name and slots alive in the extended type object */ - et = (PyHeapTypeObject *)type; - Py_INCREF(name); - et->ht_name = name; - et->ht_slots = slots; - slots = NULL; + PyObject *tuple = PyList_AsTuple(new_slots); + Py_DECREF(new_slots); + if (tuple == NULL) { + return NULL; + } - /* Initialize tp_flags */ - // All heap types need GC, since we can create a reference cycle by storing - // an instance on one of its parents: - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC; + assert(PyTuple_GET_SIZE(tuple) == new_nslot); + return tuple; - /* Initialize essential fields */ - type->tp_as_async = &et->as_async; - type->tp_as_number = &et->as_number; - type->tp_as_sequence = &et->as_sequence; - type->tp_as_mapping = &et->as_mapping; - type->tp_as_buffer = &et->as_buffer; - type->tp_name = PyUnicode_AsUTF8AndSize(name, &name_size); - if (!type->tp_name) - goto error; - if (strlen(type->tp_name) != (size_t)name_size) { - PyErr_SetString(PyExc_ValueError, - "type name must not contain null characters"); - goto error; - } +error: + Py_DECREF(new_slots); + return NULL; +} - /* Set tp_base and tp_bases */ - type->tp_bases = bases; - bases = NULL; - Py_INCREF(base); - type->tp_base = base; - /* Initialize tp_dict from passed-in dict */ - Py_INCREF(dict); - type->tp_dict = dict; +static void +type_new_slots_bases(type_new_ctx *ctx) +{ + Py_ssize_t nbases = PyTuple_GET_SIZE(ctx->bases); + if (nbases > 1 && + ((ctx->may_add_dict && ctx->add_dict == 0) || + (ctx->may_add_weak && ctx->add_weak == 0))) + { + for (Py_ssize_t i = 0; i < nbases; i++) { + PyObject *base = PyTuple_GET_ITEM(ctx->bases, i); + if (base == (PyObject *)ctx->base) { + /* Skip primary base */ + continue; + } - /* Set __module__ in the dict */ - if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) { - if (PyErr_Occurred()) { - goto error; - } - tmp = PyEval_GetGlobals(); - if (tmp != NULL) { - tmp = _PyDict_GetItemIdWithError(tmp, &PyId___name__); - if (tmp != NULL) { - if (_PyDict_SetItemId(dict, &PyId___module__, - tmp) < 0) - goto error; + assert(PyType_Check(base)); + PyTypeObject *type = (PyTypeObject *)base; + if (ctx->may_add_dict && ctx->add_dict == 0 && + type->tp_dictoffset != 0) + { + ctx->add_dict++; } - else if (PyErr_Occurred()) { - goto error; + if (ctx->may_add_weak && ctx->add_weak == 0 && + type->tp_weaklistoffset != 0) + { + ctx->add_weak++; + } + if (ctx->may_add_dict && ctx->add_dict == 0) { + continue; } + if (ctx->may_add_weak && ctx->add_weak == 0) { + continue; + } + /* Nothing more to check */ + break; } } +} - /* Set ht_qualname to dict['__qualname__'] if available, else to - __name__. The __qualname__ accessor will look for ht_qualname. - */ - qualname = _PyDict_GetItemIdWithError(dict, &PyId___qualname__); - if (qualname != NULL) { - if (!PyUnicode_Check(qualname)) { - PyErr_Format(PyExc_TypeError, - "type __qualname__ must be a str, not %s", - Py_TYPE(qualname)->tp_name); - goto error; - } + +static int +type_new_slots_impl(type_new_ctx *ctx, PyObject *dict) +{ + /* Are slots allowed? */ + if (ctx->nslot > 0 && ctx->base->tp_itemsize != 0) { + PyErr_Format(PyExc_TypeError, + "nonempty __slots__ not supported for subtype of '%s'", + ctx->base->tp_name); + return -1; } - else if (PyErr_Occurred()) { - goto error; + + if (type_new_visit_slots(ctx) < 0) { + return -1; } - et->ht_qualname = qualname ? qualname : et->ht_name; - Py_INCREF(et->ht_qualname); - if (qualname != NULL && _PyDict_DelItemId(dict, &PyId___qualname__) < 0) - goto error; - /* Set ht_module */ - et->ht_module = NULL; + PyObject *new_slots = type_new_copy_slots(ctx, dict); + if (new_slots == NULL) { + return -1; + } + assert(PyTuple_CheckExact(new_slots)); - /* Set tp_doc to a copy of dict['__doc__'], if the latter is there - and is a string. The __doc__ accessor will first look for tp_doc; - if that fails, it will still look into __dict__. - */ - { - PyObject *doc = _PyDict_GetItemIdWithError(dict, &PyId___doc__); - if (doc != NULL && PyUnicode_Check(doc)) { - Py_ssize_t len; - const char *doc_str; - char *tp_doc; - - doc_str = PyUnicode_AsUTF8(doc); - if (doc_str == NULL) - goto error; - /* Silently truncate the docstring if it contains null bytes. */ - len = strlen(doc_str); - tp_doc = (char *)PyObject_MALLOC(len + 1); - if (tp_doc == NULL) { - PyErr_NoMemory(); - goto error; - } - memcpy(tp_doc, doc_str, len + 1); - type->tp_doc = tp_doc; + Py_XSETREF(ctx->slots, new_slots); + ctx->nslot = PyTuple_GET_SIZE(new_slots); + + /* Secondary bases may provide weakrefs or dict */ + type_new_slots_bases(ctx); + return 0; +} + + +static Py_ssize_t +type_new_slots(type_new_ctx *ctx, PyObject *dict) +{ + // Check for a __slots__ sequence variable in dict, and count it + ctx->add_dict = 0; + ctx->add_weak = 0; + ctx->may_add_dict = (ctx->base->tp_dictoffset == 0); + ctx->may_add_weak = (ctx->base->tp_weaklistoffset == 0 + && ctx->base->tp_itemsize == 0); + + if (ctx->slots == NULL) { + if (ctx->may_add_dict) { + ctx->add_dict++; } - else if (doc == NULL && PyErr_Occurred()) { - goto error; + if (ctx->may_add_weak) { + ctx->add_weak++; + } + } + else { + /* Have slots */ + if (type_new_slots_impl(ctx, dict) < 0) { + return -1; } } + return 0; +} - /* Special-case __new__: if it's a plain function, - make it a static function */ - tmp = _PyDict_GetItemIdWithError(dict, &PyId___new__); - if (tmp != NULL && PyFunction_Check(tmp)) { - tmp = PyStaticMethod_New(tmp); - if (tmp == NULL) - goto error; - if (_PyDict_SetItemId(dict, &PyId___new__, tmp) < 0) { - Py_DECREF(tmp); - goto error; + +static PyTypeObject* +type_new_alloc(type_new_ctx *ctx) +{ + PyTypeObject *metatype = ctx->metatype; + PyTypeObject *type; + + // Allocate the type object + type = (PyTypeObject *)metatype->tp_alloc(metatype, ctx->nslot); + if (type == NULL) { + return NULL; + } + PyHeapTypeObject *et = (PyHeapTypeObject *)type; + + // Initialize tp_flags. + // All heap types need GC, since we can create a reference cycle by storing + // an instance on one of its parents. + type->tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC); + + // Initialize essential fields + type->tp_as_async = &et->as_async; + type->tp_as_number = &et->as_number; + type->tp_as_sequence = &et->as_sequence; + type->tp_as_mapping = &et->as_mapping; + type->tp_as_buffer = &et->as_buffer; + + type->tp_bases = Py_NewRef(ctx->bases); + type->tp_base = (PyTypeObject *)Py_NewRef(ctx->base); + + type->tp_dealloc = subtype_dealloc; + /* Always override allocation strategy to use regular heap */ + type->tp_alloc = PyType_GenericAlloc; + type->tp_free = PyObject_GC_Del; + + type->tp_traverse = subtype_traverse; + type->tp_clear = subtype_clear; + + et->ht_name = Py_NewRef(ctx->name); + et->ht_module = NULL; + + return type; +} + + +static int +type_new_set_name(const type_new_ctx *ctx, PyTypeObject *type) +{ + Py_ssize_t name_size; + type->tp_name = PyUnicode_AsUTF8AndSize(ctx->name, &name_size); + if (!type->tp_name) { + return -1; + } + if (strlen(type->tp_name) != (size_t)name_size) { + PyErr_SetString(PyExc_ValueError, + "type name must not contain null characters"); + return -1; + } + return 0; +} + + +/* Set __module__ in the dict */ +static int +type_new_set_module(PyTypeObject *type) +{ + int r = _PyDict_ContainsId(type->tp_dict, &PyId___module__); + if (r < 0) { + return -1; + } + if (r > 0) { + return 0; + } + + PyObject *globals = PyEval_GetGlobals(); + if (globals == NULL) { + return 0; + } + + PyObject *module = _PyDict_GetItemIdWithError(globals, &PyId___name__); + if (module == NULL) { + if (PyErr_Occurred()) { + return -1; } - Py_DECREF(tmp); + return 0; } - else if (tmp == NULL && PyErr_Occurred()) { - goto error; + + if (_PyDict_SetItemId(type->tp_dict, &PyId___module__, module) < 0) { + return -1; } + return 0; +} - /* Special-case __init_subclass__ and __class_getitem__: - if they are plain functions, make them classmethods */ - tmp = _PyDict_GetItemIdWithError(dict, &PyId___init_subclass__); - if (tmp != NULL && PyFunction_Check(tmp)) { - tmp = PyClassMethod_New(tmp); - if (tmp == NULL) - goto error; - if (_PyDict_SetItemId(dict, &PyId___init_subclass__, tmp) < 0) { - Py_DECREF(tmp); - goto error; + +/* Set ht_qualname to dict['__qualname__'] if available, else to + __name__. The __qualname__ accessor will look for ht_qualname. */ +static int +type_new_set_ht_name(PyTypeObject *type) +{ + PyHeapTypeObject *et = (PyHeapTypeObject *)type; + PyObject *qualname = _PyDict_GetItemIdWithError(type->tp_dict, + &PyId___qualname__); + if (qualname != NULL) { + if (!PyUnicode_Check(qualname)) { + PyErr_Format(PyExc_TypeError, + "type __qualname__ must be a str, not %s", + Py_TYPE(qualname)->tp_name); + return -1; + } + et->ht_qualname = Py_NewRef(qualname); + if (_PyDict_DelItemId(type->tp_dict, &PyId___qualname__) < 0) { + return -1; } - Py_DECREF(tmp); } - else if (tmp == NULL && PyErr_Occurred()) { - goto error; + else { + if (PyErr_Occurred()) { + return -1; + } + et->ht_qualname = Py_NewRef(et->ht_name); } + return 0; +} - tmp = _PyDict_GetItemIdWithError(dict, &PyId___class_getitem__); - if (tmp != NULL && PyFunction_Check(tmp)) { - tmp = PyClassMethod_New(tmp); - if (tmp == NULL) - goto error; - if (_PyDict_SetItemId(dict, &PyId___class_getitem__, tmp) < 0) { - Py_DECREF(tmp); - goto error; + +/* Set tp_doc to a copy of dict['__doc__'], if the latter is there + and is a string. The __doc__ accessor will first look for tp_doc; + if that fails, it will still look into __dict__. */ +static int +type_new_set_doc(PyTypeObject *type) +{ + PyObject *doc = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___doc__); + if (doc == NULL) { + if (PyErr_Occurred()) { + return -1; } - Py_DECREF(tmp); + // no __doc__ key + return 0; } - else if (tmp == NULL && PyErr_Occurred()) { - goto error; + if (!PyUnicode_Check(doc)) { + // ignore non-string __doc__ + return 0; + } + + const char *doc_str = PyUnicode_AsUTF8(doc); + if (doc_str == NULL) { + return -1; + } + + // Silently truncate the docstring if it contains a null byte + Py_ssize_t size = strlen(doc_str) + 1; + char *tp_doc = (char *)PyObject_Malloc(size); + if (tp_doc == NULL) { + PyErr_NoMemory(); + return -1; + } + + memcpy(tp_doc, doc_str, size); + type->tp_doc = tp_doc; + return 0; +} + + +static int +type_new_staticmethod(PyTypeObject *type, _Py_Identifier *attr_id) +{ + PyObject *func = _PyDict_GetItemIdWithError(type->tp_dict, attr_id); + if (func == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + if (!PyFunction_Check(func)) { + return 0; + } + + PyObject *static_func = PyStaticMethod_New(func); + if (static_func == NULL) { + return -1; + } + if (_PyDict_SetItemId(type->tp_dict, attr_id, static_func) < 0) { + Py_DECREF(static_func); + return -1; + } + Py_DECREF(static_func); + return 0; +} + + +static int +type_new_classmethod(PyTypeObject *type, _Py_Identifier *attr_id) +{ + PyObject *func = _PyDict_GetItemIdWithError(type->tp_dict, attr_id); + if (func == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; } + if (!PyFunction_Check(func)) { + return 0; + } + + PyObject *method = PyClassMethod_New(func); + if (method == NULL) { + return -1; + } + + if (_PyDict_SetItemId(type->tp_dict, attr_id, method) < 0) { + Py_DECREF(method); + return -1; + } + Py_DECREF(method); + return 0; +} + - /* Add descriptors for custom slots from __slots__, or for __dict__ */ - mp = PyHeapType_GET_MEMBERS(et); - slotoffset = base->tp_basicsize; +/* Add descriptors for custom slots from __slots__, or for __dict__ */ +static int +type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) +{ + PyHeapTypeObject *et = (PyHeapTypeObject *)type; + Py_ssize_t slotoffset = ctx->base->tp_basicsize; if (et->ht_slots != NULL) { - for (i = 0; i < nslots; i++, mp++) { + PyMemberDef *mp = PyHeapType_GET_MEMBERS(et); + Py_ssize_t nslot = PyTuple_GET_SIZE(et->ht_slots); + for (Py_ssize_t i = 0; i < nslot; i++, mp++) { mp->name = PyUnicode_AsUTF8( PyTuple_GET_ITEM(et->ht_slots, i)); - if (mp->name == NULL) - goto error; + if (mp->name == NULL) { + return -1; + } mp->type = T_OBJECT_EX; mp->offset = slotoffset; @@ -2789,95 +2972,391 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) slotoffset += sizeof(PyObject *); } } - if (add_dict) { - if (base->tp_itemsize) + + if (ctx->add_dict) { + if (ctx->base->tp_itemsize) { type->tp_dictoffset = -(long)sizeof(PyObject *); - else + } + else { type->tp_dictoffset = slotoffset; + } slotoffset += sizeof(PyObject *); } - if (add_weak) { - assert(!base->tp_itemsize); + + if (ctx->add_weak) { + assert(!ctx->base->tp_itemsize); type->tp_weaklistoffset = slotoffset; slotoffset += sizeof(PyObject *); } + type->tp_basicsize = slotoffset; - type->tp_itemsize = base->tp_itemsize; + type->tp_itemsize = ctx->base->tp_itemsize; type->tp_members = PyHeapType_GET_MEMBERS(et); + return 0; +} + - if (type->tp_weaklistoffset && type->tp_dictoffset) +static void +type_new_set_slots(const type_new_ctx *ctx, PyTypeObject *type) +{ + if (type->tp_weaklistoffset && type->tp_dictoffset) { type->tp_getset = subtype_getsets_full; - else if (type->tp_weaklistoffset && !type->tp_dictoffset) + } + else if (type->tp_weaklistoffset && !type->tp_dictoffset) { type->tp_getset = subtype_getsets_weakref_only; - else if (!type->tp_weaklistoffset && type->tp_dictoffset) + } + else if (!type->tp_weaklistoffset && type->tp_dictoffset) { type->tp_getset = subtype_getsets_dict_only; - else + } + else { type->tp_getset = NULL; + } /* Special case some slots */ - if (type->tp_dictoffset != 0 || nslots > 0) { - if (base->tp_getattr == NULL && base->tp_getattro == NULL) + if (type->tp_dictoffset != 0 || ctx->nslot > 0) { + PyTypeObject *base = ctx->base; + if (base->tp_getattr == NULL && base->tp_getattro == NULL) { type->tp_getattro = PyObject_GenericGetAttr; - if (base->tp_setattr == NULL && base->tp_setattro == NULL) + } + if (base->tp_setattr == NULL && base->tp_setattro == NULL) { type->tp_setattro = PyObject_GenericSetAttr; + } } - type->tp_dealloc = subtype_dealloc; +} - /* Always override allocation strategy to use regular heap */ - type->tp_alloc = PyType_GenericAlloc; - type->tp_free = PyObject_GC_Del; - type->tp_traverse = subtype_traverse; - type->tp_clear = subtype_clear; - /* store type in class' cell if one is supplied */ - cell = _PyDict_GetItemIdWithError(dict, &PyId___classcell__); - if (cell != NULL) { - /* At least one method requires a reference to its defining class */ - if (!PyCell_Check(cell)) { - PyErr_Format(PyExc_TypeError, - "__classcell__ must be a nonlocal cell, not %.200R", - Py_TYPE(cell)); - goto error; +/* store type in class' cell if one is supplied */ +static int +type_new_set_classcell(PyTypeObject *type) +{ + PyObject *cell = _PyDict_GetItemIdWithError(type->tp_dict, + &PyId___classcell__); + if (cell == NULL) { + if (PyErr_Occurred()) { + return -1; } - PyCell_Set(cell, (PyObject *) type); - if (_PyDict_DelItemId(dict, &PyId___classcell__) < 0) { - goto error; + return 0; + } + + /* At least one method requires a reference to its defining class */ + if (!PyCell_Check(cell)) { + PyErr_Format(PyExc_TypeError, + "__classcell__ must be a nonlocal cell, not %.200R", + Py_TYPE(cell)); + return -1; + } + + (void)PyCell_Set(cell, (PyObject *) type); + if (_PyDict_DelItemId(type->tp_dict, &PyId___classcell__) < 0) { + return -1; + } + return 0; +} + + +static int +type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type) +{ + if (type_new_set_name(ctx, type) < 0) { + return -1; + } + + if (type_new_set_module(type) < 0) { + return -1; + } + + if (type_new_set_ht_name(type) < 0) { + return -1; + } + + if (type_new_set_doc(type) < 0) { + return -1; + } + + /* Special-case __new__: if it's a plain function, + make it a static function */ + if (type_new_staticmethod(type, &PyId___new__) < 0) { + return -1; + } + + /* Special-case __init_subclass__ and __class_getitem__: + if they are plain functions, make them classmethods */ + if (type_new_classmethod(type, &PyId___init_subclass__) < 0) { + return -1; + } + if (type_new_classmethod(type, &PyId___class_getitem__) < 0) { + return -1; + } + + if (type_new_descriptors(ctx, type) < 0) { + return -1; + } + + type_new_set_slots(ctx, type); + + if (type_new_set_classcell(type) < 0) { + return -1; + } + return 0; +} + + +static int +type_new_get_slots(type_new_ctx *ctx, PyObject *dict) +{ + _Py_IDENTIFIER(__slots__); + PyObject *slots = _PyDict_GetItemIdWithError(dict, &PyId___slots__); + if (slots == NULL) { + if (PyErr_Occurred()) { + return -1; } + ctx->slots = NULL; + ctx->nslot = 0; + return 0; + } + + // Make it into a tuple + PyObject *new_slots; + if (PyUnicode_Check(slots)) { + new_slots = PyTuple_Pack(1, slots); + } + else { + new_slots = PySequence_Tuple(slots); + } + if (new_slots == NULL) { + return -1; } - else if (PyErr_Occurred()) { + assert(PyTuple_CheckExact(new_slots)); + ctx->slots = new_slots; + ctx->nslot = PyTuple_GET_SIZE(new_slots); + return 0; +} + + +static PyTypeObject* +type_new_init(type_new_ctx *ctx) +{ + PyObject *dict = PyDict_Copy(ctx->orig_dict); + if (dict == NULL) { + goto error; + } + + if (type_new_get_slots(ctx, dict) < 0) { + goto error; + } + assert(!PyErr_Occurred()); + + if (type_new_slots(ctx, dict) < 0) { + goto error; + } + + PyTypeObject *type = type_new_alloc(ctx); + if (type == NULL) { + goto error; + } + + type->tp_dict = dict; + + PyHeapTypeObject *et = (PyHeapTypeObject*)type; + et->ht_slots = ctx->slots; + ctx->slots = NULL; + + return type; + +error: + Py_CLEAR(ctx->slots); + Py_XDECREF(dict); + return NULL; +} + + +static PyObject* +type_new_impl(type_new_ctx *ctx) +{ + PyTypeObject *type = type_new_init(ctx); + if (type == NULL) { + return NULL; + } + + if (type_new_set_attrs(ctx, type) < 0) { goto error; } /* Initialize the rest */ - if (PyType_Ready(type) < 0) + if (PyType_Ready(type) < 0) { goto error; + } - /* Put the proper slots in place */ + // Put the proper slots in place fixup_slot_dispatchers(type); if (type->tp_dictoffset) { + PyHeapTypeObject *et = (PyHeapTypeObject*)type; et->ht_cached_keys = _PyDict_NewKeysForClass(); } - if (set_names(type) < 0) + if (type_new_set_names(type) < 0) { goto error; + } - if (init_subclass(type, kwds) < 0) + if (type_new_init_subclass(type, ctx->kwds) < 0) { goto error; + } - Py_DECREF(dict); + assert(_PyType_CheckConsistency(type)); return (PyObject *)type; error: - Py_XDECREF(dict); - Py_XDECREF(bases); - Py_XDECREF(slots); - Py_XDECREF(type); + Py_DECREF(type); return NULL; } -static const short slotoffsets[] = { - -1, /* invalid slot */ + +static int +type_new_get_bases(type_new_ctx *ctx, PyObject **type) +{ + Py_ssize_t nbases = PyTuple_GET_SIZE(ctx->bases); + if (nbases == 0) { + // Adjust for empty tuple bases + ctx->base = &PyBaseObject_Type; + PyObject *new_bases = PyTuple_Pack(1, ctx->base); + if (new_bases == NULL) { + return -1; + } + ctx->bases = new_bases; + return 0; + } + + _Py_IDENTIFIER(__mro_entries__); + for (Py_ssize_t i = 0; i < nbases; i++) { + PyObject *base = PyTuple_GET_ITEM(ctx->bases, i); + if (PyType_Check(base)) { + continue; + } + PyObject *mro_entries; + if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, + &mro_entries) < 0) { + return -1; + } + if (mro_entries != NULL) { + PyErr_SetString(PyExc_TypeError, + "type() doesn't support MRO entry resolution; " + "use types.new_class()"); + Py_DECREF(mro_entries); + return -1; + } + } + + // Search the bases for the proper metatype to deal with this + PyTypeObject *winner; + winner = _PyType_CalculateMetaclass(ctx->metatype, ctx->bases); + if (winner == NULL) { + return -1; + } + + if (winner != ctx->metatype) { + if (winner->tp_new != type_new) { + /* Pass it to the winner */ + *type = winner->tp_new(winner, ctx->args, ctx->kwds); + if (*type == NULL) { + return -1; + } + return 1; + } + + ctx->metatype = winner; + } + + /* Calculate best base, and check that all bases are type objects */ + PyTypeObject *base = best_base(ctx->bases); + if (base == NULL) { + return -1; + } + + ctx->base = base; + ctx->bases = Py_NewRef(ctx->bases); + return 0; +} + + +static PyObject * +type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) +{ + assert(args != NULL && PyTuple_Check(args)); + assert(kwds == NULL || PyDict_Check(kwds)); + + /* Parse arguments: (name, bases, dict) */ + PyObject *name, *bases, *orig_dict; + if (!PyArg_ParseTuple(args, "UO!O!:type.__new__", + &name, + &PyTuple_Type, &bases, + &PyDict_Type, &orig_dict)) + { + return NULL; + } + + type_new_ctx ctx = { + .metatype = metatype, + .args = args, + .kwds = kwds, + .orig_dict = orig_dict, + .name = name, + .bases = bases, + .base = NULL, + .slots = NULL, + .nslot = 0, + .add_dict = 0, + .add_weak = 0, + .may_add_dict = 0, + .may_add_weak = 0}; + PyObject *type = NULL; + int res = type_new_get_bases(&ctx, &type); + if (res < 0) { + assert(PyErr_Occurred()); + return NULL; + } + if (res == 1) { + assert(type != NULL); + return type; + } + assert(ctx.base != NULL); + assert(ctx.bases != NULL); + + type = type_new_impl(&ctx); + Py_DECREF(ctx.bases); + return type; +} + + +static PyObject * +type_vectorcall(PyObject *metatype, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs == 1 && metatype == (PyObject *)&PyType_Type){ + if (!_PyArg_NoKwnames("type", kwnames)) { + return NULL; + } + return Py_NewRef(Py_TYPE(args[0])); + } + /* In other (much less common) cases, fall back to + more flexible calling conventions. */ + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_MakeTpCall(tstate, metatype, args, nargs, kwnames); +} + +/* An array of type slot offsets corresponding to Py_tp_* constants, + * for use in e.g. PyType_Spec and PyType_GetSlot. + * Each entry has two offsets: "slot_offset" and "subslot_offset". + * If is subslot_offset is -1, slot_offset is an offset within the + * PyTypeObject struct. + * Otherwise slot_offset is an offset to a pointer to a sub-slots struct + * (such as "tp_as_number"), and subslot_offset is the offset within + * that struct. + * The actual table is generated by a script. + */ +static const PySlot_Offset pyslot_offsets[] = { + {0, 0}, #include "typeslots.inc" }; @@ -2893,10 +3372,12 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) PyHeapTypeObject *res; PyObject *modname; PyTypeObject *type, *base; + int r; const PyType_Slot *slot; Py_ssize_t nmembers, weaklistoffset, dictoffset, vectorcalloffset; char *res_start; + short slot_offset, subslot_offset; nmembers = weaklistoffset = dictoffset = vectorcalloffset = 0; for (slot = spec->slots; slot->slot; slot++) { @@ -2982,8 +3463,9 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) } } else if (!PyTuple_Check(bases)) { - PyErr_SetString(PyExc_SystemError, "bases is not a tuple"); - goto fail; + bases = PyTuple_Pack(1, bases); + if (!bases) + goto fail; } else { Py_INCREF(bases); @@ -3019,7 +3501,7 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) for (slot = spec->slots; slot->slot; slot++) { if (slot->slot < 0 - || (size_t)slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) { + || (size_t)slot->slot >= Py_ARRAY_LENGTH(pyslot_offsets)) { PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); goto fail; } @@ -3030,15 +3512,18 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) 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 */ - const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); - size_t len = strlen(old_doc)+1; - char *tp_doc = PyObject_MALLOC(len); + 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; } - memcpy(tp_doc, old_doc, len); + memcpy(tp_doc, slot->pfunc, len); type->tp_doc = tp_doc; } else if (slot->slot == Py_tp_members) { @@ -3049,7 +3534,15 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) } else { /* Copy other slots directly */ - *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; + 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; + } } } if (type->tp_dealloc == NULL) { @@ -3070,6 +3563,16 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) res->ht_cached_keys = _PyDict_NewKeysForClass(); } + if (type->tp_doc) { + PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); + if (!__doc__) + goto fail; + r = _PyDict_SetItemId(type->tp_dict, &PyId___doc__, __doc__); + Py_DECREF(__doc__); + if (r < 0) + goto fail; + } + if (weaklistoffset) { type->tp_weaklistoffset = weaklistoffset; if (PyDict_DelItemString((PyObject *)type->tp_dict, "__weaklistoffset__") < 0) @@ -3082,21 +3585,21 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) } /* Set type.__module__ */ - if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___module__) == NULL) { - if (PyErr_Occurred()) { - goto fail; - } + r = _PyDict_ContainsId(type->tp_dict, &PyId___module__); + if (r < 0) { + goto fail; + } + if (r == 0) { s = strrchr(spec->name, '.'); if (s != NULL) { - int err; modname = PyUnicode_FromStringAndSize( spec->name, (Py_ssize_t)(s - spec->name)); if (modname == NULL) { goto fail; } - err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); + r = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); Py_DECREF(modname); - if (err != 0) + if (r != 0) goto fail; } else { if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, @@ -3130,15 +3633,23 @@ _PyType_GetQualName(PyTypeObject *type) void * PyType_GetSlot(PyTypeObject *type, int slot) { - if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) || slot < 0) { + void *parent_slot; + int slots_len = Py_ARRAY_LENGTH(pyslot_offsets); + + if (slot <= 0 || slot >= slots_len) { PyErr_BadInternalCall(); return NULL; } - if ((size_t)slot >= Py_ARRAY_LENGTH(slotoffsets)) { - /* Extension module requesting slot from a future version */ + + parent_slot = *(void**)((char*)type + pyslot_offsets[slot].slot_offset); + if (parent_slot == NULL) { return NULL; } - return *(void**)(((char*)type) + slotoffsets[slot]); + /* Return slot directly if we have no sub slot. */ + if (pyslot_offsets[slot].subslot_offset == -1) { + return parent_slot; + } + return *(void**)((char*)parent_slot + pyslot_offsets[slot].subslot_offset); } PyObject * @@ -3163,18 +3674,62 @@ PyType_GetModule(PyTypeObject *type) } return et->ht_module; -} +} + +void * +PyType_GetModuleState(PyTypeObject *type) +{ + PyObject *m = PyType_GetModule(type); + if (m == NULL) { + return NULL; + } + return _PyModule_GetState(m); +} + + +/* Get the module of the first superclass where the module has the + * given PyModuleDef. + * Implemented by walking the MRO, is relatively slow. + * + * This is internal API for experimentation within stdlib. Discussion: + * https://mail.python.org/archives/list/capi-sig@python.org/thread/T3P2QNLNLBRFHWSKYSTPMVEIL2EEKFJU/ + */ +PyObject * +_PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def) +{ + assert(PyType_Check(type)); + + PyObject *mro = type->tp_mro; + // The type must be ready + assert(mro != NULL); + assert(PyTuple_Check(mro)); + // mro_invoke() ensures that the type MRO cannot be empty, so we don't have + // to check i < PyTuple_GET_SIZE(mro) at the first loop iteration. + assert(PyTuple_GET_SIZE(mro) >= 1); + + Py_ssize_t n = PyTuple_GET_SIZE(mro); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *super = PyTuple_GET_ITEM(mro, i); + if(!_PyType_HasFeature((PyTypeObject *)super, Py_TPFLAGS_HEAPTYPE)) { + // Static types in the MRO need to be skipped + continue; + } -void * -PyType_GetModuleState(PyTypeObject *type) -{ - PyObject *m = PyType_GetModule(type); - if (m == NULL) { - return NULL; + PyHeapTypeObject *ht = (PyHeapTypeObject*)super; + PyObject *module = ht->ht_module; + if (module && _PyModule_GetDef(module) == def) { + return module; + } } - return PyModule_GetState(m); + + PyErr_Format( + PyExc_TypeError, + "_PyType_GetModuleByDef: No superclass of '%s' has the given module", + type->tp_name); + return NULL; } + /* Internal API to look for a name through the MRO, bypassing the method cache. This returns a borrowed reference, and might set an exception. 'error' is set to: -1: error with exception; 1: error without exception; 0: ok */ @@ -3245,20 +3800,17 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) PyObject *res; int error; -#ifdef MCACHE - if (MCACHE_CACHEABLE_NAME(name) && - _PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) { - /* fast path */ - unsigned int h = MCACHE_HASH_METHOD(type, name); - if (method_cache[h].version == type->tp_version_tag && - method_cache[h].name == name) { + 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 - method_cache_hits++; + cache->hits++; #endif - return method_cache[h].value; - } + assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); + return entry->value; } -#endif /* We may end up clearing live exceptions below, so make sure it's ours. */ assert(!PyErr_Occurred()); @@ -3280,22 +3832,23 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) return NULL; } -#ifdef MCACHE - if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(type)) { - unsigned int h = MCACHE_HASH_METHOD(type, name); - method_cache[h].version = type->tp_version_tag; - method_cache[h].value = res; /* borrowed */ - Py_INCREF(name); + if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(cache, 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 *)(name))->hash != -1); #if MCACHE_STATS - if (method_cache[h].name != Py_None && method_cache[h].name != name) - method_cache_collisions++; - else - method_cache_misses++; + if (entry->name != Py_None && entry->name != name) { + cache->collisions++; + } + else { + cache->misses++; + } #endif - Py_SETREF(method_cache[h].name, name); + assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); + Py_SETREF(entry->name, Py_NewRef(name)); } -#endif return res; } @@ -3345,7 +3898,7 @@ type_getattro(PyTypeObject *type, PyObject *name) } /* Initialize this type (we'll assume the metatype is initialized) */ - if (type->tp_dict == NULL) { + if (!_PyType_IsReady(type)) { if (PyType_Ready(type) < 0) return NULL; } @@ -3420,11 +3973,11 @@ static int type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) { int res; - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { PyErr_Format( PyExc_TypeError, - "can't set attributes of built-in/extension type '%s'", - type->tp_name); + "cannot set %R attribute of immutable type '%s'", + name, type->tp_name); return -1; } if (PyUnicode_Check(name)) { @@ -3762,6 +4315,11 @@ type_is_gc(PyTypeObject *type) return type->tp_flags & Py_TPFLAGS_HEAPTYPE; } + +static PyNumberMethods type_as_number = { + .nb_or = _Py_union_type_or, // Add __or__ function +}; + PyTypeObject PyType_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "type", /* tp_name */ @@ -3773,7 +4331,7 @@ PyTypeObject PyType_Type = { 0, /* tp_setattr */ 0, /* tp_as_async */ (reprfunc)type_repr, /* tp_repr */ - 0, /* tp_as_number */ + &type_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ @@ -3805,6 +4363,7 @@ PyTypeObject PyType_Type = { type_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ (inquiry)type_is_gc, /* tp_is_gc */ + .tp_vectorcall = type_vectorcall, }; @@ -4189,10 +4748,10 @@ object_set_class(PyObject *self, PyObject *value, void *closure) In theory the proper fix would be to identify which classes rely on this invariant and somehow disallow __class__ assignment only for them, perhaps via some mechanism like a new Py_TPFLAGS_IMMUTABLE flag (a - "blacklisting" approach). But in practice, since this problem wasn't + "denylisting" approach). But in practice, since this problem wasn't noticed late in the 3.5 RC cycle, we're taking the conservative approach and reinstating the same HEAPTYPE->HEAPTYPE check that we used - to have, plus a "whitelist". For now, the whitelist consists only of + to have, plus an "allowlist". For now, the allowlist consists only of ModuleType subtypes, since those are the cases that motivated the patch in the first place -- see https://bugs.python.org/issue22986 -- and since module objects are mutable we can be sure that they are @@ -4207,10 +4766,10 @@ object_set_class(PyObject *self, PyObject *value, void *closure) */ if (!(PyType_IsSubtype(newto, &PyModule_Type) && PyType_IsSubtype(oldto, &PyModule_Type)) && - (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) || - !(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE))) { + (_PyType_HasFeature(newto, Py_TPFLAGS_IMMUTABLETYPE) || + _PyType_HasFeature(oldto, Py_TPFLAGS_IMMUTABLETYPE))) { PyErr_Format(PyExc_TypeError, - "__class__ assignment only supported for heap types " + "__class__ assignment only supported for mutable types " "or ModuleType subclasses"); return -1; } @@ -4770,8 +5329,11 @@ object___reduce_ex___impl(PyObject *self, int protocol) _Py_IDENTIFIER(__reduce__); if (objreduce == NULL) { - objreduce = _PyDict_GetItemId(PyBaseObject_Type.tp_dict, - &PyId___reduce__); + objreduce = _PyDict_GetItemIdWithError(PyBaseObject_Type.tp_dict, + &PyId___reduce__); + if (objreduce == NULL && PyErr_Occurred()) { + return NULL; + } } if (_PyObject_LookupAttrId(self, &PyId___reduce__, &reduce) < 0) { @@ -4989,96 +5551,98 @@ PyTypeObject PyBaseObject_Type = { }; -/* Add the methods from tp_methods to the __dict__ in a type object */ - static int -add_methods(PyTypeObject *type, PyMethodDef *meth) +type_add_method(PyTypeObject *type, PyMethodDef *meth) { - PyObject *dict = type->tp_dict; - PyObject *name; - - for (; meth->ml_name != NULL; meth++) { - PyObject *descr; - int err; - int isdescr = 1; - if (meth->ml_flags & METH_CLASS) { - if (meth->ml_flags & METH_STATIC) { - PyErr_SetString(PyExc_ValueError, - "method cannot be both class and static"); - return -1; - } - descr = PyDescr_NewClassMethod(type, meth); - } - else if (meth->ml_flags & METH_STATIC) { - PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, NULL); - if (cfunc == NULL) - return -1; - descr = PyStaticMethod_New(cfunc); - isdescr = 0; // PyStaticMethod is not PyDescrObject - Py_DECREF(cfunc); - } - else { - descr = PyDescr_NewMethod(type, meth); - } - if (descr == NULL) + PyObject *descr; + int isdescr = 1; + if (meth->ml_flags & METH_CLASS) { + if (meth->ml_flags & METH_STATIC) { + PyErr_SetString(PyExc_ValueError, + "method cannot be both class and static"); return -1; - - if (isdescr) { - name = PyDescr_NAME(descr); } - else { - name = PyUnicode_FromString(meth->ml_name); - if (name == NULL) { - Py_DECREF(descr); - return -1; - } + descr = PyDescr_NewClassMethod(type, meth); + } + else if (meth->ml_flags & METH_STATIC) { + PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, NULL); + if (cfunc == NULL) { + return -1; } + descr = PyStaticMethod_New(cfunc); + isdescr = 0; // PyStaticMethod is not PyDescrObject + Py_DECREF(cfunc); + } + else { + descr = PyDescr_NewMethod(type, meth); + } + if (descr == NULL) { + return -1; + } - if (!(meth->ml_flags & METH_COEXIST)) { - if (PyDict_GetItemWithError(dict, name)) { - if (!isdescr) { - Py_DECREF(name); - } - Py_DECREF(descr); - continue; - } - else if (PyErr_Occurred()) { - if (!isdescr) { - Py_DECREF(name); - } - return -1; - } - } - err = PyDict_SetItem(dict, name, descr); - if (!isdescr) { - Py_DECREF(name); + PyObject *name; + if (isdescr) { + name = PyDescr_NAME(descr); + } + else { + name = PyUnicode_FromString(meth->ml_name); + if (name == NULL) { + Py_DECREF(descr); + return -1; } - Py_DECREF(descr); - if (err < 0) + } + + int err; + if (!(meth->ml_flags & METH_COEXIST)) { + err = PyDict_SetDefault(type->tp_dict, name, descr) == NULL; + } + else { + err = PyDict_SetItem(type->tp_dict, name, descr) < 0; + } + if (!isdescr) { + Py_DECREF(name); + } + Py_DECREF(descr); + if (err) { + return -1; + } + return 0; +} + + +/* Add the methods from tp_methods to the __dict__ in a type object */ +static int +type_add_methods(PyTypeObject *type) +{ + PyMethodDef *meth = type->tp_methods; + if (meth == NULL) { + return 0; + } + + for (; meth->ml_name != NULL; meth++) { + if (type_add_method(type, meth) < 0) { return -1; + } } return 0; } + static int -add_members(PyTypeObject *type, PyMemberDef *memb) +type_add_members(PyTypeObject *type) { - PyObject *dict = type->tp_dict; + PyMemberDef *memb = type->tp_members; + if (memb == NULL) { + return 0; + } + PyObject *dict = type->tp_dict; for (; memb->name != NULL; memb++) { PyObject *descr = PyDescr_NewMember(type, memb); if (descr == NULL) return -1; - if (PyDict_GetItemWithError(dict, PyDescr_NAME(descr))) { - Py_DECREF(descr); - continue; - } - else if (PyErr_Occurred()) { - Py_DECREF(descr); - return -1; - } - if (PyDict_SetItem(dict, PyDescr_NAME(descr), descr) < 0) { + if (PyDict_SetDefault(dict, PyDescr_NAME(descr), descr) == NULL) { Py_DECREF(descr); return -1; } @@ -5087,25 +5651,23 @@ add_members(PyTypeObject *type, PyMemberDef *memb) return 0; } + static int -add_getset(PyTypeObject *type, PyGetSetDef *gsp) +type_add_getset(PyTypeObject *type) { - PyObject *dict = type->tp_dict; + PyGetSetDef *gsp = type->tp_getset; + if (gsp == NULL) { + return 0; + } + PyObject *dict = type->tp_dict; for (; gsp->name != NULL; gsp++) { PyObject *descr = PyDescr_NewGetSet(type, gsp); - if (descr == NULL) - return -1; - - if (PyDict_GetItemWithError(dict, PyDescr_NAME(descr))) { - Py_DECREF(descr); - continue; - } - else if (PyErr_Occurred()) { - Py_DECREF(descr); + if (descr == NULL) { return -1; } - if (PyDict_SetItem(dict, PyDescr_NAME(descr), descr) < 0) { + + if (PyDict_SetDefault(dict, PyDescr_NAME(descr), descr) == NULL) { Py_DECREF(descr); return -1; } @@ -5114,10 +5676,10 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp) return 0; } + static void inherit_special(PyTypeObject *type, PyTypeObject *base) { - /* Copying tp_traverse and tp_clear is connected to the GC flags */ if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) && (base->tp_flags & Py_TPFLAGS_HAVE_GC) && @@ -5128,53 +5690,48 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) if (type->tp_clear == NULL) type->tp_clear = base->tp_clear; } - { - /* The condition below could use some explanation. - It appears that tp_new is not inherited for static types - whose base class is 'object'; this seems to be a precaution - so that old extension types don't suddenly become - callable (object.__new__ wouldn't insure the invariants - that the extension type's own factory function ensures). - Heap types, of course, are under our control, so they do - inherit tp_new; static extension types that specify some - other built-in type as the default also - inherit object.__new__. */ - if (base != &PyBaseObject_Type || - (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { - if (type->tp_new == NULL) - type->tp_new = base->tp_new; - } - } + if (type->tp_basicsize == 0) type->tp_basicsize = base->tp_basicsize; /* Copy other non-function slots */ -#undef COPYVAL #define COPYVAL(SLOT) \ - if (type->SLOT == 0) type->SLOT = base->SLOT + if (type->SLOT == 0) { type->SLOT = base->SLOT; } COPYVAL(tp_itemsize); COPYVAL(tp_weaklistoffset); COPYVAL(tp_dictoffset); +#undef COPYVAL /* Setup fast subclass flags */ - if (PyType_IsSubtype(base, (PyTypeObject*)PyExc_BaseException)) + if (PyType_IsSubtype(base, (PyTypeObject*)PyExc_BaseException)) { type->tp_flags |= Py_TPFLAGS_BASE_EXC_SUBCLASS; - else if (PyType_IsSubtype(base, &PyType_Type)) + } + else if (PyType_IsSubtype(base, &PyType_Type)) { type->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS; - else if (PyType_IsSubtype(base, &PyLong_Type)) + } + else if (PyType_IsSubtype(base, &PyLong_Type)) { type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS; - else if (PyType_IsSubtype(base, &PyBytes_Type)) + } + else if (PyType_IsSubtype(base, &PyBytes_Type)) { type->tp_flags |= Py_TPFLAGS_BYTES_SUBCLASS; - else if (PyType_IsSubtype(base, &PyUnicode_Type)) + } + else if (PyType_IsSubtype(base, &PyUnicode_Type)) { type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS; - else if (PyType_IsSubtype(base, &PyTuple_Type)) + } + else if (PyType_IsSubtype(base, &PyTuple_Type)) { type->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS; - else if (PyType_IsSubtype(base, &PyList_Type)) + } + else if (PyType_IsSubtype(base, &PyList_Type)) { type->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS; - else if (PyType_IsSubtype(base, &PyDict_Type)) + } + else if (PyType_IsSubtype(base, &PyDict_Type)) { type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; + } + if (PyType_HasFeature(base, _Py_TPFLAGS_MATCH_SELF)) { + type->tp_flags |= _Py_TPFLAGS_MATCH_SELF; + } } static int @@ -5184,14 +5741,14 @@ overrides_hash(PyTypeObject *type) _Py_IDENTIFIER(__eq__); assert(dict != NULL); - if (_PyDict_GetItemId(dict, &PyId___eq__) != NULL) - return 1; - if (_PyDict_GetItemId(dict, &PyId___hash__) != NULL) - return 1; - return 0; + int r = _PyDict_ContainsId(dict, &PyId___eq__); + if (r == 0) { + r = _PyDict_ContainsId(dict, &PyId___hash__); + } + return r; } -static void +static int inherit_slots(PyTypeObject *type, PyTypeObject *base) { PyTypeObject *basebase; @@ -5334,11 +5891,16 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) /* Copy comparison-related slots only when not overriding them anywhere */ if (type->tp_richcompare == NULL && - type->tp_hash == NULL && - !overrides_hash(type)) + type->tp_hash == NULL) { - type->tp_richcompare = base->tp_richcompare; - type->tp_hash = base->tp_hash; + int r = overrides_hash(type); + if (r < 0) { + return -1; + } + if (!r) { + type->tp_richcompare = base->tp_richcompare; + type->tp_hash = base->tp_hash; + } } } { @@ -5381,24 +5943,17 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) * obvious to be done -- the type is on its own. */ } + return 0; } static int add_operators(PyTypeObject *); +static int add_tp_new_wrapper(PyTypeObject *type); -int -PyType_Ready(PyTypeObject *type) -{ - PyObject *dict, *bases; - PyTypeObject *base; - Py_ssize_t i, n; - - if (type->tp_flags & Py_TPFLAGS_READY) { - assert(_PyType_CheckConsistency(type)); - return 0; - } - _PyObject_ASSERT((PyObject *)type, - (type->tp_flags & Py_TPFLAGS_READYING) == 0); +#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING) +static int +type_ready_checks(PyTypeObject *type) +{ /* Consistency checks for PEP 590: * - Py_TPFLAGS_METHOD_DESCRIPTOR requires tp_descr_get * - Py_TPFLAGS_HAVE_VECTORCALL requires tp_call and @@ -5413,124 +5968,241 @@ PyType_Ready(PyTypeObject *type) _PyObject_ASSERT((PyObject *)type, type->tp_call != NULL); } - type->tp_flags |= Py_TPFLAGS_READYING; - -#ifdef Py_TRACE_REFS - /* PyType_Ready is the closest thing we have to a choke point - * for type objects, so is the best place I can think of to try - * to get type objects into the doubly-linked list of all objects. - * Still, not all type objects go through PyType_Ready. - */ - _Py_AddToAllObjects((PyObject *)type, 0); -#endif + /* Consistency checks for pattern matching + * Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING are mutually exclusive */ + _PyObject_ASSERT((PyObject *)type, (type->tp_flags & COLLECTION_FLAGS) != COLLECTION_FLAGS); if (type->tp_name == NULL) { PyErr_Format(PyExc_SystemError, "Type does not define the tp_name field."); - goto error; + return -1; + } + return 0; +} + + +static int +type_ready_set_bases(PyTypeObject *type) +{ + /* Initialize tp_base (defaults to BaseObject unless that's us) */ + PyTypeObject *base = type->tp_base; + if (base == NULL && type != &PyBaseObject_Type) { + base = &PyBaseObject_Type; + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + type->tp_base = (PyTypeObject*)Py_NewRef((PyObject*)base); + } + else { + type->tp_base = base; + } + } + assert(type->tp_base != NULL || type == &PyBaseObject_Type); + + /* Now the only way base can still be NULL is if type is + * &PyBaseObject_Type. */ + + /* Initialize the base class */ + if (base != NULL && !_PyType_IsReady(base)) { + if (PyType_Ready(base) < 0) { + return -1; + } + } + + /* 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. */ + /* The test for base != NULL is really unnecessary, since base is only + 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. */ + if (Py_IS_TYPE(type, NULL) && base != NULL) { + Py_SET_TYPE(type, Py_TYPE(base)); + } + + /* Initialize tp_bases */ + PyObject *bases = type->tp_bases; + if (bases == NULL) { + PyTypeObject *base = type->tp_base; + if (base == NULL) { + bases = PyTuple_New(0); + } + else { + bases = PyTuple_Pack(1, base); + } + if (bases == NULL) { + return -1; + } + type->tp_bases = bases; + } + return 0; +} + + +static int +type_ready_set_dict(PyTypeObject *type) +{ + if (type->tp_dict != NULL) { + return 0; + } + + PyObject *dict = PyDict_New(); + if (dict == NULL) { + return -1; + } + type->tp_dict = dict; + return 0; +} + + +/* If the type dictionary doesn't contain a __doc__, set it from + the tp_doc slot. */ +static int +type_dict_set_doc(PyTypeObject *type) +{ + int r = _PyDict_ContainsId(type->tp_dict, &PyId___doc__); + if (r < 0) { + return -1; + } + if (r > 0) { + return 0; + } + + if (type->tp_doc != NULL) { + const char *doc_str; + doc_str = _PyType_DocWithoutSignature(type->tp_name, type->tp_doc); + PyObject *doc = PyUnicode_FromString(doc_str); + if (doc == NULL) { + return -1; + } + + if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) { + Py_DECREF(doc); + return -1; + } + Py_DECREF(doc); + } + else { + if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, Py_None) < 0) { + return -1; + } } + return 0; +} - /* Initialize tp_base (defaults to BaseObject unless that's us) */ - base = type->tp_base; - if (base == NULL && type != &PyBaseObject_Type) { - base = type->tp_base = &PyBaseObject_Type; - Py_INCREF(base); + +static int +type_ready_fill_dict(PyTypeObject *type) +{ + /* Add type-specific descriptors to tp_dict */ + if (add_operators(type) < 0) { + return -1; + } + if (type_add_methods(type) < 0) { + return -1; + } + if (type_add_members(type) < 0) { + return -1; } + if (type_add_getset(type) < 0) { + return -1; + } + if (type_dict_set_doc(type) < 0) { + return -1; + } + return 0; +} - /* Now the only way base can still be NULL is if type is - * &PyBaseObject_Type. - */ - /* Initialize the base class */ - if (base != NULL && base->tp_dict == NULL) { - if (PyType_Ready(base) < 0) - goto error; +static int +type_ready_mro(PyTypeObject *type) +{ + /* Calculate method resolution order */ + if (mro_internal(type, NULL) < 0) { + return -1; } + assert(type->tp_mro != NULL); + assert(PyTuple_Check(type->tp_mro)); - /* 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. */ - /* The test for base != NULL is really unnecessary, since base is only - 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. */ - if (Py_IS_TYPE(type, NULL) && base != NULL) { - Py_SET_TYPE(type, Py_TYPE(base)); + /* All bases of statically allocated type should be statically allocated */ + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyObject *mro = type->tp_mro; + Py_ssize_t n = PyTuple_GET_SIZE(mro); + for (Py_ssize_t i = 0; i < n; i++) { + PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); + if (PyType_Check(base) && (base->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_TypeError, + "type '%.100s' is not dynamically allocated but " + "its base type '%.100s' is dynamically allocated", + type->tp_name, base->tp_name); + return -1; + } + } } + return 0; +} - /* Initialize tp_bases */ - bases = type->tp_bases; - if (bases == NULL) { - if (base == NULL) - bases = PyTuple_New(0); - else - bases = PyTuple_Pack(1, base); - if (bases == NULL) - goto error; - type->tp_bases = bases; - } - /* Initialize tp_dict */ - dict = type->tp_dict; - if (dict == NULL) { - dict = PyDict_New(); - if (dict == NULL) - goto error; - type->tp_dict = dict; +// For static types, inherit tp_as_xxx structures from the base class +// if it's NULL. +// +// For heap types, tp_as_xxx structures are not NULL: they are set to the +// PyHeapTypeObject.as_xxx fields by type_new_alloc(). +static void +type_ready_inherit_as_structs(PyTypeObject *type, PyTypeObject *base) +{ + if (type->tp_as_async == NULL) { + type->tp_as_async = base->tp_as_async; } - - /* Add type-specific descriptors to tp_dict */ - if (add_operators(type) < 0) - goto error; - if (type->tp_methods != NULL) { - if (add_methods(type, type->tp_methods) < 0) - goto error; + if (type->tp_as_number == NULL) { + type->tp_as_number = base->tp_as_number; } - if (type->tp_members != NULL) { - if (add_members(type, type->tp_members) < 0) - goto error; + if (type->tp_as_sequence == NULL) { + type->tp_as_sequence = base->tp_as_sequence; } - if (type->tp_getset != NULL) { - if (add_getset(type, type->tp_getset) < 0) - goto error; + if (type->tp_as_mapping == NULL) { + type->tp_as_mapping = base->tp_as_mapping; } + if (type->tp_as_buffer == NULL) { + type->tp_as_buffer = base->tp_as_buffer; + } +} - /* Calculate method resolution order */ - if (mro_internal(type, NULL) < 0) - goto error; +static void +inherit_patma_flags(PyTypeObject *type, PyTypeObject *base) { + if ((type->tp_flags & COLLECTION_FLAGS) == 0) { + type->tp_flags |= base->tp_flags & COLLECTION_FLAGS; + } +} +static int +type_ready_inherit(PyTypeObject *type) +{ /* Inherit special flags from dominant base */ - if (type->tp_base != NULL) - inherit_special(type, type->tp_base); - - /* Initialize tp_dict properly */ - bases = type->tp_mro; - assert(bases != NULL); - assert(PyTuple_Check(bases)); - n = PyTuple_GET_SIZE(bases); - for (i = 1; i < n; i++) { - PyObject *b = PyTuple_GET_ITEM(bases, i); - if (PyType_Check(b)) - inherit_slots(type, (PyTypeObject *)b); + PyTypeObject *base = type->tp_base; + if (base != NULL) { + inherit_special(type, base); } - /* All bases of statically allocated type should be statically allocated */ - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) - for (i = 0; i < n; i++) { - PyObject *b = PyTuple_GET_ITEM(bases, i); - if (PyType_Check(b) && - (((PyTypeObject *)b)->tp_flags & Py_TPFLAGS_HEAPTYPE)) { - PyErr_Format(PyExc_TypeError, - "type '%.100s' is not dynamically allocated but " - "its base type '%.100s' is dynamically allocated", - type->tp_name, ((PyTypeObject *)b)->tp_name); - goto error; + // Inherit slots + PyObject *mro = type->tp_mro; + Py_ssize_t n = PyTuple_GET_SIZE(type->tp_mro); + for (Py_ssize_t i = 1; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(mro, i); + if (PyType_Check(b)) { + if (inherit_slots(type, (PyTypeObject *)b) < 0) { + return -1; } + inherit_patma_flags(type, (PyTypeObject *)b); } + } + + if (base != NULL) { + type_ready_inherit_as_structs(type, base); + } /* Sanity check for tp_free. */ if (_PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) && - (type->tp_free == NULL || type->tp_free == PyObject_Del)) { + (type->tp_free == NULL || type->tp_free == PyObject_Del)) + { /* This base class needs to call tp_free, but doesn't have * one, or its tp_free is for non-gc'ed objects. */ @@ -5538,87 +6210,175 @@ PyType_Ready(PyTypeObject *type) "gc and is a base type but has inappropriate " "tp_free slot", type->tp_name); - goto error; + return -1; } - /* if the type dictionary doesn't contain a __doc__, set it from - the tp_doc slot. - */ - if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___doc__) == NULL) { - if (PyErr_Occurred()) { - goto error; + return 0; +} + + +/* Hack for tp_hash and __hash__. + If after all that, tp_hash is still NULL, and __hash__ is not in + tp_dict, set tp_hash to PyObject_HashNotImplemented and + tp_dict['__hash__'] equal to None. + This signals that __hash__ is not inherited. */ +static int +type_ready_set_hash(PyTypeObject *type) +{ + if (type->tp_hash != NULL) { + return 0; + } + + int r = _PyDict_ContainsId(type->tp_dict, &PyId___hash__); + if (r < 0) { + return -1; + } + if (r > 0) { + return 0; + } + + if (_PyDict_SetItemId(type->tp_dict, &PyId___hash__, Py_None) < 0) { + return -1; + } + type->tp_hash = PyObject_HashNotImplemented; + return 0; +} + + +/* Link into each base class's list of subclasses */ +static int +type_ready_add_subclasses(PyTypeObject *type) +{ + PyObject *bases = type->tp_bases; + Py_ssize_t nbase = PyTuple_GET_SIZE(bases); + for (Py_ssize_t i = 0; i < nbase; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(b) && add_subclass((PyTypeObject *)b, type) < 0) { + return -1; } - if (type->tp_doc != NULL) { - const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, - type->tp_doc); - PyObject *doc = PyUnicode_FromString(old_doc); - if (doc == NULL) - goto error; - if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) { - Py_DECREF(doc); - goto error; + } + return 0; +} + + +// 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) +{ + PyTypeObject *base = type->tp_base; + /* The condition below could use some explanation. + + It appears that tp_new is not inherited for static types whose base + class is 'object'; this seems to be a precaution so that old extension + types don't suddenly become callable (object.__new__ wouldn't insure the + invariants that the extension type's own factory function ensures). + + Heap types, of course, are under our control, so they do inherit tp_new; + static extension types that specify some other built-in type as the + default also inherit object.__new__. */ + if (type->tp_new == NULL + && base == &PyBaseObject_Type + && !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + { + type->tp_flags |= Py_TPFLAGS_DISALLOW_INSTANTIATION; + } + + 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; } - Py_DECREF(doc); - } else { - if (_PyDict_SetItemId(type->tp_dict, - &PyId___doc__, Py_None) < 0) - goto error; } + else { + // tp_new is NULL: inherit tp_new from base + type->tp_new = base->tp_new; + } + } + else { + // Py_TPFLAGS_DISALLOW_INSTANTIATION sets tp_new to NULL + type->tp_new = NULL; + } + return 0; +} + + +static int +type_ready(PyTypeObject *type) +{ + if (type_ready_checks(type) < 0) { + return -1; } - /* Hack for tp_hash and __hash__. - If after all that, tp_hash is still NULL, and __hash__ is not in - tp_dict, set tp_hash to PyObject_HashNotImplemented and - tp_dict['__hash__'] equal to None. - This signals that __hash__ is not inherited. +#ifdef Py_TRACE_REFS + /* PyType_Ready is the closest thing we have to a choke point + * for type objects, so is the best place I can think of to try + * to get type objects into the doubly-linked list of all objects. + * Still, not all type objects go through PyType_Ready. */ - if (type->tp_hash == NULL) { - if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___hash__) == NULL) { - if (PyErr_Occurred() || - _PyDict_SetItemId(type->tp_dict, &PyId___hash__, Py_None) < 0) - { - goto error; - } - type->tp_hash = PyObject_HashNotImplemented; - } + _Py_AddToAllObjects((PyObject *)type, 0); +#endif + + /* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */ + if (type_ready_set_dict(type) < 0) { + return -1; + } + if (type_ready_set_bases(type) < 0) { + return -1; + } + if (type_ready_mro(type) < 0) { + return -1; + } + if (type_ready_set_new(type) < 0) { + return -1; + } + if (type_ready_fill_dict(type) < 0) { + return -1; + } + if (type_ready_inherit(type) < 0) { + return -1; } + if (type_ready_set_hash(type) < 0) { + return -1; + } + if (type_ready_add_subclasses(type) < 0) { + return -1; + } + return 0; +} - /* Some more special stuff */ - base = type->tp_base; - if (base != NULL) { - if (type->tp_as_async == NULL) - type->tp_as_async = base->tp_as_async; - if (type->tp_as_number == NULL) - type->tp_as_number = base->tp_as_number; - if (type->tp_as_sequence == NULL) - type->tp_as_sequence = base->tp_as_sequence; - if (type->tp_as_mapping == NULL) - type->tp_as_mapping = base->tp_as_mapping; - if (type->tp_as_buffer == NULL) - type->tp_as_buffer = base->tp_as_buffer; - } - - /* Link into each base class's list of subclasses */ - bases = type->tp_bases; - n = PyTuple_GET_SIZE(bases); - for (i = 0; i < n; i++) { - PyObject *b = PyTuple_GET_ITEM(bases, i); - if (PyType_Check(b) && - add_subclass((PyTypeObject *)b, type) < 0) - goto error; + +int +PyType_Ready(PyTypeObject *type) +{ + if (type->tp_flags & Py_TPFLAGS_READY) { + assert(_PyType_CheckConsistency(type)); + return 0; + } + _PyObject_ASSERT((PyObject *)type, + (type->tp_flags & Py_TPFLAGS_READYING) == 0); + + type->tp_flags |= Py_TPFLAGS_READYING; + + /* 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; } /* All done -- set the ready flag */ - type->tp_flags = - (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; + type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; assert(_PyType_CheckConsistency(type)); return 0; - - error: - type->tp_flags &= ~Py_TPFLAGS_READYING; - return -1; } + static int add_subclass(PyTypeObject *base, PyTypeObject *type) { @@ -6202,8 +6962,8 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) "__new__() called with non-type 'self'"); return NULL; } - type = (PyTypeObject *)self; + if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 1) { PyErr_Format(PyExc_TypeError, "%s.__new__(): not enough arguments", @@ -6265,21 +7025,21 @@ static struct PyMethodDef tp_new_methoddef[] = { static int add_tp_new_wrapper(PyTypeObject *type) { - PyObject *func; - - if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___new__) != NULL) + int r = _PyDict_ContainsId(type->tp_dict, &PyId___new__); + if (r > 0) { return 0; - if (PyErr_Occurred()) - return -1; - func = PyCFunction_NewEx(tp_new_methoddef, (PyObject *)type, NULL); - if (func == NULL) + } + if (r < 0) { return -1; - if (_PyDict_SetItemId(type->tp_dict, &PyId___new__, func)) { - Py_DECREF(func); + } + + PyObject *func = PyCFunction_NewEx(tp_new_methoddef, (PyObject *)type, NULL); + if (func == NULL) { return -1; } + r = _PyDict_SetItemId(type->tp_dict, &PyId___new__, func); Py_DECREF(func); - return 0; + return r; } /* Slot wrappers that call the corresponding __foo__ slot. See comments @@ -6394,7 +7154,7 @@ slot_sq_length(PyObject *self) if (res == NULL) return -1; - Py_SETREF(res, PyNumber_Index(res)); + Py_SETREF(res, _PyNumber_Index(res)); if (res == NULL) return -1; @@ -7636,8 +8396,17 @@ update_slot(PyTypeObject *type, PyObject *name) assert(slotdefs_initialized); pp = ptrs; for (p = slotdefs; p->name; p++) { - if (p->name_strobj == name) + assert(PyUnicode_CheckExact(p->name_strobj)); + assert(PyUnicode_CheckExact(name)); +#ifdef INTERN_NAME_STRINGS + if (p->name_strobj == name) { + *pp++ = p; + } +#else + if (p->name_strobj == name || _PyUnicode_EQ(p->name_strobj, name)) { *pp++ = p; + } +#endif } *pp = NULL; for (pp = ptrs; *pp; pp++) { @@ -7659,11 +8428,11 @@ update_slot(PyTypeObject *type, PyObject *name) static void fixup_slot_dispatchers(PyTypeObject *type) { - slotdef *p; - + assert(!PyErr_Occurred()); assert(slotdefs_initialized); - for (p = slotdefs; p->name; ) + for (slotdef *p = slotdefs; p->name; ) { p = update_one_slot(type, p); + } } static void @@ -7681,63 +8450,67 @@ update_all_slots(PyTypeObject* type) } } -/* Call __set_name__ on all descriptors in a newly generated type */ + +/* Call __set_name__ on all attributes (including descriptors) + in a newly generated type */ static int -set_names(PyTypeObject *type) +type_new_set_names(PyTypeObject *type) { - PyObject *names_to_set, *key, *value, *set_name, *tmp; - Py_ssize_t i = 0; - - names_to_set = PyDict_Copy(type->tp_dict); - if (names_to_set == NULL) + PyObject *names_to_set = PyDict_Copy(type->tp_dict); + if (names_to_set == NULL) { return -1; + } + Py_ssize_t i = 0; + PyObject *key, *value; while (PyDict_Next(names_to_set, &i, &key, &value)) { - set_name = _PyObject_LookupSpecial(value, &PyId___set_name__); - if (set_name != NULL) { - tmp = PyObject_CallFunctionObjArgs(set_name, type, key, NULL); - Py_DECREF(set_name); - if (tmp == NULL) { - _PyErr_FormatFromCause(PyExc_RuntimeError, - "Error calling __set_name__ on '%.100s' instance %R " - "in '%.100s'", - Py_TYPE(value)->tp_name, key, type->tp_name); - Py_DECREF(names_to_set); - return -1; + PyObject *set_name = _PyObject_LookupSpecial(value, &PyId___set_name__); + if (set_name == NULL) { + if (PyErr_Occurred()) { + goto error; } - else - Py_DECREF(tmp); + continue; } - else if (PyErr_Occurred()) { - Py_DECREF(names_to_set); - return -1; + + PyObject *res = PyObject_CallFunctionObjArgs(set_name, type, key, NULL); + Py_DECREF(set_name); + + if (res == NULL) { + _PyErr_FormatFromCause(PyExc_RuntimeError, + "Error calling __set_name__ on '%.100s' instance %R " + "in '%.100s'", + Py_TYPE(value)->tp_name, key, type->tp_name); + goto error; } + Py_DECREF(res); } Py_DECREF(names_to_set); return 0; + +error: + Py_DECREF(names_to_set); + return -1; } + /* Call __init_subclass__ on the parent of a newly generated type */ static int -init_subclass(PyTypeObject *type, PyObject *kwds) +type_new_init_subclass(PyTypeObject *type, PyObject *kwds) { - PyObject *super, *func, *result; PyObject *args[2] = {(PyObject *)type, (PyObject *)type}; - - super = _PyObject_FastCall((PyObject *)&PySuper_Type, args, 2); + PyObject *super = _PyObject_FastCall((PyObject *)&PySuper_Type, args, 2); if (super == NULL) { return -1; } - func = _PyObject_GetAttrId(super, &PyId___init_subclass__); + PyObject *func = _PyObject_GetAttrId(super, &PyId___init_subclass__); Py_DECREF(super); if (func == NULL) { return -1; } - - result = PyObject_VectorcallDict(func, NULL, 0, kwds); + PyObject *result = PyObject_VectorcallDict(func, NULL, 0, kwds); Py_DECREF(func); if (result == NULL) { return -1; @@ -7747,6 +8520,7 @@ init_subclass(PyTypeObject *type, PyObject *kwds) return 0; } + /* recurse_down_subclasses() and update_subclasses() are mutually recursive functions to call a callback for all subclasses, but refraining from recursing into subclasses that define 'name'. */ @@ -7783,10 +8557,11 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *name, /* Avoid recursing down into unaffected classes */ dict = subclass->tp_dict; if (dict != NULL && PyDict_Check(dict)) { - if (PyDict_GetItemWithError(dict, name) != NULL) { + int r = PyDict_Contains(dict, name); + if (r > 0) { continue; } - if (PyErr_Occurred()) { + if (r < 0) { return -1; } } @@ -7841,9 +8616,10 @@ add_operators(PyTypeObject *type) ptr = slotptr(type, p->offset); if (!ptr || !*ptr) continue; - if (PyDict_GetItemWithError(dict, p->name_strobj)) + int r = PyDict_Contains(dict, p->name_strobj); + if (r > 0) continue; - if (PyErr_Occurred()) { + if (r < 0) { return -1; } if (*ptr == (void *)PyObject_HashNotImplemented) { @@ -7864,10 +8640,6 @@ add_operators(PyTypeObject *type) Py_DECREF(descr); } } - if (type->tp_new != NULL) { - if (add_tp_new_wrapper(type) < 0) - return -1; - } return 0; } diff --git a/contrib/tools/python3/src/Objects/typeslots.inc b/contrib/tools/python3/src/Objects/typeslots.inc index ffc9bb2e1c7..896daa7d806 100644 --- a/contrib/tools/python3/src/Objects/typeslots.inc +++ b/contrib/tools/python3/src/Objects/typeslots.inc @@ -1,81 +1,82 @@ /* Generated by typeslots.py */ -offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer), -offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer), -offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), -offsetof(PyHeapTypeObject, as_mapping.mp_length), -offsetof(PyHeapTypeObject, as_mapping.mp_subscript), -offsetof(PyHeapTypeObject, as_number.nb_absolute), -offsetof(PyHeapTypeObject, as_number.nb_add), -offsetof(PyHeapTypeObject, as_number.nb_and), -offsetof(PyHeapTypeObject, as_number.nb_bool), -offsetof(PyHeapTypeObject, as_number.nb_divmod), -offsetof(PyHeapTypeObject, as_number.nb_float), -offsetof(PyHeapTypeObject, as_number.nb_floor_divide), -offsetof(PyHeapTypeObject, as_number.nb_index), -offsetof(PyHeapTypeObject, as_number.nb_inplace_add), -offsetof(PyHeapTypeObject, as_number.nb_inplace_and), -offsetof(PyHeapTypeObject, as_number.nb_inplace_floor_divide), -offsetof(PyHeapTypeObject, as_number.nb_inplace_lshift), -offsetof(PyHeapTypeObject, as_number.nb_inplace_multiply), -offsetof(PyHeapTypeObject, as_number.nb_inplace_or), -offsetof(PyHeapTypeObject, as_number.nb_inplace_power), -offsetof(PyHeapTypeObject, as_number.nb_inplace_remainder), -offsetof(PyHeapTypeObject, as_number.nb_inplace_rshift), -offsetof(PyHeapTypeObject, as_number.nb_inplace_subtract), -offsetof(PyHeapTypeObject, as_number.nb_inplace_true_divide), -offsetof(PyHeapTypeObject, as_number.nb_inplace_xor), -offsetof(PyHeapTypeObject, as_number.nb_int), -offsetof(PyHeapTypeObject, as_number.nb_invert), -offsetof(PyHeapTypeObject, as_number.nb_lshift), -offsetof(PyHeapTypeObject, as_number.nb_multiply), -offsetof(PyHeapTypeObject, as_number.nb_negative), -offsetof(PyHeapTypeObject, as_number.nb_or), -offsetof(PyHeapTypeObject, as_number.nb_positive), -offsetof(PyHeapTypeObject, as_number.nb_power), -offsetof(PyHeapTypeObject, as_number.nb_remainder), -offsetof(PyHeapTypeObject, as_number.nb_rshift), -offsetof(PyHeapTypeObject, as_number.nb_subtract), -offsetof(PyHeapTypeObject, as_number.nb_true_divide), -offsetof(PyHeapTypeObject, as_number.nb_xor), -offsetof(PyHeapTypeObject, as_sequence.sq_ass_item), -offsetof(PyHeapTypeObject, as_sequence.sq_concat), -offsetof(PyHeapTypeObject, as_sequence.sq_contains), -offsetof(PyHeapTypeObject, as_sequence.sq_inplace_concat), -offsetof(PyHeapTypeObject, as_sequence.sq_inplace_repeat), -offsetof(PyHeapTypeObject, as_sequence.sq_item), -offsetof(PyHeapTypeObject, as_sequence.sq_length), -offsetof(PyHeapTypeObject, as_sequence.sq_repeat), -offsetof(PyHeapTypeObject, ht_type.tp_alloc), -offsetof(PyHeapTypeObject, ht_type.tp_base), -offsetof(PyHeapTypeObject, ht_type.tp_bases), -offsetof(PyHeapTypeObject, ht_type.tp_call), -offsetof(PyHeapTypeObject, ht_type.tp_clear), -offsetof(PyHeapTypeObject, ht_type.tp_dealloc), -offsetof(PyHeapTypeObject, ht_type.tp_del), -offsetof(PyHeapTypeObject, ht_type.tp_descr_get), -offsetof(PyHeapTypeObject, ht_type.tp_descr_set), -offsetof(PyHeapTypeObject, ht_type.tp_doc), -offsetof(PyHeapTypeObject, ht_type.tp_getattr), -offsetof(PyHeapTypeObject, ht_type.tp_getattro), -offsetof(PyHeapTypeObject, ht_type.tp_hash), -offsetof(PyHeapTypeObject, ht_type.tp_init), -offsetof(PyHeapTypeObject, ht_type.tp_is_gc), -offsetof(PyHeapTypeObject, ht_type.tp_iter), -offsetof(PyHeapTypeObject, ht_type.tp_iternext), -offsetof(PyHeapTypeObject, ht_type.tp_methods), -offsetof(PyHeapTypeObject, ht_type.tp_new), -offsetof(PyHeapTypeObject, ht_type.tp_repr), -offsetof(PyHeapTypeObject, ht_type.tp_richcompare), -offsetof(PyHeapTypeObject, ht_type.tp_setattr), -offsetof(PyHeapTypeObject, ht_type.tp_setattro), -offsetof(PyHeapTypeObject, ht_type.tp_str), -offsetof(PyHeapTypeObject, ht_type.tp_traverse), -offsetof(PyHeapTypeObject, ht_type.tp_members), -offsetof(PyHeapTypeObject, ht_type.tp_getset), -offsetof(PyHeapTypeObject, ht_type.tp_free), -offsetof(PyHeapTypeObject, as_number.nb_matrix_multiply), -offsetof(PyHeapTypeObject, as_number.nb_inplace_matrix_multiply), -offsetof(PyHeapTypeObject, as_async.am_await), -offsetof(PyHeapTypeObject, as_async.am_aiter), -offsetof(PyHeapTypeObject, as_async.am_anext), -offsetof(PyHeapTypeObject, ht_type.tp_finalize), +{offsetof(PyBufferProcs, bf_getbuffer), offsetof(PyTypeObject, tp_as_buffer)}, +{offsetof(PyBufferProcs, bf_releasebuffer), offsetof(PyTypeObject, tp_as_buffer)}, +{offsetof(PyMappingMethods, mp_ass_subscript), offsetof(PyTypeObject, tp_as_mapping)}, +{offsetof(PyMappingMethods, mp_length), offsetof(PyTypeObject, tp_as_mapping)}, +{offsetof(PyMappingMethods, mp_subscript), offsetof(PyTypeObject, tp_as_mapping)}, +{offsetof(PyNumberMethods, nb_absolute), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_add), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_and), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_bool), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_divmod), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_float), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_floor_divide), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_index), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_add), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_and), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_floor_divide), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_lshift), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_multiply), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_or), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_power), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_remainder), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_rshift), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_subtract), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_true_divide), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_xor), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_int), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_invert), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_lshift), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_multiply), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_negative), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_or), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_positive), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_power), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_remainder), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_rshift), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_subtract), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_true_divide), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_xor), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PySequenceMethods, sq_ass_item), offsetof(PyTypeObject, tp_as_sequence)}, +{offsetof(PySequenceMethods, sq_concat), offsetof(PyTypeObject, tp_as_sequence)}, +{offsetof(PySequenceMethods, sq_contains), offsetof(PyTypeObject, tp_as_sequence)}, +{offsetof(PySequenceMethods, sq_inplace_concat), offsetof(PyTypeObject, tp_as_sequence)}, +{offsetof(PySequenceMethods, sq_inplace_repeat), offsetof(PyTypeObject, tp_as_sequence)}, +{offsetof(PySequenceMethods, sq_item), offsetof(PyTypeObject, tp_as_sequence)}, +{offsetof(PySequenceMethods, sq_length), offsetof(PyTypeObject, tp_as_sequence)}, +{offsetof(PySequenceMethods, sq_repeat), offsetof(PyTypeObject, tp_as_sequence)}, +{-1, offsetof(PyTypeObject, tp_alloc)}, +{-1, offsetof(PyTypeObject, tp_base)}, +{-1, offsetof(PyTypeObject, tp_bases)}, +{-1, offsetof(PyTypeObject, tp_call)}, +{-1, offsetof(PyTypeObject, tp_clear)}, +{-1, offsetof(PyTypeObject, tp_dealloc)}, +{-1, offsetof(PyTypeObject, tp_del)}, +{-1, offsetof(PyTypeObject, tp_descr_get)}, +{-1, offsetof(PyTypeObject, tp_descr_set)}, +{-1, offsetof(PyTypeObject, tp_doc)}, +{-1, offsetof(PyTypeObject, tp_getattr)}, +{-1, offsetof(PyTypeObject, tp_getattro)}, +{-1, offsetof(PyTypeObject, tp_hash)}, +{-1, offsetof(PyTypeObject, tp_init)}, +{-1, offsetof(PyTypeObject, tp_is_gc)}, +{-1, offsetof(PyTypeObject, tp_iter)}, +{-1, offsetof(PyTypeObject, tp_iternext)}, +{-1, offsetof(PyTypeObject, tp_methods)}, +{-1, offsetof(PyTypeObject, tp_new)}, +{-1, offsetof(PyTypeObject, tp_repr)}, +{-1, offsetof(PyTypeObject, tp_richcompare)}, +{-1, offsetof(PyTypeObject, tp_setattr)}, +{-1, offsetof(PyTypeObject, tp_setattro)}, +{-1, offsetof(PyTypeObject, tp_str)}, +{-1, offsetof(PyTypeObject, tp_traverse)}, +{-1, offsetof(PyTypeObject, tp_members)}, +{-1, offsetof(PyTypeObject, tp_getset)}, +{-1, offsetof(PyTypeObject, tp_free)}, +{offsetof(PyNumberMethods, nb_matrix_multiply), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyNumberMethods, nb_inplace_matrix_multiply), offsetof(PyTypeObject, tp_as_number)}, +{offsetof(PyAsyncMethods, am_await), offsetof(PyTypeObject, tp_as_async)}, +{offsetof(PyAsyncMethods, am_aiter), offsetof(PyTypeObject, tp_as_async)}, +{offsetof(PyAsyncMethods, am_anext), offsetof(PyTypeObject, tp_as_async)}, +{-1, offsetof(PyTypeObject, tp_finalize)}, +{offsetof(PyAsyncMethods, am_send), offsetof(PyTypeObject, tp_as_async)}, diff --git a/contrib/tools/python3/src/Objects/unicodeobject.c b/contrib/tools/python3/src/Objects/unicodeobject.c index 7767d140e6c..077cf8d7f45 100644 --- a/contrib/tools/python3/src/Objects/unicodeobject.c +++ b/contrib/tools/python3/src/Objects/unicodeobject.c @@ -40,17 +40,18 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_bytes_methods.h" -#include "pycore_fileutils.h" -#include "pycore_initconfig.h" -#include "pycore_interp.h" // PyInterpreterState.fs_codec -#include "pycore_object.h" -#include "pycore_pathconfig.h" -#include "pycore_pylifecycle.h" -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "ucnhash.h" -#include "stringlib/eq.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_atomic_funcs.h" // _Py_atomic_size_get() +#include "pycore_bytes_methods.h" // _Py_bytes_lower() +#include "pycore_format.h" // F_LJUST +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_interp.h" // PyInterpreterState.fs_codec +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_pathconfig.h" // _Py_DumpPathConfig() +#include "pycore_pylifecycle.h" // _Py_SetFileSystemEncoding() +#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI +#include "stringlib/eq.h" // unicode_eq() #ifdef MS_WINDOWS #include @@ -60,8 +61,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "pycore_fileutils.h" // _Py_LocaleUsesNonUnicodeWchar() #endif -/* Uncomment to display statistics on interned strings at exit when - using Valgrind or Insecure++. */ +/* Uncomment to display statistics on interned strings at exit + in _PyUnicode_ClearInterned(). */ /* #define INTERNED_STATS 1 */ @@ -210,7 +211,10 @@ extern "C" { # define OVERALLOCATE_FACTOR 4 #endif -#define INTERNED_STRINGS +/* bpo-40521: Interned strings are shared by all interpreters. */ +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS +# define INTERNED_STRINGS +#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. @@ -224,26 +228,36 @@ extern "C" { static PyObject *interned = NULL; #endif -/* The empty Unicode object is shared to improve performance. */ -static PyObject *unicode_empty = NULL; +static struct _Py_unicode_state* +get_unicode_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->unicode; +} -#define _Py_INCREF_UNICODE_EMPTY() \ - do { \ - if (unicode_empty != NULL) \ - Py_INCREF(unicode_empty); \ - else { \ - unicode_empty = PyUnicode_New(0, 0); \ - if (unicode_empty != NULL) { \ - Py_INCREF(unicode_empty); \ - assert(_PyUnicode_CheckConsistency(unicode_empty, 1)); \ - } \ - } \ - } while (0) -#define _Py_RETURN_UNICODE_EMPTY() \ - do { \ - _Py_INCREF_UNICODE_EMPTY(); \ - return unicode_empty; \ +// Return a borrowed reference to the empty string singleton. +static inline PyObject* unicode_get_empty(void) +{ + struct _Py_unicode_state *state = get_unicode_state(); + // unicode_get_empty() must not be called before _PyUnicode_Init() + // or after _PyUnicode_Fini() + assert(state->empty_string != NULL); + return state->empty_string; +} + + +// Return a strong reference to the empty string singleton. +static inline PyObject* unicode_new_empty(void) +{ + PyObject *empty = unicode_get_empty(); + Py_INCREF(empty); + return empty; +} + +#define _Py_RETURN_UNICODE_EMPTY() \ + do { \ + return unicode_new_empty(); \ } while (0) static inline void @@ -294,17 +308,6 @@ unicode_decode_utf8(const char *s, Py_ssize_t size, _Py_error_handler error_handler, const char *errors, Py_ssize_t *consumed); -/* List of static strings. */ -static _Py_Identifier *static_strings = NULL; - -#define LATIN1_SINGLETONS - -#ifdef LATIN1_SINGLETONS -/* Single character Unicode strings in the Latin-1 range are being - shared as well. */ -static PyObject *unicode_latin1[256] = {NULL}; -#endif - /* Fast detection of the most frequent whitespace characters */ const unsigned char _Py_ascii_whitespace[] = { 0, 0, 0, 0, 0, 0, 0, 0, @@ -498,20 +501,6 @@ unicode_check_encoding_errors(const char *encoding, const char *errors) } -/* The max unicode value is always 0x10FFFF while using the PEP-393 API. - This function is kept for backward compatibility with the old API. */ -Py_UNICODE -PyUnicode_GetMax(void) -{ -#ifdef Py_UNICODE_WIDE - return 0x10FFFF; -#else - /* This is actually an illegal character, so it should - not be passed to unichr. */ - return 0xFFFF; -#endif -} - int _PyUnicode_CheckConsistency(PyObject *op, int check_content) { @@ -648,9 +637,8 @@ unicode_result_wchar(PyObject *unicode) if (len == 1) { wchar_t ch = _PyUnicode_WSTR(unicode)[0]; if ((Py_UCS4)ch < 256) { - PyObject *latin1_char = get_latin1_char((unsigned char)ch); Py_DECREF(unicode); - return latin1_char; + return get_latin1_char((unsigned char)ch); } } @@ -675,20 +663,21 @@ unicode_result_ready(PyObject *unicode) length = PyUnicode_GET_LENGTH(unicode); if (length == 0) { - if (unicode != unicode_empty) { + PyObject *empty = unicode_get_empty(); + if (unicode != empty) { Py_DECREF(unicode); - _Py_RETURN_UNICODE_EMPTY(); + Py_INCREF(empty); } - return unicode_empty; + return empty; } -#ifdef LATIN1_SINGLETONS if (length == 1) { - const void *data = PyUnicode_DATA(unicode); int kind = PyUnicode_KIND(unicode); - Py_UCS4 ch = PyUnicode_READ(kind, data, 0); - if (ch < 256) { - PyObject *latin1_char = unicode_latin1[ch]; + if (kind == PyUnicode_1BYTE_KIND) { + const Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode); + Py_UCS1 ch = data[0]; + struct _Py_unicode_state *state = get_unicode_state(); + PyObject *latin1_char = state->latin1[ch]; if (latin1_char != NULL) { if (unicode != latin1_char) { Py_INCREF(latin1_char); @@ -699,12 +688,14 @@ unicode_result_ready(PyObject *unicode) else { assert(_PyUnicode_CheckConsistency(unicode, 1)); Py_INCREF(unicode); - unicode_latin1[ch] = unicode; + state->latin1[ch] = unicode; return unicode; } } + else { + assert(PyUnicode_READ_CHAR(unicode, 0) >= 256); + } } -#endif assert(_PyUnicode_CheckConsistency(unicode, 1)); return unicode; @@ -867,7 +858,7 @@ xmlcharrefreplace(_PyBytesWriter *writer, char *str, to keep things simple, we use a single bitmask, using the least 5 bits from each unicode characters as the bit index. */ -/* the linebreak mask is set up by Unicode_Init below */ +/* the linebreak mask is set up by _PyUnicode_Init() below */ #if LONG_BIT >= 128 #define BLOOM_WIDTH 128 @@ -941,6 +932,8 @@ ensure_unicode(PyObject *obj) /* Compilation of templated routines */ +#define STRINGLIB_GET_EMPTY() unicode_get_empty() + #include "stringlib/asciilib.h" #include "stringlib/fastsearch.h" #include "stringlib/partition.h" @@ -989,6 +982,8 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS #include "stringlib/undef.h" _Py_COMP_DIAG_POP +#undef STRINGLIB_GET_EMPTY + /* --- Unicode Object ----------------------------------------------------- */ static inline Py_ssize_t @@ -1070,7 +1065,7 @@ resize_compact(PyObject *unicode, Py_ssize_t length) new_size = (struct_size + (length + 1) * char_size); if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) { - PyObject_DEL(_PyUnicode_UTF8(unicode)); + PyObject_Free(_PyUnicode_UTF8(unicode)); _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; } @@ -1081,7 +1076,7 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _Py_ForgetReference(unicode); #endif - new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size); + new_unicode = (PyObject *)PyObject_Realloc(unicode, new_size); if (new_unicode == NULL) { _Py_NewReference(unicode); PyErr_NoMemory(); @@ -1097,7 +1092,7 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _PyUnicode_WSTR_LENGTH(unicode) = length; } else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_DEL(_PyUnicode_WSTR(unicode)); + PyObject_Free(_PyUnicode_WSTR(unicode)); _PyUnicode_WSTR(unicode) = NULL; if (!PyUnicode_IS_ASCII(unicode)) _PyUnicode_WSTR_LENGTH(unicode) = 0; @@ -1140,12 +1135,12 @@ resize_inplace(PyObject *unicode, Py_ssize_t length) if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) { - PyObject_DEL(_PyUnicode_UTF8(unicode)); + PyObject_Free(_PyUnicode_UTF8(unicode)); _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; } - data = (PyObject *)PyObject_REALLOC(data, new_size); + data = (PyObject *)PyObject_Realloc(data, new_size); if (data == NULL) { PyErr_NoMemory(); return -1; @@ -1178,7 +1173,7 @@ resize_inplace(PyObject *unicode, Py_ssize_t length) } new_size = sizeof(wchar_t) * (length + 1); wstr = _PyUnicode_WSTR(unicode); - wstr = PyObject_REALLOC(wstr, new_size); + wstr = PyObject_Realloc(wstr, new_size); if (!wstr) { PyErr_NoMemory(); return -1; @@ -1237,9 +1232,8 @@ _PyUnicode_New(Py_ssize_t length) size_t new_size; /* Optimization for empty strings */ - if (length == 0 && unicode_empty != NULL) { - Py_INCREF(unicode_empty); - return (PyUnicodeObject*)unicode_empty; + if (length == 0) { + return (PyUnicodeObject *)unicode_new_empty(); } /* Ensure we won't overflow the size. */ @@ -1269,7 +1263,7 @@ _PyUnicode_New(Py_ssize_t length) _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; - _PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_MALLOC(new_size); + _PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_Malloc(new_size); if (!_PyUnicode_WSTR(unicode)) { Py_DECREF(unicode); PyErr_NoMemory(); @@ -1369,27 +1363,51 @@ _PyUnicode_Dump(PyObject *op) } else data = unicode->data.any; - printf("%s: len=%" PY_FORMAT_SIZE_T "u, ", - unicode_kind_name(op), ascii->length); + 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(" (%" PY_FORMAT_SIZE_T "u), ", compact->wstr_length); - if (!ascii->state.compact && compact->utf8 == unicode->data.any) + printf(" (%zu), ", compact->wstr_length); + if (!ascii->state.compact && compact->utf8 == unicode->data.any) { printf("shared "); - printf("utf8=%p (%" PY_FORMAT_SIZE_T "u)", - (void *)compact->utf8, compact->utf8_length); + } + printf("utf8=%p (%zu)", (void *)compact->utf8, compact->utf8_length); } printf(", data=%p\n", data); } #endif +static int +unicode_create_empty_string_singleton(struct _Py_unicode_state *state) +{ + // Use size=1 rather than size=0, so PyUnicode_New(0, maxchar) can be + // optimized to always use state->empty_string without having to check if + // it is NULL or not. + PyObject *empty = PyUnicode_New(1, 0); + if (empty == NULL) { + return -1; + } + PyUnicode_1BYTE_DATA(empty)[0] = 0; + _PyUnicode_LENGTH(empty) = 0; + assert(_PyUnicode_CheckConsistency(empty, 1)); + + assert(state->empty_string == NULL); + state->empty_string = empty; + return 0; +} + + PyObject * PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) { + /* Optimization for empty strings */ + if (size == 0) { + return unicode_new_empty(); + } + PyObject *obj; PyCompactUnicodeObject *unicode; void *data; @@ -1398,12 +1416,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) Py_ssize_t char_size; Py_ssize_t struct_size; - /* Optimization for empty strings */ - if (size == 0 && unicode_empty != NULL) { - Py_INCREF(unicode_empty); - return unicode_empty; - } - is_ascii = 0; is_sharing = 0; struct_size = sizeof(PyCompactUnicodeObject); @@ -1448,12 +1460,11 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) * PyObject_New() so we are able to allocate space for the object and * it's data buffer. */ - obj = (PyObject *) PyObject_MALLOC(struct_size + (size + 1) * char_size); - if (obj == NULL) + obj = (PyObject *) PyObject_Malloc(struct_size + (size + 1) * char_size); + if (obj == NULL) { return PyErr_NoMemory(); - obj = PyObject_INIT(obj, &PyUnicode_Type); - if (obj == NULL) - return NULL; + } + _PyObject_Init(obj, &PyUnicode_Type); unicode = (PyCompactUnicodeObject *)obj; if (is_ascii) @@ -1831,7 +1842,7 @@ _PyUnicode_Ready(PyObject *unicode) return -1; if (maxchar < 256) { - _PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(_PyUnicode_WSTR_LENGTH(unicode) + 1); + _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(_PyUnicode_WSTR_LENGTH(unicode) + 1); if (!_PyUnicode_DATA_ANY(unicode)) { PyErr_NoMemory(); return -1; @@ -1852,7 +1863,7 @@ _PyUnicode_Ready(PyObject *unicode) _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; } - PyObject_FREE(_PyUnicode_WSTR(unicode)); + PyObject_Free(_PyUnicode_WSTR(unicode)); _PyUnicode_WSTR(unicode) = NULL; _PyUnicode_WSTR_LENGTH(unicode) = 0; } @@ -1872,7 +1883,7 @@ _PyUnicode_Ready(PyObject *unicode) _PyUnicode_UTF8_LENGTH(unicode) = 0; #else /* sizeof(wchar_t) == 4 */ - _PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC( + _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc( 2 * (_PyUnicode_WSTR_LENGTH(unicode) + 1)); if (!_PyUnicode_DATA_ANY(unicode)) { PyErr_NoMemory(); @@ -1886,7 +1897,7 @@ _PyUnicode_Ready(PyObject *unicode) _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; - PyObject_FREE(_PyUnicode_WSTR(unicode)); + PyObject_Free(_PyUnicode_WSTR(unicode)); _PyUnicode_WSTR(unicode) = NULL; _PyUnicode_WSTR_LENGTH(unicode) = 0; #endif @@ -1901,7 +1912,7 @@ _PyUnicode_Ready(PyObject *unicode) PyErr_NoMemory(); return -1; } - _PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(4 * (length_wo_surrogates + 1)); + _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(4 * (length_wo_surrogates + 1)); if (!_PyUnicode_DATA_ANY(unicode)) { PyErr_NoMemory(); return -1; @@ -1913,7 +1924,7 @@ _PyUnicode_Ready(PyObject *unicode) /* 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)); + PyObject_Free(_PyUnicode_WSTR(unicode)); _PyUnicode_WSTR(unicode) = NULL; _PyUnicode_WSTR_LENGTH(unicode) = 0; #else @@ -1940,15 +1951,24 @@ unicode_dealloc(PyObject *unicode) break; case SSTATE_INTERNED_MORTAL: - /* revive dead object temporarily for DelItem */ - Py_SET_REFCNT(unicode, 3); + { #ifdef INTERNED_STRINGS + /* 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); #endif break; + } case SSTATE_INTERNED_IMMORTAL: _PyObject_ASSERT_FAILED_MSG(unicode, "Immortal interned string died"); @@ -1959,13 +1979,13 @@ unicode_dealloc(PyObject *unicode) } if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_DEL(_PyUnicode_WSTR(unicode)); + PyObject_Free(_PyUnicode_WSTR(unicode)); } if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) { - PyObject_DEL(_PyUnicode_UTF8(unicode)); + PyObject_Free(_PyUnicode_UTF8(unicode)); } if (!PyUnicode_IS_COMPACT(unicode) && _PyUnicode_DATA_ANY(unicode)) { - PyObject_DEL(_PyUnicode_DATA_ANY(unicode)); + PyObject_Free(_PyUnicode_DATA_ANY(unicode)); } Py_TYPE(unicode)->tp_free(unicode); @@ -1975,18 +1995,18 @@ unicode_dealloc(PyObject *unicode) static int unicode_is_singleton(PyObject *unicode) { - if (unicode == unicode_empty) { + struct _Py_unicode_state *state = get_unicode_state(); + if (unicode == state->empty_string) { return 1; } -#ifdef LATIN1_SINGLETONS PyASCIIObject *ascii = (PyASCIIObject *)unicode; if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) { Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); - if (ch < 256 && unicode_latin1[ch] == unicode) + if (ch < 256 && state->latin1[ch] == unicode) { return 1; + } } -#endif return 0; } #endif @@ -2031,10 +2051,8 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length) return 0; if (length == 0) { - _Py_INCREF_UNICODE_EMPTY(); - if (!unicode_empty) - return -1; - Py_SETREF(*p_unicode, unicode_empty); + PyObject *empty = unicode_new_empty(); + Py_SETREF(*p_unicode, empty); return 0; } @@ -2126,17 +2144,15 @@ unicode_write_cstr(PyObject *unicode, Py_ssize_t index, } static PyObject* -get_latin1_char(unsigned char ch) +get_latin1_char(Py_UCS1 ch) { - PyObject *unicode; + struct _Py_unicode_state *state = get_unicode_state(); -#ifdef LATIN1_SINGLETONS - unicode = unicode_latin1[ch]; + PyObject *unicode = state->latin1[ch]; if (unicode) { Py_INCREF(unicode); return unicode; } -#endif unicode = PyUnicode_New(1, ch); if (!unicode) { @@ -2146,10 +2162,8 @@ get_latin1_char(unsigned char ch) PyUnicode_1BYTE_DATA(unicode)[0] = ch; assert(_PyUnicode_CheckConsistency(unicode, 1)); -#ifdef LATIN1_SINGLETONS Py_INCREF(unicode); - unicode_latin1[ch] = unicode; -#endif + state->latin1[ch] = unicode; return unicode; } @@ -2160,8 +2174,9 @@ unicode_char(Py_UCS4 ch) assert(ch <= MAX_UNICODE); - if (ch < 256) + if (ch < 256) { return get_latin1_char(ch); + } unicode = PyUnicode_New(1, ch); if (unicode == NULL) @@ -2181,8 +2196,16 @@ unicode_char(Py_UCS4 ch) PyObject * PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) { - if (u == NULL) + 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(); @@ -2282,10 +2305,19 @@ PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) "Negative size passed to PyUnicode_FromStringAndSize"); return NULL; } - if (u != NULL) + if (u != NULL) { return PyUnicode_DecodeUTF8Stateful(u, size, NULL, NULL); - else + } + 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); + } } PyObject * @@ -2299,36 +2331,84 @@ PyUnicode_FromString(const char *u) return PyUnicode_DecodeUTF8Stateful(u, (Py_ssize_t)size, NULL, NULL); } + PyObject * _PyUnicode_FromId(_Py_Identifier *id) { - if (!id->object) { - id->object = PyUnicode_DecodeUTF8Stateful(id->string, - strlen(id->string), - NULL, NULL); - if (!id->object) + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_unicode_ids *ids = &interp->unicode.ids; + + Py_ssize_t index = _Py_atomic_size_get(&id->index); + if (index < 0) { + struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_ids; + + PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); + // Check again to detect concurrent access. Another thread can have + // initialized the index while this thread waited for the lock. + index = _Py_atomic_size_get(&id->index); + if (index < 0) { + assert(rt_ids->next_index < PY_SSIZE_T_MAX); + index = rt_ids->next_index; + rt_ids->next_index++; + _Py_atomic_size_set(&id->index, index); + } + PyThread_release_lock(rt_ids->lock); + } + assert(index >= 0); + + PyObject *obj; + if (index < ids->size) { + obj = ids->array[index]; + if (obj) { + // Return a borrowed reference + return obj; + } + } + + obj = PyUnicode_DecodeUTF8Stateful(id->string, strlen(id->string), + NULL, NULL); + if (!obj) { + return NULL; + } + PyUnicode_InternInPlace(&obj); + + if (index >= ids->size) { + // Overallocate to reduce the number of realloc + Py_ssize_t new_size = Py_MAX(index * 2, 16); + Py_ssize_t item_size = sizeof(ids->array[0]); + PyObject **new_array = PyMem_Realloc(ids->array, new_size * item_size); + if (new_array == NULL) { + PyErr_NoMemory(); return NULL; - PyUnicode_InternInPlace(&id->object); - assert(!id->next); - id->next = static_strings; - static_strings = id; + } + memset(&new_array[ids->size], 0, (new_size - ids->size) * item_size); + ids->array = new_array; + ids->size = new_size; } - return id->object; + + // The array stores a strong reference + ids->array[index] = obj; + + // Return a borrowed reference + return obj; } + static void -unicode_clear_static_strings(void) +unicode_clear_identifiers(struct _Py_unicode_state *state) { - _Py_Identifier *tmp, *s = static_strings; - while (s) { - Py_CLEAR(s->object); - tmp = s->next; - s->next = NULL; - s = tmp; + struct _Py_unicode_ids *ids = &state->ids; + for (Py_ssize_t i=0; i < ids->size; i++) { + Py_XDECREF(ids->array[i]); } - static_strings = NULL; + ids->size = 0; + PyMem_Free(ids->array); + ids->array = NULL; + // Don't reset _PyRuntime next_index: _Py_Identifier.id remains valid + // after Py_Finalize(). } + /* Internal function, doesn't check maximum character */ PyObject* @@ -2371,11 +2451,13 @@ _PyUnicode_FromUCS1(const Py_UCS1* u, Py_ssize_t size) PyObject *res; unsigned char max_char; - if (size == 0) + if (size == 0) { _Py_RETURN_UNICODE_EMPTY(); + } assert(size > 0); - if (size == 1) + if (size == 1) { return get_latin1_char(u[0]); + } max_char = ucs1lib_find_max_char(u, u + size); res = PyUnicode_New(size, max_char); @@ -2866,35 +2948,35 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, 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, "%" PY_FORMAT_SIZE_T "u", - va_arg(*vargs, size_t)); - else - len = sprintf(buffer, "%u", - va_arg(*vargs, unsigned int)); + 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, "%" PY_FORMAT_SIZE_T "i", - va_arg(*vargs, Py_ssize_t)); - else - len = sprintf(buffer, "%i", - va_arg(*vargs, int)); + 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)); + } } assert(len >= 0); @@ -3134,9 +3216,11 @@ 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); @@ -3157,16 +3241,21 @@ unicode_get_widechar_size(PyObject *unicode) static void unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size) { - const wchar_t *wstr; - assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); - wstr = _PyUnicode_WSTR(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) { @@ -3293,7 +3382,7 @@ PyUnicode_AsWideCharString(PyObject *unicode, *size = buflen; } else if (wcslen(buffer) != (size_t)buflen) { - PyMem_FREE(buffer); + PyMem_Free(buffer); PyErr_SetString(PyExc_ValueError, "embedded null character"); return NULL; @@ -3303,6 +3392,74 @@ PyUnicode_AsWideCharString(PyObject *unicode, #endif /* HAVE_WCHAR_H */ +int +_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", + Py_TYPE(obj)->tp_name); + return 0; +} + +int +_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; + } + if (obj == Py_None) { + *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 or None, not %.50s", + Py_TYPE(obj)->tp_name); + return 0; +} + PyObject * PyUnicode_FromOrdinal(int ordinal) { @@ -4126,7 +4283,7 @@ PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) PyErr_NoMemory(); return NULL; } - w = (wchar_t *) PyObject_MALLOC(sizeof(wchar_t) * (wlen + 1)); + w = (wchar_t *) PyObject_Malloc(sizeof(wchar_t) * (wlen + 1)); if (w == NULL) { PyErr_NoMemory(); return NULL; @@ -4316,7 +4473,6 @@ unicode_decode_call_errorhandler_wchar( Py_ssize_t requiredsize; Py_ssize_t newpos; PyObject *inputobj = NULL; - wchar_t *repwstr; Py_ssize_t repwlen; if (*errorHandler == NULL) { @@ -4362,12 +4518,19 @@ unicode_decode_call_errorhandler_wchar( goto onError; } +#if USE_UNICODE_WCHAR_CACHE _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS - repwstr = PyUnicode_AsUnicodeAndSize(repunicode, &repwlen); + repwlen = PyUnicode_GetSize(repunicode); + if (repwlen < 0) + goto onError; _Py_COMP_DIAG_POP - if (repwstr == NULL) +#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 @@ -4387,7 +4550,7 @@ _Py_COMP_DIAG_POP goto onError; } } - wcsncpy(*buf + *outpos, repwstr, repwlen); + PyUnicode_AsWideChar(repunicode, *buf + *outpos, repwlen); *outpos += repwlen; *endinpos = newpos; *inptr = *input + newpos; @@ -4950,45 +5113,36 @@ PyUnicode_DecodeUTF8(const char *s, #include "stringlib/codecs.h" #include "stringlib/undef.h" -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif static Py_ssize_t ascii_decode(const char *start, const char *end, Py_UCS1 *dest) { const char *p = start; - const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); - - /* - * Issue #17237: m68k is a bit different from most architectures in - * that objects do not use "natural alignment" - for example, int and - * long are only aligned at 2-byte boundaries. Therefore the assert() - * won't work; also, tests have shown that skipping the "optimised - * version" will even speed up m68k. - */ -#if !defined(__m68k__) -#if SIZEOF_LONG <= SIZEOF_VOID_P - assert(_Py_IS_ALIGNED(dest, SIZEOF_LONG)); - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + +#if SIZEOF_SIZE_T <= SIZEOF_VOID_P + assert(_Py_IS_ALIGNED(dest, ALIGNOF_SIZE_T)); + if (_Py_IS_ALIGNED(p, ALIGNOF_SIZE_T)) { /* Fast path, see in STRINGLIB(utf8_decode) for an explanation. */ /* Help allocation */ const char *_p = p; Py_UCS1 * q = dest; - while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + while (_p + SIZEOF_SIZE_T <= end) { + size_t value = *(const size_t *) _p; if (value & ASCII_CHAR_MASK) break; - *((unsigned long *)q) = value; - _p += SIZEOF_LONG; - q += SIZEOF_LONG; + *((size_t *)q) = value; + _p += SIZEOF_SIZE_T; + q += SIZEOF_SIZE_T; } p = _p; while (p < end) { @@ -4998,19 +5152,18 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) } return p - start; } -#endif #endif while (p < end) { /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h for an explanation. */ - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(p, ALIGNOF_SIZE_T)) { /* Help allocation */ const char *_p = p; - while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + while (_p + SIZEOF_SIZE_T <= end) { + size_t value = *(const size_t *) _p; if (value & ASCII_CHAR_MASK) break; - _p += SIZEOF_LONG; + _p += SIZEOF_SIZE_T; } p = _p; if (_p == end) @@ -5037,8 +5190,9 @@ unicode_decode_utf8(const char *s, Py_ssize_t size, /* ASCII is equivalent to the first 128 ordinals in Unicode. */ if (size == 1 && (unsigned char)s[0] < 128) { - if (consumed) + if (consumed) { *consumed = 1; + } return get_latin1_char((unsigned char)s[0]); } @@ -5547,7 +5701,7 @@ unicode_fill_utf8(PyObject *unicode) PyBytes_AS_STRING(writer.buffer); Py_ssize_t len = end - start; - char *cache = PyObject_MALLOC(len + 1); + char *cache = PyObject_Malloc(len + 1); if (cache == NULL) { _PyBytesWriter_Dealloc(&writer); PyErr_NoMemory(); @@ -6268,7 +6422,7 @@ PyUnicode_AsUTF16String(PyObject *unicode) /* --- Unicode Escape Codec ----------------------------------------------- */ -static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL; +static _PyUnicode_Name_CAPI *ucnhash_capi = NULL; PyObject * _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, @@ -6423,11 +6577,11 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, /* \N{name} */ case 'N': - if (ucnhash_CAPI == NULL) { + if (ucnhash_capi == NULL) { /* load the unicode data module */ - ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import( + ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( PyUnicodeData_CAPSULE_NAME, 1); - if (ucnhash_CAPI == NULL) { + if (ucnhash_capi == NULL) { PyErr_SetString( PyExc_UnicodeError, "\\N escapes not supported (can't load unicodedata module)" @@ -6455,7 +6609,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, s++; ch = 0xffffffff; /* in case 'getcode' messes up */ if (namelen <= INT_MAX && - ucnhash_CAPI->getcode(NULL, start, (int)namelen, + ucnhash_capi->getcode(start, (int)namelen, &ch, 0)) { assert(ch <= MAX_UNICODE); WRITE_CHAR(ch); @@ -7254,8 +7408,9 @@ PyUnicode_DecodeASCII(const char *s, _Py_RETURN_UNICODE_EMPTY(); /* ASCII is equivalent to the first 128 ordinals in Unicode. */ - if (size == 1 && (unsigned char)s[0] < 128) + if (size == 1 && (unsigned char)s[0] < 128) { return get_latin1_char((unsigned char)s[0]); + } // Shortcut for simple case PyObject *u = PyUnicode_New(size, 127); @@ -7736,6 +7891,7 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, /* Create a substring so that we can get the UTF-16 representation of just the slice under consideration. */ PyObject *substring; + int ret = -1; assert(len > 0); @@ -7747,14 +7903,22 @@ 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); -_Py_COMP_DIAG_POP 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 */ @@ -7766,16 +7930,15 @@ _Py_COMP_DIAG_POP goto error; /* If we used a default char, then we failed! */ if (pusedDefaultChar && *pusedDefaultChar) { - Py_DECREF(substring); - return -2; + ret = -2; + goto done; } if (*outbytes == NULL) { /* Create string object */ *outbytes = PyBytes_FromStringAndSize(NULL, outsize); if (*outbytes == NULL) { - Py_DECREF(substring); - return -1; + goto done; } out = PyBytes_AS_STRING(*outbytes); } @@ -7784,12 +7947,10 @@ _Py_COMP_DIAG_POP const Py_ssize_t n = PyBytes_Size(*outbytes); if (outsize > PY_SSIZE_T_MAX - n) { PyErr_NoMemory(); - Py_DECREF(substring); - return -1; + goto done; } if (_PyBytes_Resize(outbytes, n + outsize) < 0) { - Py_DECREF(substring); - return -1; + goto done; } out = PyBytes_AS_STRING(*outbytes) + n; } @@ -7799,19 +7960,29 @@ _Py_COMP_DIAG_POP p, (int)size, out, outsize, NULL, pusedDefaultChar); - Py_CLEAR(substring); if (outsize <= 0) goto error; - if (pusedDefaultChar && *pusedDefaultChar) - return -2; - return 0; + if (pusedDefaultChar && *pusedDefaultChar) { + ret = -2; + goto done; + } + 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: - Py_XDECREF(substring); - if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) - return -2; + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + ret = -2; + goto done; + } PyErr_SetFromWindowsErr(0); - return -1; + goto done; } /* @@ -8496,11 +8667,13 @@ PyUnicode_BuildEncodingMap(PyObject* string) } /* Create a three-level trie */ - result = PyObject_MALLOC(sizeof(struct encoding_map) + + result = PyObject_Malloc(sizeof(struct encoding_map) + 16*count2 + 128*count3 - 1); - if (!result) + if (!result) { return PyErr_NoMemory(); - PyObject_Init(result, &EncodingMapType); + } + + _PyObject_Init(result, &EncodingMapType); mresult = (struct encoding_map*)result; mresult->count2 = count2; mresult->count3 = count3; @@ -10161,7 +10334,7 @@ case_operation(PyObject *self, PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } - tmp = PyMem_MALLOC(sizeof(Py_UCS4) * 3 * length); + tmp = PyMem_Malloc(sizeof(Py_UCS4) * 3 * length); if (tmp == NULL) return PyErr_NoMemory(); newlength = perform(kind, data, length, tmp, &maxchar); @@ -10185,7 +10358,7 @@ case_operation(PyObject *self, Py_UNREACHABLE(); } leave: - PyMem_FREE(tmp); + PyMem_Free(tmp); return res; } @@ -10924,10 +11097,7 @@ replace(PyObject *self, PyObject *str1, } new_size = slen + n * (len2 - len1); if (new_size == 0) { - _Py_INCREF_UNICODE_EMPTY(); - if (!unicode_empty) - goto error; - u = unicode_empty; + u = unicode_new_empty(); goto done; } if (new_size > (PY_SSIZE_T_MAX / rkind)) { @@ -11003,11 +11173,11 @@ replace(PyObject *self, PyObject *str1, assert(release1 == (buf1 != PyUnicode_DATA(str1))); assert(release2 == (buf2 != PyUnicode_DATA(str2))); if (srelease) - PyMem_FREE((void *)sbuf); + PyMem_Free((void *)sbuf); if (release1) - PyMem_FREE((void *)buf1); + PyMem_Free((void *)buf1); if (release2) - PyMem_FREE((void *)buf2); + PyMem_Free((void *)buf2); assert(_PyUnicode_CheckConsistency(u, 1)); return u; @@ -11017,11 +11187,11 @@ replace(PyObject *self, PyObject *str1, assert(release1 == (buf1 != PyUnicode_DATA(str1))); assert(release2 == (buf2 != PyUnicode_DATA(str2))); if (srelease) - PyMem_FREE((void *)sbuf); + PyMem_Free((void *)sbuf); if (release1) - PyMem_FREE((void *)buf1); + PyMem_Free((void *)buf1); if (release2) - PyMem_FREE((void *)buf2); + PyMem_Free((void *)buf2); return unicode_result_unchanged(self); error: @@ -11029,11 +11199,11 @@ replace(PyObject *self, PyObject *str1, assert(release1 == (buf1 != PyUnicode_DATA(str1))); assert(release2 == (buf2 != PyUnicode_DATA(str2))); if (srelease) - PyMem_FREE((void *)sbuf); + PyMem_Free((void *)sbuf); if (release1) - PyMem_FREE((void *)buf1); + PyMem_Free((void *)buf1); if (release2) - PyMem_FREE((void *)buf2); + PyMem_Free((void *)buf2); return NULL; } @@ -11450,8 +11620,9 @@ _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right) #ifdef INTERNED_STRINGS assert(_PyUnicode_HASH(right_uni) != -1); Py_hash_t hash = _PyUnicode_HASH(left); - if (hash != -1 && hash != _PyUnicode_HASH(right_uni)) + if (hash != -1 && hash != _PyUnicode_HASH(right_uni)) { return 0; + } #endif return unicode_compare_eq(left, right_uni); @@ -11585,10 +11756,13 @@ PyUnicode_Concat(PyObject *left, PyObject *right) return NULL; /* Shortcuts */ - if (left == unicode_empty) + PyObject *empty = unicode_get_empty(); // Borrowed reference + if (left == empty) { return PyUnicode_FromObject(right); - if (right == unicode_empty) + } + if (right == empty) { return PyUnicode_FromObject(left); + } left_len = PyUnicode_GET_LENGTH(left); right_len = PyUnicode_GET_LENGTH(right); @@ -11639,14 +11813,16 @@ PyUnicode_Append(PyObject **p_left, PyObject *right) goto error; /* Shortcuts */ - if (left == unicode_empty) { + PyObject *empty = unicode_get_empty(); // Borrowed reference + if (left == empty) { Py_DECREF(left); Py_INCREF(right); *p_left = right; return; } - if (right == unicode_empty) + if (right == empty) { return; + } left_len = PyUnicode_GET_LENGTH(left); right_len = PyUnicode_GET_LENGTH(right); @@ -13343,14 +13519,8 @@ PyUnicode_Partition(PyObject *str_obj, PyObject *sep_obj) len1 = PyUnicode_GET_LENGTH(str_obj); len2 = PyUnicode_GET_LENGTH(sep_obj); if (kind1 < kind2 || len1 < len2) { - _Py_INCREF_UNICODE_EMPTY(); - if (!unicode_empty) - out = NULL; - else { - out = PyTuple_Pack(3, str_obj, unicode_empty, unicode_empty); - Py_DECREF(unicode_empty); - } - return out; + PyObject *empty = unicode_get_empty(); // Borrowed reference + return PyTuple_Pack(3, str_obj, empty, empty); } buf1 = PyUnicode_DATA(str_obj); buf2 = PyUnicode_DATA(sep_obj); @@ -13401,14 +13571,8 @@ PyUnicode_RPartition(PyObject *str_obj, PyObject *sep_obj) len1 = PyUnicode_GET_LENGTH(str_obj); len2 = PyUnicode_GET_LENGTH(sep_obj); if (kind1 < kind2 || len1 < len2) { - _Py_INCREF_UNICODE_EMPTY(); - if (!unicode_empty) - out = NULL; - else { - out = PyTuple_Pack(3, unicode_empty, unicode_empty, str_obj); - Py_DECREF(unicode_empty); - } - return out; + PyObject *empty = unicode_get_empty(); // Borrowed reference + return PyTuple_Pack(3, empty, empty, str_obj); } buf1 = PyUnicode_DATA(str_obj); buf2 = PyUnicode_DATA(sep_obj); @@ -14731,20 +14895,15 @@ mainformatlong(PyObject *v, /* make sure number is a type of integer for o, x, and X */ if (!PyLong_Check(v)) { if (type == 'o' || type == 'x' || type == 'X') { - iobj = PyNumber_Index(v); - if (iobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - goto wrongtype; - return -1; - } + iobj = _PyNumber_Index(v); } else { iobj = PyNumber_Long(v); - if (iobj == NULL ) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - goto wrongtype; - return -1; - } + } + if (iobj == NULL ) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + goto wrongtype; + return -1; } assert(PyLong_Check(iobj)); } @@ -14808,7 +14967,7 @@ wrongtype: break; default: PyErr_Format(PyExc_TypeError, - "%%%c format: a number is required, " + "%%%c format: a real number is required, " "not %.200s", type, Py_TYPE(v)->tp_name); break; @@ -14827,24 +14986,17 @@ formatchar(PyObject *v) goto onError; } else { - PyObject *iobj; - long x; - /* make sure number is a type of integer */ - if (!PyLong_Check(v)) { - iobj = PyNumber_Index(v); - if (iobj == NULL) { + int overflow; + long x = PyLong_AsLongAndOverflow(v, &overflow); + if (x == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { goto onError; } - x = PyLong_AsLong(iobj); - Py_DECREF(iobj); - } - else { - x = PyLong_AsLong(v); + return (Py_UCS4) -1; } - if (x == -1 && PyErr_Occurred()) - goto onError; if (x < 0 || x > MAX_UNICODE) { + /* this includes an overflow in converting to C long */ PyErr_SetString(PyExc_OverflowError, "%c arg not in range(0x110000)"); return (Py_UCS4) -1; @@ -15442,52 +15594,57 @@ PyUnicode_Format(PyObject *format, PyObject *args) } static PyObject * -unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +unicode_subtype_new(PyTypeObject *type, PyObject *unicode); + +/*[clinic input] +@classmethod +str.__new__ as unicode_new + + object as x: object = NULL + encoding: str = NULL + errors: str = NULL + +[clinic start generated code]*/ static PyObject * -unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +unicode_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, + const char *errors) +/*[clinic end generated code: output=fc72d4878b0b57e9 input=e81255e5676d174e]*/ { - PyObject *x = NULL; - static char *kwlist[] = {"object", "encoding", "errors", 0}; - char *encoding = NULL; - char *errors = NULL; + PyObject *unicode; + if (x == NULL) { + unicode = unicode_new_empty(); + } + else if (encoding == NULL && errors == NULL) { + unicode = PyObject_Str(x); + } + else { + unicode = PyUnicode_FromEncodedObject(x, encoding, errors); + } - if (type != &PyUnicode_Type) - return unicode_subtype_new(type, args, kwds); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:str", - kwlist, &x, &encoding, &errors)) - return NULL; - if (x == NULL) - _Py_RETURN_UNICODE_EMPTY(); - if (encoding == NULL && errors == NULL) - return PyObject_Str(x); - else - return PyUnicode_FromEncodedObject(x, encoding, errors); + if (unicode != NULL && type != &PyUnicode_Type) { + Py_SETREF(unicode, unicode_subtype_new(type, unicode)); + } + return unicode; } static PyObject * -unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +unicode_subtype_new(PyTypeObject *type, PyObject *unicode) { - PyObject *unicode, *self; + PyObject *self; Py_ssize_t length, char_size; int share_wstr, share_utf8; unsigned int kind; void *data; assert(PyType_IsSubtype(type, &PyUnicode_Type)); - - unicode = unicode_new(&PyUnicode_Type, args, kwds); - if (unicode == NULL) - return NULL; assert(_PyUnicode_CHECK(unicode)); if (PyUnicode_READY(unicode) == -1) { - Py_DECREF(unicode); return NULL; } self = type->tp_alloc(type, 0); if (self == NULL) { - Py_DECREF(unicode); return NULL; } kind = PyUnicode_KIND(unicode); @@ -15534,7 +15691,7 @@ unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyErr_NoMemory(); goto onError; } - data = PyObject_MALLOC((length + 1) * char_size); + data = PyObject_Malloc((length + 1) * char_size); if (data == NULL) { PyErr_NoMemory(); goto onError; @@ -15556,11 +15713,9 @@ unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) #ifdef Py_DEBUG _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode); #endif - Py_DECREF(unicode); return self; onError: - Py_DECREF(unicode); Py_DECREF(self); return NULL; } @@ -15601,7 +15756,8 @@ PyTypeObject PyUnicode_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_UNICODE_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_UNICODE_SUBCLASS | + _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ unicode_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -15626,36 +15782,40 @@ PyTypeObject PyUnicode_Type = { /* Initialize the Unicode implementation */ PyStatus -_PyUnicode_Init(void) -{ - /* XXX - move this array to unicodectype.c ? */ - Py_UCS2 linebreak[] = { - 0x000A, /* LINE FEED */ - 0x000D, /* CARRIAGE RETURN */ - 0x001C, /* FILE SEPARATOR */ - 0x001D, /* GROUP SEPARATOR */ - 0x001E, /* RECORD SEPARATOR */ - 0x0085, /* NEXT LINE */ - 0x2028, /* LINE SEPARATOR */ - 0x2029, /* PARAGRAPH SEPARATOR */ - }; - - /* Init the implementation */ - _Py_INCREF_UNICODE_EMPTY(); - if (!unicode_empty) { - return _PyStatus_ERR("Can't create empty string"); - } - Py_DECREF(unicode_empty); +_PyUnicode_Init(PyInterpreterState *interp) +{ + struct _Py_unicode_state *state = &interp->unicode; + if (unicode_create_empty_string_singleton(state) < 0) { + return _PyStatus_NO_MEMORY(); + } + + if (_Py_IsMainInterpreter(interp)) { + /* initialize the linebreak bloom filter */ + const Py_UCS2 linebreak[] = { + 0x000A, /* LINE FEED */ + 0x000D, /* CARRIAGE RETURN */ + 0x001C, /* FILE SEPARATOR */ + 0x001D, /* GROUP SEPARATOR */ + 0x001E, /* RECORD SEPARATOR */ + 0x0085, /* NEXT LINE */ + 0x2028, /* LINE SEPARATOR */ + 0x2029, /* PARAGRAPH SEPARATOR */ + }; + bloom_linebreak = make_bloom_mask( + PyUnicode_2BYTE_KIND, linebreak, + Py_ARRAY_LENGTH(linebreak)); + } + + return _PyStatus_OK(); +} + +PyStatus +_PyUnicode_InitTypes(void) +{ if (PyType_Ready(&PyUnicode_Type) < 0) { return _PyStatus_ERR("Can't initialize unicode type"); } - - /* initialize the linebreak bloom filter */ - bloom_linebreak = make_bloom_mask( - PyUnicode_2BYTE_KIND, linebreak, - Py_ARRAY_LENGTH(linebreak)); - if (PyType_Ready(&EncodingMapType) < 0) { return _PyStatus_ERR("Can't initialize encoding map type"); } @@ -15693,6 +15853,11 @@ PyUnicode_InternInPlace(PyObject **p) } #ifdef INTERNED_STRINGS + if (PyUnicode_READY(s) == -1) { + PyErr_Clear(); + return; + } + if (interned == NULL) { interned = PyDict_New(); if (interned == NULL) { @@ -15701,9 +15866,7 @@ PyUnicode_InternInPlace(PyObject **p) } } - PyObject *t; - t = PyDict_SetDefault(interned, s, s); - + PyObject *t = PyDict_SetDefault(interned, s, s); if (t == NULL) { PyErr_Clear(); return; @@ -15715,16 +15878,30 @@ PyUnicode_InternInPlace(PyObject **p) return; } - /* The two references in interned are not counted by refcnt. - The deallocator will take care of this */ + /* 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; +#else + // PyDict expects that interned strings have their hash + // (PyASCIIObject.hash) already computed. + (void)unicode_hash(s); #endif } void PyUnicode_InternImmortal(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); + } + PyUnicode_InternInPlace(p); if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; @@ -15743,45 +15920,45 @@ PyUnicode_InternFromString(const char *cp) } -#if defined(WITH_VALGRIND) || defined(__INSURE__) -static void -unicode_release_interned(void) +void +_PyUnicode_ClearInterned(PyInterpreterState *interp) { - if (interned == NULL || !PyDict_Check(interned)) { + if (!_Py_IsMainInterpreter(interp)) { + // interned dict is shared by all interpreters return; } - PyObject *keys = PyDict_Keys(interned); - if (keys == NULL || !PyList_Check(keys)) { - PyErr_Clear(); + + if (interned == NULL) { return; } + assert(PyDict_CheckExact(interned)); - /* Since unicode_release_interned() is intended to help a leak - detector, interned unicode strings are not forcibly deallocated; - rather, we give them their stolen references back, and then clear - and DECREF the interned dict. */ + /* Interned unicode strings are not forcibly deallocated; rather, we give + them their stolen references back, and then clear and DECREF the + interned dict. */ - Py_ssize_t n = PyList_GET_SIZE(keys); #ifdef INTERNED_STATS - fprintf(stderr, "releasing %" PY_FORMAT_SIZE_T "d interned strings\n", - n); + fprintf(stderr, "releasing %zd interned strings\n", + PyDict_GET_SIZE(interned)); Py_ssize_t immortal_size = 0, mortal_size = 0; #endif - for (Py_ssize_t i = 0; i < n; i++) { - PyObject *s = PyList_GET_ITEM(keys, i); - if (PyUnicode_READY(s) == -1) { - Py_UNREACHABLE(); - } + Py_ssize_t pos = 0; + PyObject *s, *ignored_value; + while (PyDict_Next(interned, &pos, &s, &ignored_value)) { + assert(PyUnicode_IS_READY(s)); + switch (PyUnicode_CHECK_INTERNED(s)) { case SSTATE_INTERNED_IMMORTAL: - Py_REFCNT(s) += 1; + Py_SET_REFCNT(s, Py_REFCNT(s) + 1); #ifdef INTERNED_STATS immortal_size += PyUnicode_GET_LENGTH(s); #endif break; case SSTATE_INTERNED_MORTAL: - Py_REFCNT(s) += 2; + // Restore the two references (key and value) ignored + // by PyUnicode_InternInPlace(). + Py_SET_REFCNT(s, Py_REFCNT(s) + 2); #ifdef INTERNED_STATS mortal_size += PyUnicode_GET_LENGTH(s); #endif @@ -15794,15 +15971,14 @@ unicode_release_interned(void) _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; } #ifdef INTERNED_STATS - fprintf(stderr, "total size of all interned strings: " - "%" PY_FORMAT_SIZE_T "d/%" PY_FORMAT_SIZE_T "d " - "mortal/immortal\n", mortal_size, immortal_size); + fprintf(stderr, + "total size of all interned strings: %zd/%zd mortal/immortal\n", + mortal_size, immortal_size); #endif - Py_DECREF(keys); + PyDict_Clear(interned); Py_CLEAR(interned); } -#endif /********************* Unicode Iterator **************************/ @@ -15964,127 +16140,6 @@ unicode_iter(PyObject *seq) return (PyObject *)it; } - -size_t -Py_UNICODE_strlen(const Py_UNICODE *u) -{ - return wcslen(u); -} - -Py_UNICODE* -Py_UNICODE_strcpy(Py_UNICODE *s1, const Py_UNICODE *s2) -{ - Py_UNICODE *u = s1; - while ((*u++ = *s2++)); - return s1; -} - -Py_UNICODE* -Py_UNICODE_strncpy(Py_UNICODE *s1, const Py_UNICODE *s2, size_t n) -{ - Py_UNICODE *u = s1; - while ((*u++ = *s2++)) - if (n-- == 0) - break; - return s1; -} - -Py_UNICODE* -Py_UNICODE_strcat(Py_UNICODE *s1, const Py_UNICODE *s2) -{ - Py_UNICODE *u1 = s1; - u1 += wcslen(u1); - while ((*u1++ = *s2++)); - return s1; -} - -int -Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2) -{ - while (*s1 && *s2 && *s1 == *s2) - s1++, s2++; - if (*s1 && *s2) - return (*s1 < *s2) ? -1 : +1; - if (*s1) - return 1; - if (*s2) - return -1; - return 0; -} - -int -Py_UNICODE_strncmp(const Py_UNICODE *s1, const Py_UNICODE *s2, size_t n) -{ - Py_UNICODE u1, u2; - for (; n != 0; n--) { - u1 = *s1; - u2 = *s2; - if (u1 != u2) - return (u1 < u2) ? -1 : +1; - if (u1 == '\0') - return 0; - s1++; - s2++; - } - return 0; -} - -Py_UNICODE* -Py_UNICODE_strchr(const Py_UNICODE *s, Py_UNICODE c) -{ - const Py_UNICODE *p; - for (p = s; *p; p++) - if (*p == c) - return (Py_UNICODE*)p; - return NULL; -} - -Py_UNICODE* -Py_UNICODE_strrchr(const Py_UNICODE *s, Py_UNICODE c) -{ - const Py_UNICODE *p; - p = s + wcslen(s); - while (p != s) { - p--; - if (*p == c) - return (Py_UNICODE*)p; - } - return NULL; -} - -Py_UNICODE* -PyUnicode_AsUnicodeCopy(PyObject *unicode) -{ - Py_UNICODE *u, *copy; - Py_ssize_t len, size; - - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - return NULL; - } -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - u = PyUnicode_AsUnicodeAndSize(unicode, &len); -_Py_COMP_DIAG_POP - if (u == NULL) - return NULL; - /* Ensure we won't overflow the size. */ - if (len > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { - PyErr_NoMemory(); - return NULL; - } - size = len + 1; /* copy the null character */ - size *= sizeof(Py_UNICODE); - copy = PyMem_Malloc(size); - if (copy == NULL) { - PyErr_NoMemory(); - return NULL; - } - memcpy(copy, u, size); - return copy; -} - - static int encode_wstr_utf8(wchar_t *wstr, char **str, const char *name) { @@ -16150,10 +16205,10 @@ error: static PyStatus -init_stdio_encoding(PyThreadState *tstate) +init_stdio_encoding(PyInterpreterState *interp) { /* Update the stdio encoding to the normalized Python codec name. */ - PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(tstate->interp); + PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp); if (config_get_codec_name(&config->stdio_encoding) < 0) { return _PyStatus_ERR("failed to get the Python codec name " "of the stdio encoding"); @@ -16246,7 +16301,7 @@ _PyUnicode_InitEncodings(PyThreadState *tstate) return status; } - return init_stdio_encoding(tstate); + return init_stdio_encoding(tstate->interp); } @@ -16290,33 +16345,23 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void) void -_PyUnicode_Fini(PyThreadState *tstate) -{ - if (_Py_IsMainInterpreter(tstate)) { -#if defined(WITH_VALGRIND) || defined(__INSURE__) - /* Insure++ is a memory analysis tool that aids in discovering - * memory leaks and other memory problems. On Python exit, the - * interned string dictionaries are flagged as being in use at exit - * (which it is). Under normal circumstances, this is fine because - * the memory will be automatically reclaimed by the system. Under - * memory debugging, it's a huge source of useless noise, so we - * trade off slower shutdown for less distraction in the memory - * reports. -baw - */ - unicode_release_interned(); -#endif /* __INSURE__ */ - - Py_CLEAR(unicode_empty); - -#ifdef LATIN1_SINGLETONS - for (Py_ssize_t i = 0; i < 256; i++) { - Py_CLEAR(unicode_latin1[i]); - } -#endif - unicode_clear_static_strings(); +_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); } - _PyUnicode_FiniEncodings(&tstate->interp->unicode.fs_codec); + _PyUnicode_FiniEncodings(&state->fs_codec); + + unicode_clear_identifiers(state); + + for (Py_ssize_t i = 0; i < 256; i++) { + Py_CLEAR(state->latin1[i]); + } + Py_CLEAR(state->empty_string); } @@ -16333,20 +16378,16 @@ static PyMethodDef _string_methods[] = { static struct PyModuleDef _string_module = { PyModuleDef_HEAD_INIT, - "_string", - PyDoc_STR("string helper module"), - 0, - _string_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_string", + .m_doc = PyDoc_STR("string helper module"), + .m_size = 0, + .m_methods = _string_methods, }; PyMODINIT_FUNC PyInit__string(void) { - return PyModule_Create(&_string_module); + return PyModuleDef_Init(&_string_module); } diff --git a/contrib/tools/python3/src/Objects/unionobject.c b/contrib/tools/python3/src/Objects/unionobject.c new file mode 100644 index 00000000000..80c70389ab3 --- /dev/null +++ b/contrib/tools/python3/src/Objects/unionobject.c @@ -0,0 +1,496 @@ +// 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_unionobject.h" +#include "structmember.h" + + +static PyObject *make_union(PyObject *); + + +typedef struct { + PyObject_HEAD + PyObject *args; + PyObject *parameters; +} unionobject; + +static void +unionobject_dealloc(PyObject *self) +{ + unionobject *alias = (unionobject *)self; + + _PyObject_GC_UNTRACK(self); + + Py_XDECREF(alias->args); + Py_XDECREF(alias->parameters); + Py_TYPE(self)->tp_free(self); +} + +static int +union_traverse(PyObject *self, visitproc visit, void *arg) +{ + unionobject *alias = (unionobject *)self; + Py_VISIT(alias->args); + Py_VISIT(alias->parameters); + return 0; +} + +static Py_hash_t +union_hash(PyObject *self) +{ + unionobject *alias = (unionobject *)self; + PyObject *args = PyFrozenSet_New(alias->args); + if (args == NULL) { + return (Py_hash_t)-1; + } + Py_hash_t hash = PyObject_Hash(args); + Py_DECREF(args); + return hash; +} + +static int +is_generic_alias_in_args(PyObject *args) +{ + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(args, iarg); + if (_PyGenericAlias_Check(arg)) { + return 0; + } + } + return 1; +} + +static PyObject * +union_instancecheck(PyObject *self, PyObject *instance) +{ + unionobject *alias = (unionobject *) self; + Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args); + if (!is_generic_alias_in_args(alias->args)) { + PyErr_SetString(PyExc_TypeError, + "isinstance() argument 2 cannot contain a parameterized generic"); + return NULL; + } + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg); + if (PyType_Check(arg)) { + int res = PyObject_IsInstance(instance, arg); + if (res < 0) { + return NULL; + } + if (res) { + Py_RETURN_TRUE; + } + } + } + Py_RETURN_FALSE; +} + +static PyObject * +union_subclasscheck(PyObject *self, PyObject *instance) +{ + if (!PyType_Check(instance)) { + PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class"); + return NULL; + } + unionobject *alias = (unionobject *)self; + if (!is_generic_alias_in_args(alias->args)) { + PyErr_SetString(PyExc_TypeError, + "issubclass() argument 2 cannot contain a parameterized generic"); + return NULL; + } + Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args); + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg); + if (PyType_Check(arg)) { + int res = PyObject_IsSubclass(instance, arg); + if (res < 0) { + return NULL; + } + if (res) { + Py_RETURN_TRUE; + } + } + } + Py_RETURN_FALSE; +} + +static PyObject * +union_richcompare(PyObject *a, PyObject *b, int op) +{ + if (!_PyUnion_Check(b) || (op != Py_EQ && op != Py_NE)) { + Py_RETURN_NOTIMPLEMENTED; + } + + PyObject *a_set = PySet_New(((unionobject*)a)->args); + if (a_set == NULL) { + return NULL; + } + PyObject *b_set = PySet_New(((unionobject*)b)->args); + if (b_set == NULL) { + Py_DECREF(a_set); + return NULL; + } + PyObject *result = PyObject_RichCompare(a_set, b_set, op); + Py_DECREF(b_set); + Py_DECREF(a_set); + return result; +} + +static PyObject* +flatten_args(PyObject* args) +{ + Py_ssize_t arg_length = PyTuple_GET_SIZE(args); + Py_ssize_t total_args = 0; + // Get number of total args once it's flattened. + for (Py_ssize_t i = 0; i < arg_length; i++) { + PyObject *arg = PyTuple_GET_ITEM(args, i); + if (_PyUnion_Check(arg)) { + total_args += PyTuple_GET_SIZE(((unionobject*) arg)->args); + } else { + total_args++; + } + } + // Create new tuple of flattened args. + PyObject *flattened_args = PyTuple_New(total_args); + if (flattened_args == NULL) { + return NULL; + } + Py_ssize_t pos = 0; + for (Py_ssize_t i = 0; i < arg_length; i++) { + PyObject *arg = PyTuple_GET_ITEM(args, i); + if (_PyUnion_Check(arg)) { + PyObject* nested_args = ((unionobject*)arg)->args; + Py_ssize_t nested_arg_length = PyTuple_GET_SIZE(nested_args); + for (Py_ssize_t j = 0; j < nested_arg_length; j++) { + PyObject* nested_arg = PyTuple_GET_ITEM(nested_args, j); + Py_INCREF(nested_arg); + PyTuple_SET_ITEM(flattened_args, pos, nested_arg); + pos++; + } + } else { + if (arg == Py_None) { + arg = (PyObject *)&_PyNone_Type; + } + Py_INCREF(arg); + PyTuple_SET_ITEM(flattened_args, pos, arg); + pos++; + } + } + assert(pos == total_args); + return flattened_args; +} + +static PyObject* +dedup_and_flatten_args(PyObject* args) +{ + args = flatten_args(args); + if (args == NULL) { + return NULL; + } + Py_ssize_t arg_length = PyTuple_GET_SIZE(args); + PyObject *new_args = PyTuple_New(arg_length); + if (new_args == NULL) { + Py_DECREF(args); + return NULL; + } + // Add unique elements to an array. + Py_ssize_t added_items = 0; + for (Py_ssize_t i = 0; i < arg_length; i++) { + int is_duplicate = 0; + PyObject* i_element = PyTuple_GET_ITEM(args, i); + for (Py_ssize_t j = 0; j < added_items; j++) { + PyObject* j_element = PyTuple_GET_ITEM(new_args, j); + int is_ga = _PyGenericAlias_Check(i_element) && + _PyGenericAlias_Check(j_element); + // RichCompare to also deduplicate GenericAlias types (slower) + is_duplicate = is_ga ? PyObject_RichCompareBool(i_element, j_element, Py_EQ) + : i_element == j_element; + // Should only happen if RichCompare fails + if (is_duplicate < 0) { + Py_DECREF(args); + Py_DECREF(new_args); + return NULL; + } + if (is_duplicate) + break; + } + if (!is_duplicate) { + Py_INCREF(i_element); + PyTuple_SET_ITEM(new_args, added_items, i_element); + added_items++; + } + } + Py_DECREF(args); + _PyTuple_Resize(&new_args, added_items); + return new_args; +} + +static int +is_unionable(PyObject *obj) +{ + return (obj == Py_None || + PyType_Check(obj) || + _PyGenericAlias_Check(obj) || + _PyUnion_Check(obj)); +} + +PyObject * +_Py_union_type_or(PyObject* self, PyObject* other) +{ + if (!is_unionable(self) || !is_unionable(other)) { + Py_RETURN_NOTIMPLEMENTED; + } + + PyObject *tuple = PyTuple_Pack(2, self, other); + if (tuple == NULL) { + return NULL; + } + + PyObject *new_union = make_union(tuple); + Py_DECREF(tuple); + return new_union; +} + +static int +union_repr_item(_PyUnicodeWriter *writer, PyObject *p) +{ + _Py_IDENTIFIER(__module__); + _Py_IDENTIFIER(__qualname__); + _Py_IDENTIFIER(__origin__); + _Py_IDENTIFIER(__args__); + PyObject *qualname = NULL; + PyObject *module = NULL; + PyObject *tmp; + PyObject *r = NULL; + int err; + + if (p == (PyObject *)&_PyNone_Type) { + return _PyUnicodeWriter_WriteASCIIString(writer, "None", 4); + } + + if (_PyObject_LookupAttrId(p, &PyId___origin__, &tmp) < 0) { + goto exit; + } + + if (tmp) { + Py_DECREF(tmp); + if (_PyObject_LookupAttrId(p, &PyId___args__, &tmp) < 0) { + goto exit; + } + if (tmp) { + // It looks like a GenericAlias + Py_DECREF(tmp); + goto use_repr; + } + } + + if (_PyObject_LookupAttrId(p, &PyId___qualname__, &qualname) < 0) { + goto exit; + } + if (qualname == NULL) { + goto use_repr; + } + if (_PyObject_LookupAttrId(p, &PyId___module__, &module) < 0) { + goto exit; + } + if (module == NULL || module == Py_None) { + goto use_repr; + } + + // Looks like a class + if (PyUnicode_Check(module) && + _PyUnicode_EqualToASCIIString(module, "builtins")) + { + // builtins don't need a module name + r = PyObject_Str(qualname); + goto exit; + } + else { + r = PyUnicode_FromFormat("%S.%S", module, qualname); + goto exit; + } + +use_repr: + r = PyObject_Repr(p); +exit: + Py_XDECREF(qualname); + Py_XDECREF(module); + if (r == NULL) { + return -1; + } + err = _PyUnicodeWriter_WriteStr(writer, r); + Py_DECREF(r); + return err; +} + +static PyObject * +union_repr(PyObject *self) +{ + unionobject *alias = (unionobject *)self; + Py_ssize_t len = PyTuple_GET_SIZE(alias->args); + + _PyUnicodeWriter writer; + _PyUnicodeWriter_Init(&writer); + for (Py_ssize_t i = 0; i < len; i++) { + if (i > 0 && _PyUnicodeWriter_WriteASCIIString(&writer, " | ", 3) < 0) { + goto error; + } + PyObject *p = PyTuple_GET_ITEM(alias->args, i); + if (union_repr_item(&writer, p) < 0) { + goto error; + } + } + return _PyUnicodeWriter_Finish(&writer); +error: + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + +static PyMemberDef union_members[] = { + {"__args__", T_OBJECT, offsetof(unionobject, args), READONLY}, + {0} +}; + +static PyMethodDef union_methods[] = { + {"__instancecheck__", union_instancecheck, METH_O}, + {"__subclasscheck__", union_subclasscheck, METH_O}, + {0}}; + + +static PyObject * +union_getitem(PyObject *self, PyObject *item) +{ + unionobject *alias = (unionobject *)self; + // Populate __parameters__ if needed. + if (alias->parameters == NULL) { + alias->parameters = _Py_make_parameters(alias->args); + if (alias->parameters == NULL) { + return NULL; + } + } + + PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item); + if (newargs == NULL) { + return NULL; + } + + PyObject *res; + Py_ssize_t nargs = PyTuple_GET_SIZE(newargs); + if (nargs == 0) { + res = make_union(newargs); + } + else { + res = PyTuple_GET_ITEM(newargs, 0); + Py_INCREF(res); + for (Py_ssize_t iarg = 1; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(newargs, iarg); + Py_SETREF(res, PyNumber_Or(res, arg)); + if (res == NULL) { + break; + } + } + } + Py_DECREF(newargs); + return res; +} + +static PyMappingMethods union_as_mapping = { + .mp_subscript = union_getitem, +}; + +static PyObject * +union_parameters(PyObject *self, void *Py_UNUSED(unused)) +{ + unionobject *alias = (unionobject *)self; + if (alias->parameters == NULL) { + alias->parameters = _Py_make_parameters(alias->args); + if (alias->parameters == NULL) { + return NULL; + } + } + Py_INCREF(alias->parameters); + return alias->parameters; +} + +static PyGetSetDef union_properties[] = { + {"__parameters__", union_parameters, (setter)NULL, "Type variables in the types.UnionType.", NULL}, + {0} +}; + +static PyNumberMethods union_as_number = { + .nb_or = _Py_union_type_or, // Add __or__ function +}; + +static const char* const cls_attrs[] = { + "__module__", // Required for compatibility with typing module + NULL, +}; + +static PyObject * +union_getattro(PyObject *self, PyObject *name) +{ + unionobject *alias = (unionobject *)self; + if (PyUnicode_Check(name)) { + for (const char * const *p = cls_attrs; ; p++) { + if (*p == NULL) { + break; + } + if (_PyUnicode_EqualToASCIIString(name, *p)) { + return PyObject_GetAttr((PyObject *) Py_TYPE(alias), name); + } + } + } + return PyObject_GenericGetAttr(self, name); +} + +PyTypeObject _PyUnion_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "types.UnionType", + .tp_doc = "Represent a PEP 604 union type\n" + "\n" + "E.g. for int | str", + .tp_basicsize = sizeof(unionobject), + .tp_dealloc = unionobject_dealloc, + .tp_alloc = PyType_GenericAlloc, + .tp_free = PyObject_GC_Del, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = union_traverse, + .tp_hash = union_hash, + .tp_getattro = union_getattro, + .tp_members = union_members, + .tp_methods = union_methods, + .tp_richcompare = union_richcompare, + .tp_as_mapping = &union_as_mapping, + .tp_as_number = &union_as_number, + .tp_repr = union_repr, + .tp_getset = union_properties, +}; + +static PyObject * +make_union(PyObject *args) +{ + assert(PyTuple_CheckExact(args)); + + args = dedup_and_flatten_args(args); + if (args == NULL) { + return NULL; + } + if (PyTuple_GET_SIZE(args) == 1) { + PyObject *result1 = PyTuple_GET_ITEM(args, 0); + Py_INCREF(result1); + Py_DECREF(args); + return result1; + } + + unionobject *result = PyObject_GC_New(unionobject, &_PyUnion_Type); + if (result == NULL) { + Py_DECREF(args); + return NULL; + } + + result->parameters = NULL; + result->args = args; + _PyObject_GC_TRACK(result); + return (PyObject*)result; +} diff --git a/contrib/tools/python3/src/PC/clinic/_msi.c.h b/contrib/tools/python3/src/PC/clinic/_msi.c.h new file mode 100644 index 00000000000..85c4d226ee4 --- /dev/null +++ b/contrib/tools/python3/src/PC/clinic/_msi.c.h @@ -0,0 +1,716 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_msi_UuidCreate__doc__, +"UuidCreate($module, /)\n" +"--\n" +"\n" +"Return the string representation of a new unique identifier."); + +#define _MSI_UUIDCREATE_METHODDEF \ + {"UuidCreate", (PyCFunction)_msi_UuidCreate, METH_NOARGS, _msi_UuidCreate__doc__}, + +static PyObject * +_msi_UuidCreate_impl(PyObject *module); + +static PyObject * +_msi_UuidCreate(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _msi_UuidCreate_impl(module); +} + +PyDoc_STRVAR(_msi_FCICreate__doc__, +"FCICreate($module, cabname, files, /)\n" +"--\n" +"\n" +"Create a new CAB file.\n" +"\n" +" cabname\n" +" the name of the CAB file\n" +" files\n" +" a list of tuples, each containing the name of the file on disk,\n" +" and the name of the file inside the CAB file"); + +#define _MSI_FCICREATE_METHODDEF \ + {"FCICreate", (PyCFunction)(void(*)(void))_msi_FCICreate, METH_FASTCALL, _msi_FCICreate__doc__}, + +static PyObject * +_msi_FCICreate_impl(PyObject *module, const char *cabname, PyObject *files); + +static PyObject * +_msi_FCICreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *cabname; + PyObject *files; + + if (!_PyArg_CheckPositional("FCICreate", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("FCICreate", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t cabname_length; + cabname = PyUnicode_AsUTF8AndSize(args[0], &cabname_length); + if (cabname == NULL) { + goto exit; + } + if (strlen(cabname) != (size_t)cabname_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + files = args[1]; + return_value = _msi_FCICreate_impl(module, cabname, files); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_Database_Close__doc__, +"Close($self, /)\n" +"--\n" +"\n" +"Close the database object."); + +#define _MSI_DATABASE_CLOSE_METHODDEF \ + {"Close", (PyCFunction)_msi_Database_Close, METH_NOARGS, _msi_Database_Close__doc__}, + +static PyObject * +_msi_Database_Close_impl(msiobj *self); + +static PyObject * +_msi_Database_Close(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_Database_Close_impl(self); +} + +PyDoc_STRVAR(_msi_Record_GetFieldCount__doc__, +"GetFieldCount($self, /)\n" +"--\n" +"\n" +"Return the number of fields of the record."); + +#define _MSI_RECORD_GETFIELDCOUNT_METHODDEF \ + {"GetFieldCount", (PyCFunction)_msi_Record_GetFieldCount, METH_NOARGS, _msi_Record_GetFieldCount__doc__}, + +static PyObject * +_msi_Record_GetFieldCount_impl(msiobj *self); + +static PyObject * +_msi_Record_GetFieldCount(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_Record_GetFieldCount_impl(self); +} + +PyDoc_STRVAR(_msi_Record_GetInteger__doc__, +"GetInteger($self, field, /)\n" +"--\n" +"\n" +"Return the value of field as an integer where possible."); + +#define _MSI_RECORD_GETINTEGER_METHODDEF \ + {"GetInteger", (PyCFunction)_msi_Record_GetInteger, METH_O, _msi_Record_GetInteger__doc__}, + +static PyObject * +_msi_Record_GetInteger_impl(msiobj *self, unsigned int field); + +static PyObject * +_msi_Record_GetInteger(msiobj *self, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned int field; + + field = (unsigned int)PyLong_AsUnsignedLongMask(arg); + if (field == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_Record_GetInteger_impl(self, field); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_Record_GetString__doc__, +"GetString($self, field, /)\n" +"--\n" +"\n" +"Return the value of field as a string where possible."); + +#define _MSI_RECORD_GETSTRING_METHODDEF \ + {"GetString", (PyCFunction)_msi_Record_GetString, METH_O, _msi_Record_GetString__doc__}, + +static PyObject * +_msi_Record_GetString_impl(msiobj *self, unsigned int field); + +static PyObject * +_msi_Record_GetString(msiobj *self, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned int field; + + field = (unsigned int)PyLong_AsUnsignedLongMask(arg); + if (field == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_Record_GetString_impl(self, field); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_Record_ClearData__doc__, +"ClearData($self, /)\n" +"--\n" +"\n" +"Set all fields of the record to 0."); + +#define _MSI_RECORD_CLEARDATA_METHODDEF \ + {"ClearData", (PyCFunction)_msi_Record_ClearData, METH_NOARGS, _msi_Record_ClearData__doc__}, + +static PyObject * +_msi_Record_ClearData_impl(msiobj *self); + +static PyObject * +_msi_Record_ClearData(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_Record_ClearData_impl(self); +} + +PyDoc_STRVAR(_msi_Record_SetString__doc__, +"SetString($self, field, value, /)\n" +"--\n" +"\n" +"Set field to a string value."); + +#define _MSI_RECORD_SETSTRING_METHODDEF \ + {"SetString", (PyCFunction)(void(*)(void))_msi_Record_SetString, METH_FASTCALL, _msi_Record_SetString__doc__}, + +static PyObject * +_msi_Record_SetString_impl(msiobj *self, int field, const Py_UNICODE *value); + +static PyObject * +_msi_Record_SetString(msiobj *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int field; + const Py_UNICODE *value; + + if (!_PyArg_CheckPositional("SetString", nargs, 2, 2)) { + goto exit; + } + field = _PyLong_AsInt(args[0]); + if (field == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _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; + } + return_value = _msi_Record_SetString_impl(self, field, value); + +exit: + /* Cleanup for value */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)value); + #endif /* USE_UNICODE_WCHAR_CACHE */ + + return return_value; +} + +PyDoc_STRVAR(_msi_Record_SetStream__doc__, +"SetStream($self, field, value, /)\n" +"--\n" +"\n" +"Set field to the contents of the file named value."); + +#define _MSI_RECORD_SETSTREAM_METHODDEF \ + {"SetStream", (PyCFunction)(void(*)(void))_msi_Record_SetStream, METH_FASTCALL, _msi_Record_SetStream__doc__}, + +static PyObject * +_msi_Record_SetStream_impl(msiobj *self, int field, const Py_UNICODE *value); + +static PyObject * +_msi_Record_SetStream(msiobj *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int field; + const Py_UNICODE *value; + + if (!_PyArg_CheckPositional("SetStream", nargs, 2, 2)) { + goto exit; + } + field = _PyLong_AsInt(args[0]); + if (field == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _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; + } + return_value = _msi_Record_SetStream_impl(self, field, value); + +exit: + /* Cleanup for value */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)value); + #endif /* USE_UNICODE_WCHAR_CACHE */ + + return return_value; +} + +PyDoc_STRVAR(_msi_Record_SetInteger__doc__, +"SetInteger($self, field, value, /)\n" +"--\n" +"\n" +"Set field to an integer value."); + +#define _MSI_RECORD_SETINTEGER_METHODDEF \ + {"SetInteger", (PyCFunction)(void(*)(void))_msi_Record_SetInteger, METH_FASTCALL, _msi_Record_SetInteger__doc__}, + +static PyObject * +_msi_Record_SetInteger_impl(msiobj *self, int field, int value); + +static PyObject * +_msi_Record_SetInteger(msiobj *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int field; + int value; + + if (!_PyArg_CheckPositional("SetInteger", nargs, 2, 2)) { + goto exit; + } + field = _PyLong_AsInt(args[0]); + if (field == -1 && PyErr_Occurred()) { + goto exit; + } + value = _PyLong_AsInt(args[1]); + if (value == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_Record_SetInteger_impl(self, field, value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_SummaryInformation_GetProperty__doc__, +"GetProperty($self, field, /)\n" +"--\n" +"\n" +"Return a property of the summary.\n" +"\n" +" field\n" +" the name of the property, one of the PID_* constants"); + +#define _MSI_SUMMARYINFORMATION_GETPROPERTY_METHODDEF \ + {"GetProperty", (PyCFunction)_msi_SummaryInformation_GetProperty, METH_O, _msi_SummaryInformation_GetProperty__doc__}, + +static PyObject * +_msi_SummaryInformation_GetProperty_impl(msiobj *self, int field); + +static PyObject * +_msi_SummaryInformation_GetProperty(msiobj *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int field; + + field = _PyLong_AsInt(arg); + if (field == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_SummaryInformation_GetProperty_impl(self, field); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_SummaryInformation_GetPropertyCount__doc__, +"GetPropertyCount($self, /)\n" +"--\n" +"\n" +"Return the number of summary properties."); + +#define _MSI_SUMMARYINFORMATION_GETPROPERTYCOUNT_METHODDEF \ + {"GetPropertyCount", (PyCFunction)_msi_SummaryInformation_GetPropertyCount, METH_NOARGS, _msi_SummaryInformation_GetPropertyCount__doc__}, + +static PyObject * +_msi_SummaryInformation_GetPropertyCount_impl(msiobj *self); + +static PyObject * +_msi_SummaryInformation_GetPropertyCount(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_SummaryInformation_GetPropertyCount_impl(self); +} + +PyDoc_STRVAR(_msi_SummaryInformation_SetProperty__doc__, +"SetProperty($self, field, value, /)\n" +"--\n" +"\n" +"Set a property.\n" +"\n" +" field\n" +" the name of the property, one of the PID_* constants\n" +" value\n" +" the new value of the property (integer or string)"); + +#define _MSI_SUMMARYINFORMATION_SETPROPERTY_METHODDEF \ + {"SetProperty", (PyCFunction)(void(*)(void))_msi_SummaryInformation_SetProperty, METH_FASTCALL, _msi_SummaryInformation_SetProperty__doc__}, + +static PyObject * +_msi_SummaryInformation_SetProperty_impl(msiobj *self, int field, + PyObject *data); + +static PyObject * +_msi_SummaryInformation_SetProperty(msiobj *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int field; + PyObject *data; + + if (!_PyArg_CheckPositional("SetProperty", nargs, 2, 2)) { + goto exit; + } + field = _PyLong_AsInt(args[0]); + if (field == -1 && PyErr_Occurred()) { + goto exit; + } + data = args[1]; + return_value = _msi_SummaryInformation_SetProperty_impl(self, field, data); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_SummaryInformation_Persist__doc__, +"Persist($self, /)\n" +"--\n" +"\n" +"Write the modified properties to the summary information stream."); + +#define _MSI_SUMMARYINFORMATION_PERSIST_METHODDEF \ + {"Persist", (PyCFunction)_msi_SummaryInformation_Persist, METH_NOARGS, _msi_SummaryInformation_Persist__doc__}, + +static PyObject * +_msi_SummaryInformation_Persist_impl(msiobj *self); + +static PyObject * +_msi_SummaryInformation_Persist(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_SummaryInformation_Persist_impl(self); +} + +PyDoc_STRVAR(_msi_View_Execute__doc__, +"Execute($self, params, /)\n" +"--\n" +"\n" +"Execute the SQL query of the view.\n" +"\n" +" params\n" +" a record describing actual values of the parameter tokens\n" +" in the query or None"); + +#define _MSI_VIEW_EXECUTE_METHODDEF \ + {"Execute", (PyCFunction)_msi_View_Execute, METH_O, _msi_View_Execute__doc__}, + +PyDoc_STRVAR(_msi_View_Fetch__doc__, +"Fetch($self, /)\n" +"--\n" +"\n" +"Return a result record of the query."); + +#define _MSI_VIEW_FETCH_METHODDEF \ + {"Fetch", (PyCFunction)_msi_View_Fetch, METH_NOARGS, _msi_View_Fetch__doc__}, + +static PyObject * +_msi_View_Fetch_impl(msiobj *self); + +static PyObject * +_msi_View_Fetch(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_View_Fetch_impl(self); +} + +PyDoc_STRVAR(_msi_View_GetColumnInfo__doc__, +"GetColumnInfo($self, kind, /)\n" +"--\n" +"\n" +"Return a record describing the columns of the view.\n" +"\n" +" kind\n" +" MSICOLINFO_NAMES or MSICOLINFO_TYPES"); + +#define _MSI_VIEW_GETCOLUMNINFO_METHODDEF \ + {"GetColumnInfo", (PyCFunction)_msi_View_GetColumnInfo, METH_O, _msi_View_GetColumnInfo__doc__}, + +static PyObject * +_msi_View_GetColumnInfo_impl(msiobj *self, int kind); + +static PyObject * +_msi_View_GetColumnInfo(msiobj *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int kind; + + kind = _PyLong_AsInt(arg); + if (kind == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_View_GetColumnInfo_impl(self, kind); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_View_Modify__doc__, +"Modify($self, kind, data, /)\n" +"--\n" +"\n" +"Modify the view.\n" +"\n" +" kind\n" +" one of the MSIMODIFY_* constants\n" +" data\n" +" a record describing the new data"); + +#define _MSI_VIEW_MODIFY_METHODDEF \ + {"Modify", (PyCFunction)(void(*)(void))_msi_View_Modify, METH_FASTCALL, _msi_View_Modify__doc__}, + +static PyObject * +_msi_View_Modify_impl(msiobj *self, int kind, PyObject *data); + +static PyObject * +_msi_View_Modify(msiobj *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int kind; + PyObject *data; + + if (!_PyArg_CheckPositional("Modify", nargs, 2, 2)) { + goto exit; + } + kind = _PyLong_AsInt(args[0]); + if (kind == -1 && PyErr_Occurred()) { + goto exit; + } + data = args[1]; + return_value = _msi_View_Modify_impl(self, kind, data); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_View_Close__doc__, +"Close($self, /)\n" +"--\n" +"\n" +"Close the view."); + +#define _MSI_VIEW_CLOSE_METHODDEF \ + {"Close", (PyCFunction)_msi_View_Close, METH_NOARGS, _msi_View_Close__doc__}, + +static PyObject * +_msi_View_Close_impl(msiobj *self); + +static PyObject * +_msi_View_Close(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_View_Close_impl(self); +} + +PyDoc_STRVAR(_msi_Database_OpenView__doc__, +"OpenView($self, sql, /)\n" +"--\n" +"\n" +"Return a view object.\n" +"\n" +" sql\n" +" the SQL statement to execute"); + +#define _MSI_DATABASE_OPENVIEW_METHODDEF \ + {"OpenView", (PyCFunction)_msi_Database_OpenView, METH_O, _msi_Database_OpenView__doc__}, + +static PyObject * +_msi_Database_OpenView_impl(msiobj *self, const Py_UNICODE *sql); + +static PyObject * +_msi_Database_OpenView(msiobj *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const Py_UNICODE *sql; + + if (!PyUnicode_Check(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; + } + return_value = _msi_Database_OpenView_impl(self, sql); + +exit: + /* Cleanup for sql */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sql); + #endif /* USE_UNICODE_WCHAR_CACHE */ + + return return_value; +} + +PyDoc_STRVAR(_msi_Database_Commit__doc__, +"Commit($self, /)\n" +"--\n" +"\n" +"Commit the changes pending in the current transaction."); + +#define _MSI_DATABASE_COMMIT_METHODDEF \ + {"Commit", (PyCFunction)_msi_Database_Commit, METH_NOARGS, _msi_Database_Commit__doc__}, + +static PyObject * +_msi_Database_Commit_impl(msiobj *self); + +static PyObject * +_msi_Database_Commit(msiobj *self, PyObject *Py_UNUSED(ignored)) +{ + return _msi_Database_Commit_impl(self); +} + +PyDoc_STRVAR(_msi_Database_GetSummaryInformation__doc__, +"GetSummaryInformation($self, count, /)\n" +"--\n" +"\n" +"Return a new summary information object.\n" +"\n" +" count\n" +" the maximum number of updated values"); + +#define _MSI_DATABASE_GETSUMMARYINFORMATION_METHODDEF \ + {"GetSummaryInformation", (PyCFunction)_msi_Database_GetSummaryInformation, METH_O, _msi_Database_GetSummaryInformation__doc__}, + +static PyObject * +_msi_Database_GetSummaryInformation_impl(msiobj *self, int count); + +static PyObject * +_msi_Database_GetSummaryInformation(msiobj *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int count; + + count = _PyLong_AsInt(arg); + if (count == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_Database_GetSummaryInformation_impl(self, count); + +exit: + return return_value; +} + +PyDoc_STRVAR(_msi_OpenDatabase__doc__, +"OpenDatabase($module, path, persist, /)\n" +"--\n" +"\n" +"Return a new database object.\n" +"\n" +" path\n" +" the file name of the MSI file\n" +" persist\n" +" the persistence mode"); + +#define _MSI_OPENDATABASE_METHODDEF \ + {"OpenDatabase", (PyCFunction)(void(*)(void))_msi_OpenDatabase, METH_FASTCALL, _msi_OpenDatabase__doc__}, + +static PyObject * +_msi_OpenDatabase_impl(PyObject *module, const Py_UNICODE *path, int persist); + +static PyObject * +_msi_OpenDatabase(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const Py_UNICODE *path; + int persist; + + if (!_PyArg_CheckPositional("OpenDatabase", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _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; + } + persist = _PyLong_AsInt(args[1]); + if (persist == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_OpenDatabase_impl(module, path, persist); + +exit: + /* Cleanup for path */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)path); + #endif /* USE_UNICODE_WCHAR_CACHE */ + + return return_value; +} + +PyDoc_STRVAR(_msi_CreateRecord__doc__, +"CreateRecord($module, count, /)\n" +"--\n" +"\n" +"Return a new record object.\n" +"\n" +" count\n" +" the number of fields of the record"); + +#define _MSI_CREATERECORD_METHODDEF \ + {"CreateRecord", (PyCFunction)_msi_CreateRecord, METH_O, _msi_CreateRecord__doc__}, + +static PyObject * +_msi_CreateRecord_impl(PyObject *module, int count); + +static PyObject * +_msi_CreateRecord(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int count; + + count = _PyLong_AsInt(arg); + if (count == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _msi_CreateRecord_impl(module, count); + +exit: + return return_value; +} +/*[clinic end generated code: output=49debf733ee5cab2 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/PC/clinic/msvcrtmodule.c.h b/contrib/tools/python3/src/PC/clinic/msvcrtmodule.c.h index 180c3e5fc54..1ac82cb965b 100644 --- a/contrib/tools/python3/src/PC/clinic/msvcrtmodule.c.h +++ b/contrib/tools/python3/src/PC/clinic/msvcrtmodule.c.h @@ -53,29 +53,14 @@ msvcrt_locking(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("locking", nargs, 3, 3)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } nbytes = PyLong_AsLong(args[2]); if (nbytes == -1 && PyErr_Occurred()) { goto exit; @@ -114,20 +99,10 @@ msvcrt_setmode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setmode", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -201,11 +176,6 @@ msvcrt_get_osfhandle(PyObject *module, PyObject *arg) int fd; void *_return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; @@ -561,20 +531,10 @@ msvcrt_CrtSetReportMode(PyObject *module, PyObject *const *args, Py_ssize_t narg if (!_PyArg_CheckPositional("CrtSetReportMode", nargs, 2, 2)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } type = _PyLong_AsInt(args[0]); if (type == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -614,11 +574,6 @@ msvcrt_set_error_mode(PyObject *module, PyObject *arg) int mode; long _return_value; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = _PyLong_AsInt(arg); if (mode == -1 && PyErr_Occurred()) { goto exit; @@ -635,6 +590,24 @@ exit: #endif /* defined(_DEBUG) */ +PyDoc_STRVAR(msvcrt_GetErrorMode__doc__, +"GetErrorMode($module, /)\n" +"--\n" +"\n" +"Wrapper around GetErrorMode."); + +#define MSVCRT_GETERRORMODE_METHODDEF \ + {"GetErrorMode", (PyCFunction)msvcrt_GetErrorMode, METH_NOARGS, msvcrt_GetErrorMode__doc__}, + +static PyObject * +msvcrt_GetErrorMode_impl(PyObject *module); + +static PyObject * +msvcrt_GetErrorMode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return msvcrt_GetErrorMode_impl(module); +} + PyDoc_STRVAR(msvcrt_SetErrorMode__doc__, "SetErrorMode($module, mode, /)\n" "--\n" @@ -653,11 +626,6 @@ msvcrt_SetErrorMode(PyObject *module, PyObject *arg) PyObject *return_value = NULL; unsigned int mode; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } mode = (unsigned int)PyLong_AsUnsignedLongMask(arg); if (mode == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -679,4 +647,4 @@ 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=7cc6ffaf64f268f7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=20dfbc768edce7c0 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/PC/clinic/winreg.c.h b/contrib/tools/python3/src/PC/clinic/winreg.c.h index b7af1855ac5..183301f0618 100644 --- a/contrib/tools/python3/src/PC/clinic/winreg.c.h +++ b/contrib/tools/python3/src/PC/clinic/winreg.c.h @@ -152,8 +152,27 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs HKEY key; HKEY _return_value; - if (!_PyArg_ParseStack(args, nargs, "ZO&:ConnectRegistry", - &computer_name, clinic_HKEY_converter, &key)) { + if (!_PyArg_CheckPositional("ConnectRegistry", nargs, 2, 2)) { + goto exit; + } + if (args[0] == Py_None) { + 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; + } + } + else { + _PyArg_BadArgument("ConnectRegistry", "argument 1", "str or None", args[0]); + goto exit; + } + if (!clinic_HKEY_converter(args[1], &key)) { goto exit; } _return_value = winreg_ConnectRegistry_impl(module, computer_name, key); @@ -163,6 +182,11 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs return_value = PyHKEY_FromHKEY(_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; } @@ -199,8 +223,27 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const Py_UNICODE *sub_key; HKEY _return_value; - if (!_PyArg_ParseStack(args, nargs, "O&Z:CreateKey", - clinic_HKEY_converter, &key, &sub_key)) { + if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(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; + } + } + else { + _PyArg_BadArgument("CreateKey", "argument 2", "str or None", args[1]); goto exit; } _return_value = winreg_CreateKey_impl(module, key, sub_key); @@ -210,6 +253,11 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return_value = PyHKEY_FromHKEY(_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; } @@ -251,7 +299,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&Z|ii:CreateKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:CreateKeyEx", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; int reserved = 0; @@ -259,7 +307,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py HKEY _return_value; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { goto exit; } _return_value = winreg_CreateKeyEx_impl(module, key, sub_key, reserved, access); @@ -269,6 +317,11 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py return_value = PyHKEY_FromHKEY(_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; } @@ -303,13 +356,32 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *sub_key; - if (!_PyArg_ParseStack(args, nargs, "O&u:DeleteKey", - clinic_HKEY_converter, &key, &sub_key)) { + if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(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; } return_value = winreg_DeleteKey_impl(module, key, sub_key); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -351,19 +423,24 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL}; - static _PyArg_Parser _parser = {"O&u|ii:DeleteKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:DeleteKeyEx", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; REGSAM access = KEY_WOW64_64KEY; int reserved = 0; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &access, &reserved)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Converter, &sub_key, &access, &reserved)) { goto exit; } 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; } @@ -391,13 +468,37 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *value; - if (!_PyArg_ParseStack(args, nargs, "O&Z:DeleteValue", - clinic_HKEY_converter, &key, &value)) { + if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(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; + } + } + else { + _PyArg_BadArgument("DeleteValue", "argument 2", "str or None", args[1]); goto exit; } return_value = winreg_DeleteValue_impl(module, key, value); exit: + /* Cleanup for value */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)value); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -435,11 +536,6 @@ winreg_EnumKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!clinic_HKEY_converter(args[0], &key)) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } index = _PyLong_AsInt(args[1]); if (index == -1 && PyErr_Occurred()) { goto exit; @@ -493,11 +589,6 @@ winreg_EnumValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!clinic_HKEY_converter(args[0], &key)) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } index = _PyLong_AsInt(args[1]); if (index == -1 && PyErr_Occurred()) { goto exit; @@ -527,12 +618,26 @@ winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg) PyObject *return_value = NULL; const Py_UNICODE *string; - if (!PyArg_Parse(arg, "u:ExpandEnvironmentStrings", &string)) { + if (!PyUnicode_Check(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; } return_value = winreg_ExpandEnvironmentStrings_impl(module, string); exit: + /* Cleanup for string */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)string); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -619,13 +724,48 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const Py_UNICODE *sub_key; const Py_UNICODE *file_name; - if (!_PyArg_ParseStack(args, nargs, "O&uu:LoadKey", - clinic_HKEY_converter, &key, &sub_key, &file_name)) { + if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) { + goto exit; + } + if (!clinic_HKEY_converter(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; + } + if (!PyUnicode_Check(args[2])) { + _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; } return_value = winreg_LoadKey_impl(module, key, sub_key, file_name); 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; } @@ -660,7 +800,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&Z|ii:OpenKey", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:OpenKey", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; int reserved = 0; @@ -668,7 +808,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje HKEY _return_value; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { goto exit; } _return_value = winreg_OpenKey_impl(module, key, sub_key, reserved, access); @@ -678,6 +818,11 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje return_value = PyHKEY_FromHKEY(_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; } @@ -712,7 +857,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&Z|ii:OpenKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:OpenKeyEx", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; int reserved = 0; @@ -720,7 +865,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb HKEY _return_value; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { goto exit; } _return_value = winreg_OpenKeyEx_impl(module, key, sub_key, reserved, access); @@ -730,6 +875,11 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb return_value = PyHKEY_FromHKEY(_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; } @@ -802,13 +952,37 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *sub_key; - if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValue", - clinic_HKEY_converter, &key, &sub_key)) { + if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(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; + } + } + else { + _PyArg_BadArgument("QueryValue", "argument 2", "str or None", args[1]); goto exit; } return_value = winreg_QueryValue_impl(module, key, sub_key); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -841,13 +1015,37 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *name; - if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValueEx", - clinic_HKEY_converter, &key, &name)) { + if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(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; + } + } + else { + _PyArg_BadArgument("QueryValueEx", "argument 2", "str or None", args[1]); goto exit; } return_value = winreg_QueryValueEx_impl(module, key, name); exit: + /* Cleanup for name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -885,13 +1083,32 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *file_name; - if (!_PyArg_ParseStack(args, nargs, "O&u:SaveKey", - clinic_HKEY_converter, &key, &file_name)) { + if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(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; } return_value = winreg_SaveKey_impl(module, key, file_name); exit: + /* Cleanup for file_name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)file_name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -926,8 +1143,7 @@ PyDoc_STRVAR(winreg_SetValue__doc__, static PyObject * winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, - DWORD type, const Py_UNICODE *value, - Py_ssize_clean_t value_length); + DWORD type, PyObject *value_obj); static PyObject * winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) @@ -936,16 +1152,20 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *sub_key; DWORD type; - const Py_UNICODE *value; - Py_ssize_clean_t value_length; + PyObject *value_obj; - if (!_PyArg_ParseStack(args, nargs, "O&Zku#:SetValue", - clinic_HKEY_converter, &key, &sub_key, &type, &value, &value_length)) { + if (!_PyArg_ParseStack(args, nargs, "O&O&kU:SetValue", + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &type, &value_obj)) { goto exit; } - return_value = winreg_SetValue_impl(module, key, sub_key, type, value, value_length); + 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; } @@ -1010,13 +1230,18 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) DWORD type; PyObject *value; - if (!_PyArg_ParseStack(args, nargs, "O&ZOkO:SetValueEx", - clinic_HKEY_converter, &key, &value_name, &reserved, &type, &value)) { + if (!_PyArg_ParseStack(args, nargs, "O&O&OkO:SetValueEx", + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &value_name, &reserved, &type, &value)) { goto exit; } 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; } @@ -1121,4 +1346,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=015afbbd690eb59d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=497a2e804821d5c9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/PC/clinic/winsound.c.h b/contrib/tools/python3/src/PC/clinic/winsound.c.h index b37db4c6cbc..c5458990baa 100644 --- a/contrib/tools/python3/src/PC/clinic/winsound.c.h +++ b/contrib/tools/python3/src/PC/clinic/winsound.c.h @@ -34,11 +34,6 @@ winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto exit; } sound = args[0]; - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -81,20 +76,10 @@ winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } frequency = _PyLong_AsInt(args[0]); if (frequency == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } duration = _PyLong_AsInt(args[1]); if (duration == -1 && PyErr_Occurred()) { goto exit; @@ -136,11 +121,6 @@ winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } type = _PyLong_AsInt(args[0]); if (type == -1 && PyErr_Occurred()) { goto exit; @@ -151,4 +131,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=28d1cd033282723d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=16b3c1a96861cd3a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/PC/msvcrtmodule.c b/contrib/tools/python3/src/PC/msvcrtmodule.c index faceb03fba3..0591497871c 100644 --- a/contrib/tools/python3/src/PC/msvcrtmodule.c +++ b/contrib/tools/python3/src/PC/msvcrtmodule.c @@ -177,19 +177,11 @@ static long msvcrt_open_osfhandle_impl(PyObject *module, void *handle, int flags) /*[clinic end generated code: output=b2fb97c4b515e4e6 input=d5db190a307cf4bb]*/ { - int fd; - if (PySys_Audit("msvcrt.open_osfhandle", "Ki", handle, flags) < 0) { return -1; } - _Py_BEGIN_SUPPRESS_IPH - fd = _open_osfhandle((intptr_t)handle, flags); - _Py_END_SUPPRESS_IPH - if (fd == -1) - PyErr_SetFromErrno(PyExc_OSError); - - return fd; + return _Py_open_osfhandle(handle, flags); } /*[clinic input] @@ -207,19 +199,11 @@ static void * msvcrt_get_osfhandle_impl(PyObject *module, int fd) /*[clinic end generated code: output=aca01dfe24637374 input=5fcfde9b17136aa2]*/ { - intptr_t handle = -1; - if (PySys_Audit("msvcrt.get_osfhandle", "(i)", fd) < 0) { return NULL; } - _Py_BEGIN_SUPPRESS_IPH - handle = _get_osfhandle(fd); - _Py_END_SUPPRESS_IPH - if (handle == -1) - PyErr_SetFromErrno(PyExc_OSError); - - return (HANDLE)handle; + return _Py_get_osfhandle(fd); } /* Console I/O */ @@ -482,6 +466,25 @@ msvcrt_set_error_mode_impl(PyObject *module, int mode) } #endif /* _DEBUG */ +/*[clinic input] +msvcrt.GetErrorMode + +Wrapper around GetErrorMode. +[clinic start generated code]*/ + +static PyObject * +msvcrt_GetErrorMode_impl(PyObject *module) +/*[clinic end generated code: output=3103fc6145913591 input=5a7fb083b6dd71fd]*/ +{ + unsigned int res; + + _Py_BEGIN_SUPPRESS_IPH + res = GetErrorMode(); + _Py_END_SUPPRESS_IPH + + return PyLong_FromUnsignedLong(res); +} + /*[clinic input] msvcrt.SetErrorMode @@ -520,6 +523,7 @@ static struct PyMethodDef msvcrt_functions[] = { MSVCRT_GETCHE_METHODDEF MSVCRT_PUTCH_METHODDEF MSVCRT_UNGETCH_METHODDEF + MSVCRT_GETERRORMODE_METHODDEF MSVCRT_SETERRORMODE_METHODDEF MSVCRT_CRTSETREPORTFILE_METHODDEF MSVCRT_CRTSETREPORTMODE_METHODDEF diff --git a/contrib/tools/python3/src/PC/pyconfig.h b/contrib/tools/python3/src/PC/pyconfig.h index b53ae107e5b..1987a1237a5 100644 --- a/contrib/tools/python3/src/PC/pyconfig.h +++ b/contrib/tools/python3/src/PC/pyconfig.h @@ -165,11 +165,11 @@ WIN32 is still required for the locale module. /* Define like size_t, omitting the "unsigned" */ #ifdef MS_WIN64 -typedef __int64 ssize_t; +typedef __int64 Py_ssize_t; #else -typedef _W64 int ssize_t; +typedef _W64 int Py_ssize_t; #endif -#define HAVE_SSIZE_T 1 +#define HAVE_PY_SSIZE_T 1 #if defined(MS_WIN32) && !defined(MS_WIN64) #if defined(_M_IX86) @@ -268,11 +268,11 @@ 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,"python39_d.lib") +# pragma comment(lib,"python310_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else -# pragma comment(lib,"python39.lib") +# pragma comment(lib,"python310.lib") # endif /* _DEBUG */ # endif /* _MSC_VER */ # endif /* Py_BUILD_CORE */ @@ -289,6 +289,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ # define SIZEOF_FPOS_T 8 # define SIZEOF_HKEY 8 # define SIZEOF_SIZE_T 8 +# define ALIGNOF_SIZE_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 @@ -303,6 +304,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ # define SIZEOF_FPOS_T 8 # define SIZEOF_HKEY 4 # define SIZEOF_SIZE_T 4 +# define ALIGNOF_SIZE_T 4 /* MS VS2005 changes time_t to a 64-bit type on all platforms */ # if defined(_MSC_VER) && _MSC_VER >= 1400 # define SIZEOF_TIME_T 8 @@ -317,6 +319,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ #define SIZEOF_SHORT 2 #define SIZEOF_INT 4 #define SIZEOF_LONG 4 +#define ALIGNOF_LONG 4 #define SIZEOF_LONG_LONG 8 #define SIZEOF_DOUBLE 8 #define SIZEOF_FLOAT 4 diff --git a/contrib/tools/python3/src/PC/winreg.c b/contrib/tools/python3/src/PC/winreg.c index fd1ccb7b83e..004a89a5355 100644 --- a/contrib/tools/python3/src/PC/winreg.c +++ b/contrib/tools/python3/src/PC/winreg.c @@ -14,6 +14,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" // _PyObject_Init() #include "structmember.h" // PyMemberDef #include @@ -111,7 +112,7 @@ typedef struct { HKEY hkey; } PyHKEYObject; -#define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type) +#define PyHKEY_Check(op) Py_IS_TYPE(op, &PyHKEY_Type) static char *failMsg = "bad operand type"; @@ -144,7 +145,7 @@ PyHKEY_deallocFunc(PyObject *ob) PyHKEYObject *obkey = (PyHKEYObject *)ob; if (obkey->hkey) RegCloseKey((HKEY)obkey->hkey); - PyObject_DEL(ob); + PyObject_Free(ob); } static int @@ -457,13 +458,12 @@ clinic_HKEY_converter(PyObject *ob, void *p) PyObject * PyHKEY_FromHKEY(HKEY h) { - PyHKEYObject *op; - /* Inline PyObject_New */ - op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject)); - if (op == NULL) + PyHKEYObject *op = (PyHKEYObject *) PyObject_Malloc(sizeof(PyHKEYObject)); + if (op == NULL) { return PyErr_NoMemory(); - PyObject_INIT(op, &PyHKEY_Type); + } + _PyObject_Init((PyObject*)op, &PyHKEY_Type); op->hkey = h; return (PyObject *)op; } @@ -640,19 +640,25 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) for (j = 0; j < i; j++) { PyObject *t; - wchar_t *wstr; Py_ssize_t len; 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 - wstr = PyUnicode_AsUnicodeAndSize(t, &len); + len = PyUnicode_GetSize(t); + if (len < 0) + return FALSE; + len++; _Py_COMP_DIAG_POP - if (wstr == NULL) +#else /* USE_UNICODE_WCHAR_CACHE */ + len = PyUnicode_AsWideChar(t, NULL, 0); + if (len < 0) return FALSE; - size += Py_SAFE_DOWNCAST((len + 1) * sizeof(wchar_t), +#endif /* USE_UNICODE_WCHAR_CACHE */ + size += Py_SAFE_DOWNCAST(len * sizeof(wchar_t), size_t, DWORD); } @@ -668,20 +674,18 @@ _Py_COMP_DIAG_POP for (j = 0; j < i; j++) { PyObject *t; - wchar_t *wstr; Py_ssize_t len; t = PyList_GET_ITEM(value, j); -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wstr = PyUnicode_AsUnicodeAndSize(t, &len); -_Py_COMP_DIAG_POP - assert(wstr); - wcscpy(P, wstr); - P += (len + 1); + assert(size > 0); + len = PyUnicode_AsWideChar(t, P, size); + assert(len >= 0); + assert((unsigned)len < size); + size -= (DWORD)len + 1; + P += len + 1; } /* And doubly-terminate the list... */ - *P = '\0'; + *P = L'\0'; break; } case REG_BINARY: @@ -699,7 +703,7 @@ _Py_COMP_DIAG_POP PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not " "be used as binary registry values", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return FALSE; } @@ -1675,7 +1679,7 @@ winreg.SetValue type: DWORD An integer that specifies the type of the data. Currently this must be REG_SZ, meaning only strings are supported. - value: Py_UNICODE(zeroes=True) + value as value_obj: unicode A string that specifies the new value. / @@ -1694,30 +1698,51 @@ KEY_SET_VALUE access. static PyObject * winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, - DWORD type, const Py_UNICODE *value, - Py_ssize_clean_t value_length) -/*[clinic end generated code: output=686bedb1cbb4367b input=2cd2adab79339c53]*/ + DWORD type, PyObject *value_obj) +/*[clinic end generated code: output=d4773dc9c372311a input=bf088494ae2d24fd]*/ { + Py_ssize_t value_length; long rc; if (type != REG_SZ) { PyErr_SetString(PyExc_TypeError, "type must be winreg.REG_SZ"); return NULL; } - if ((size_t)value_length >= PY_DWORD_MAX) { + +#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 */ + if (value == NULL) { + return NULL; + } + if ((Py_ssize_t)(DWORD)value_length != value_length) { PyErr_SetString(PyExc_OverflowError, "value is too long"); +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(value); +#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } 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; } Py_BEGIN_ALLOW_THREADS rc = RegSetValueW(key, sub_key, REG_SZ, value, (DWORD)(value_length + 1)); Py_END_ALLOW_THREADS +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(value); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); Py_RETURN_NONE; @@ -1794,7 +1819,7 @@ winreg_SetValueEx_impl(PyObject *module, HKEY key, Py_BEGIN_ALLOW_THREADS rc = RegSetValueExW(key, value_name, 0, type, data, len); Py_END_ALLOW_THREADS - PyMem_DEL(data); + PyMem_Free(data); if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValueEx"); diff --git a/contrib/tools/python3/src/Parser/acceler.c b/contrib/tools/python3/src/Parser/acceler.c deleted file mode 100644 index e515833e1dd..00000000000 --- a/contrib/tools/python3/src/Parser/acceler.c +++ /dev/null @@ -1,123 +0,0 @@ - -/* Parser accelerator module */ - -/* The parser as originally conceived had disappointing performance. - This module does some precomputation that speeds up the selection - of a DFA based upon a token, turning a search through an array - into a simple indexing operation. The parser now cannot work - without the accelerators installed. Note that the accelerators - are installed dynamically when the parser is initialized, they - are not part of the static data structure written on graminit.[ch] - by the parser generator. */ - -#include "Python.h" -#include "grammar.h" -#include "node.h" -#include "token.h" -#include "parser.h" - -/* Forward references */ -static void fixdfa(grammar *, const dfa *); -static void fixstate(grammar *, state *); - -void -PyGrammar_AddAccelerators(grammar *g) -{ - int i; - const dfa *d = g->g_dfa; - for (i = g->g_ndfas; --i >= 0; d++) - fixdfa(g, d); - g->g_accel = 1; -} - -void -PyGrammar_RemoveAccelerators(grammar *g) -{ - int i; - g->g_accel = 0; - const dfa *d = g->g_dfa; - for (i = g->g_ndfas; --i >= 0; d++) { - state *s; - int j; - s = d->d_state; - for (j = 0; j < d->d_nstates; j++, s++) { - if (s->s_accel) - PyObject_FREE(s->s_accel); - s->s_accel = NULL; - } - } -} - -static void -fixdfa(grammar *g, const dfa *d) -{ - state *s; - int j; - s = d->d_state; - for (j = 0; j < d->d_nstates; j++, s++) - fixstate(g, s); -} - -static void -fixstate(grammar *g, state *s) -{ - const arc *a; - int k; - int *accel; - int nl = g->g_ll.ll_nlabels; - s->s_accept = 0; - accel = (int *) PyObject_MALLOC(nl * sizeof(int)); - if (accel == NULL) { - fprintf(stderr, "no mem to build parser accelerators\n"); - exit(1); - } - for (k = 0; k < nl; k++) - accel[k] = -1; - a = s->s_arc; - for (k = s->s_narcs; --k >= 0; a++) { - int lbl = a->a_lbl; - const label *l = &g->g_ll.ll_label[lbl]; - int type = l->lb_type; - if (a->a_arrow >= (1 << 7)) { - printf("XXX too many states!\n"); - continue; - } - if (ISNONTERMINAL(type)) { - const dfa *d1 = PyGrammar_FindDFA(g, type); - int ibit; - if (type - NT_OFFSET >= (1 << 7)) { - printf("XXX too high nonterminal number!\n"); - continue; - } - for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) { - if (testbit(d1->d_first, ibit)) { - if (accel[ibit] != -1) - printf("XXX ambiguity!\n"); - accel[ibit] = a->a_arrow | (1 << 7) | - ((type - NT_OFFSET) << 8); - } - } - } - else if (lbl == EMPTY) - s->s_accept = 1; - else if (lbl >= 0 && lbl < nl) - accel[lbl] = a->a_arrow; - } - while (nl > 0 && accel[nl-1] == -1) - nl--; - for (k = 0; k < nl && accel[k] == -1;) - k++; - if (k < nl) { - int i; - s->s_accel = (int *) PyObject_MALLOC((nl-k) * sizeof(int)); - if (s->s_accel == NULL) { - fprintf(stderr, "no mem to add parser accelerators\n"); - exit(1); - } - s->s_lower = k; - s->s_upper = nl; - for (i = 0; k < nl; i++, k++) - s->s_accel[i] = accel[k]; - } - PyObject_FREE(accel); -} diff --git a/contrib/tools/python3/src/Parser/grammar1.c b/contrib/tools/python3/src/Parser/grammar1.c deleted file mode 100644 index c702040efdf..00000000000 --- a/contrib/tools/python3/src/Parser/grammar1.c +++ /dev/null @@ -1,47 +0,0 @@ - -/* Grammar subroutines needed by parser */ - -#include "Python.h" -#include "grammar.h" -#include "token.h" - -/* Return the DFA for the given type */ - -const dfa * -PyGrammar_FindDFA(grammar *g, int type) -{ - /* Massive speed-up */ - const dfa *d = &g->g_dfa[type - NT_OFFSET]; - assert(d->d_type == type); - return d; -} - -const char * -PyGrammar_LabelRepr(label *lb) -{ - static char buf[100]; - - if (lb->lb_type == ENDMARKER) - return "EMPTY"; - else if (ISNONTERMINAL(lb->lb_type)) { - if (lb->lb_str == NULL) { - PyOS_snprintf(buf, sizeof(buf), "NT%d", lb->lb_type); - return buf; - } - else - return lb->lb_str; - } - else if (lb->lb_type < N_TOKENS) { - if (lb->lb_str == NULL) - return _PyParser_TokenNames[lb->lb_type]; - else { - PyOS_snprintf(buf, sizeof(buf), "%.32s(%.32s)", - _PyParser_TokenNames[lb->lb_type], lb->lb_str); - return buf; - } - } - else { - Py_FatalError("invalid grammar label"); - return NULL; - } -} diff --git a/contrib/tools/python3/src/Parser/listnode.c b/contrib/tools/python3/src/Parser/listnode.c deleted file mode 100644 index c806b98e48c..00000000000 --- a/contrib/tools/python3/src/Parser/listnode.c +++ /dev/null @@ -1,71 +0,0 @@ - -/* List a node on a file */ - -#include "Python.h" -#include "pycore_interp.h" // PyInterpreterState.parser -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "token.h" -#include "node.h" - -/* Forward */ -static void list1node(FILE *, node *); -static void listnode(FILE *, node *); - -void -PyNode_ListTree(node *n) -{ - listnode(stdout, n); -} - -static void -listnode(FILE *fp, node *n) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - - interp->parser.listnode.level = 0; - interp->parser.listnode.atbol = 1; - list1node(fp, n); -} - -static void -list1node(FILE *fp, node *n) -{ - PyInterpreterState *interp; - - if (n == NULL) - return; - if (ISNONTERMINAL(TYPE(n))) { - int i; - for (i = 0; i < NCH(n); i++) - list1node(fp, CHILD(n, i)); - } - else if (ISTERMINAL(TYPE(n))) { - interp = _PyInterpreterState_GET(); - switch (TYPE(n)) { - case INDENT: - interp->parser.listnode.level++; - break; - case DEDENT: - interp->parser.listnode.level--; - break; - default: - if (interp->parser.listnode.atbol) { - int i; - for (i = 0; i < interp->parser.listnode.level; ++i) - fprintf(fp, "\t"); - interp->parser.listnode.atbol = 0; - } - if (TYPE(n) == NEWLINE) { - if (STR(n) != NULL) - fprintf(fp, "%s", STR(n)); - fprintf(fp, "\n"); - interp->parser.listnode.atbol = 1; - } - else - fprintf(fp, "%s ", STR(n)); - break; - } - } - else - fprintf(fp, "? "); -} diff --git a/contrib/tools/python3/src/Parser/myreadline.c b/contrib/tools/python3/src/Parser/myreadline.c index 143b41f1eab..e5e2fb1099d 100644 --- a/contrib/tools/python3/src/Parser/myreadline.c +++ b/contrib/tools/python3/src/Parser/myreadline.c @@ -249,10 +249,8 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) { HANDLE hStdIn, hStdErr; - _Py_BEGIN_SUPPRESS_IPH - hStdIn = (HANDLE)_get_osfhandle(fileno(sys_stdin)); - hStdErr = (HANDLE)_get_osfhandle(fileno(stderr)); - _Py_END_SUPPRESS_IPH + hStdIn = _Py_get_osfhandle_noraise(fileno(sys_stdin)); + hStdErr = _Py_get_osfhandle_noraise(fileno(stderr)); if (_get_console_type(hStdIn) == 'r') { fflush(sys_stdout); diff --git a/contrib/tools/python3/src/Parser/node.c b/contrib/tools/python3/src/Parser/node.c deleted file mode 100644 index 8789e01e9b8..00000000000 --- a/contrib/tools/python3/src/Parser/node.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Parse tree node implementation */ - -#include "Python.h" -#include "node.h" -#include "errcode.h" - -node * -PyNode_New(int type) -{ - node *n = (node *) PyObject_MALLOC(1 * sizeof(node)); - if (n == NULL) - return NULL; - n->n_type = type; - n->n_str = NULL; - n->n_lineno = 0; - n->n_end_lineno = 0; - n->n_col_offset = 0; - n->n_end_col_offset = -1; - n->n_nchildren = 0; - n->n_child = NULL; - return n; -} - -/* See comments at XXXROUNDUP below. Returns -1 on overflow. */ -static int -fancy_roundup(int n) -{ - /* Round up to the closest power of 2 >= n. */ - int result = 256; - assert(n > 128); - while (result < n) { - result <<= 1; - if (result <= 0) - return -1; - } - return result; -} - -/* A gimmick to make massive numbers of reallocs quicker. The result is - * a number >= the input. In PyNode_AddChild, it's used like so, when - * we're about to add child number current_size + 1: - * - * if XXXROUNDUP(current_size) < XXXROUNDUP(current_size + 1): - * allocate space for XXXROUNDUP(current_size + 1) total children - * else: - * we already have enough space - * - * Since a node starts out empty, we must have - * - * XXXROUNDUP(0) < XXXROUNDUP(1) - * - * so that we allocate space for the first child. One-child nodes are very - * common (presumably that would change if we used a more abstract form - * of syntax tree), so to avoid wasting memory it's desirable that - * XXXROUNDUP(1) == 1. That in turn forces XXXROUNDUP(0) == 0. - * - * Else for 2 <= n <= 128, we round up to the closest multiple of 4. Why 4? - * Rounding up to a multiple of an exact power of 2 is very efficient, and - * most nodes with more than one child have <= 4 kids. - * - * Else we call fancy_roundup() to grow proportionately to n. We've got an - * extreme case then (like test_longexp.py), and on many platforms doing - * anything less than proportional growth leads to exorbitant runtime - * (e.g., MacPython), or extreme fragmentation of user address space (e.g., - * Win98). - * - * In a run of compileall across the 2.3a0 Lib directory, Andrew MacIntyre - * reported that, with this scheme, 89% of PyObject_REALLOC calls in - * PyNode_AddChild passed 1 for the size, and 9% passed 4. So this usually - * wastes very little memory, but is very effective at sidestepping - * platform-realloc disasters on vulnerable platforms. - * - * Note that this would be straightforward if a node stored its current - * capacity. The code is tricky to avoid that. - */ -#define XXXROUNDUP(n) ((n) <= 1 ? (n) : \ - (n) <= 128 ? (int)_Py_SIZE_ROUND_UP((n), 4) : \ - fancy_roundup(n)) - - -void -_PyNode_FinalizeEndPos(node *n) -{ - int nch = NCH(n); - node *last; - if (nch == 0) { - return; - } - last = CHILD(n, nch - 1); - _PyNode_FinalizeEndPos(last); - n->n_end_lineno = last->n_end_lineno; - n->n_end_col_offset = last->n_end_col_offset; -} - -int -PyNode_AddChild(node *n1, int type, char *str, int lineno, int col_offset, - int end_lineno, int end_col_offset) -{ - const int nch = n1->n_nchildren; - int current_capacity; - int required_capacity; - node *n; - - // finalize end position of previous node (if any) - if (nch > 0) { - _PyNode_FinalizeEndPos(CHILD(n1, nch - 1)); - } - - if (nch == INT_MAX || nch < 0) - return E_OVERFLOW; - - current_capacity = XXXROUNDUP(nch); - required_capacity = XXXROUNDUP(nch + 1); - if (current_capacity < 0 || required_capacity < 0) - return E_OVERFLOW; - if (current_capacity < required_capacity) { - if ((size_t)required_capacity > SIZE_MAX / sizeof(node)) { - return E_NOMEM; - } - n = n1->n_child; - n = (node *) PyObject_REALLOC(n, - required_capacity * sizeof(node)); - if (n == NULL) - return E_NOMEM; - n1->n_child = n; - } - - n = &n1->n_child[n1->n_nchildren++]; - n->n_type = type; - n->n_str = str; - n->n_lineno = lineno; - n->n_col_offset = col_offset; - n->n_end_lineno = end_lineno; // this and below will be updates after all children are added. - n->n_end_col_offset = end_col_offset; - n->n_nchildren = 0; - n->n_child = NULL; - return 0; -} - -/* Forward */ -static void freechildren(node *); -static Py_ssize_t sizeofchildren(node *n); - - -void -PyNode_Free(node *n) -{ - if (n != NULL) { - freechildren(n); - PyObject_FREE(n); - } -} - -Py_ssize_t -_PyNode_SizeOf(node *n) -{ - Py_ssize_t res = 0; - - if (n != NULL) - res = sizeof(node) + sizeofchildren(n); - return res; -} - -static void -freechildren(node *n) -{ - int i; - for (i = NCH(n); --i >= 0; ) - freechildren(CHILD(n, i)); - if (n->n_child != NULL) - PyObject_FREE(n->n_child); - if (STR(n) != NULL) - PyObject_FREE(STR(n)); -} - -static Py_ssize_t -sizeofchildren(node *n) -{ - Py_ssize_t res = 0; - int i; - for (i = NCH(n); --i >= 0; ) - res += sizeofchildren(CHILD(n, i)); - if (n->n_child != NULL) - /* allocated size of n->n_child array */ - res += XXXROUNDUP(NCH(n)) * sizeof(node); - if (STR(n) != NULL) - res += strlen(STR(n)) + 1; - return res; -} diff --git a/contrib/tools/python3/src/Parser/parser.c b/contrib/tools/python3/src/Parser/parser.c index a61b2f5ebf7..3f73003b789 100644 --- a/contrib/tools/python3/src/Parser/parser.c +++ b/contrib/tools/python3/src/Parser/parser.c @@ -1,463 +1,34520 @@ +// @generated by pegen.py from python.gram +#include "pegen.h" -/* Parser implementation */ +#if defined(Py_DEBUG) && defined(Py_BUILD_CORE) +# define D(x) if (Py_DebugFlag) x; +#else +# define D(x) +#endif + +# define MAXSTACK 6000 +static const int n_keyword_lists = 9; +static KeywordToken *reserved_keywords[] = { + (KeywordToken[]) {{NULL, -1}}, + (KeywordToken[]) {{NULL, -1}}, + (KeywordToken[]) { + {"if", 510}, + {"in", 518}, + {"as", 520}, + {"is", 530}, + {"or", 531}, + {NULL, -1}, + }, + (KeywordToken[]) { + {"del", 503}, + {"try", 511}, + {"for", 517}, + {"def", 526}, + {"not", 529}, + {"and", 532}, + {NULL, -1}, + }, + (KeywordToken[]) { + {"pass", 502}, + {"from", 514}, + {"elif", 515}, + {"else", 516}, + {"with", 519}, + {"None", 523}, + {"True", 524}, + {NULL, -1}, + }, + (KeywordToken[]) { + {"raise", 501}, + {"yield", 504}, + {"break", 506}, + {"while", 512}, + {"False", 525}, + {"class", 527}, + {NULL, -1}, + }, + (KeywordToken[]) { + {"return", 500}, + {"assert", 505}, + {"global", 508}, + {"import", 513}, + {"except", 521}, + {"lambda", 528}, + {NULL, -1}, + }, + (KeywordToken[]) { + {"finally", 522}, + {NULL, -1}, + }, + (KeywordToken[]) { + {"continue", 507}, + {"nonlocal", 509}, + {NULL, -1}, + }, +}; +static char *soft_keywords[] = { + "_", + "case", + "match", + NULL, +}; +#define file_type 1000 +#define interactive_type 1001 +#define eval_type 1002 +#define func_type_type 1003 +#define fstring_type 1004 +#define type_expressions_type 1005 +#define statements_type 1006 +#define statement_type 1007 +#define statement_newline_type 1008 +#define simple_stmts_type 1009 +#define simple_stmt_type 1010 +#define compound_stmt_type 1011 +#define assignment_type 1012 +#define augassign_type 1013 +#define global_stmt_type 1014 +#define nonlocal_stmt_type 1015 +#define yield_stmt_type 1016 +#define assert_stmt_type 1017 +#define del_stmt_type 1018 +#define import_stmt_type 1019 +#define import_name_type 1020 +#define import_from_type 1021 +#define import_from_targets_type 1022 +#define import_from_as_names_type 1023 +#define import_from_as_name_type 1024 +#define dotted_as_names_type 1025 +#define dotted_as_name_type 1026 +#define dotted_name_type 1027 // Left-recursive +#define if_stmt_type 1028 +#define elif_stmt_type 1029 +#define else_block_type 1030 +#define while_stmt_type 1031 +#define for_stmt_type 1032 +#define with_stmt_type 1033 +#define with_item_type 1034 +#define try_stmt_type 1035 +#define except_block_type 1036 +#define finally_block_type 1037 +#define match_stmt_type 1038 +#define subject_expr_type 1039 +#define case_block_type 1040 +#define guard_type 1041 +#define patterns_type 1042 +#define pattern_type 1043 +#define as_pattern_type 1044 +#define or_pattern_type 1045 +#define closed_pattern_type 1046 +#define literal_pattern_type 1047 +#define literal_expr_type 1048 +#define complex_number_type 1049 +#define signed_number_type 1050 +#define signed_real_number_type 1051 +#define real_number_type 1052 +#define imaginary_number_type 1053 +#define capture_pattern_type 1054 +#define pattern_capture_target_type 1055 +#define wildcard_pattern_type 1056 +#define value_pattern_type 1057 +#define attr_type 1058 // Left-recursive +#define name_or_attr_type 1059 // Left-recursive +#define group_pattern_type 1060 +#define sequence_pattern_type 1061 +#define open_sequence_pattern_type 1062 +#define maybe_sequence_pattern_type 1063 +#define maybe_star_pattern_type 1064 +#define star_pattern_type 1065 +#define mapping_pattern_type 1066 +#define items_pattern_type 1067 +#define key_value_pattern_type 1068 +#define double_star_pattern_type 1069 +#define class_pattern_type 1070 +#define positional_patterns_type 1071 +#define keyword_patterns_type 1072 +#define keyword_pattern_type 1073 +#define return_stmt_type 1074 +#define raise_stmt_type 1075 +#define function_def_type 1076 +#define function_def_raw_type 1077 +#define func_type_comment_type 1078 +#define params_type 1079 +#define parameters_type 1080 +#define slash_no_default_type 1081 +#define slash_with_default_type 1082 +#define star_etc_type 1083 +#define kwds_type 1084 +#define param_no_default_type 1085 +#define param_with_default_type 1086 +#define param_maybe_default_type 1087 +#define param_type 1088 +#define annotation_type 1089 +#define default_type 1090 +#define decorators_type 1091 +#define class_def_type 1092 +#define class_def_raw_type 1093 +#define block_type 1094 +#define star_expressions_type 1095 +#define star_expression_type 1096 +#define star_named_expressions_type 1097 +#define star_named_expression_type 1098 +#define assignment_expression_type 1099 +#define named_expression_type 1100 +#define annotated_rhs_type 1101 +#define expressions_type 1102 +#define expression_type 1103 +#define lambdef_type 1104 +#define lambda_params_type 1105 +#define lambda_parameters_type 1106 +#define lambda_slash_no_default_type 1107 +#define lambda_slash_with_default_type 1108 +#define lambda_star_etc_type 1109 +#define lambda_kwds_type 1110 +#define lambda_param_no_default_type 1111 +#define lambda_param_with_default_type 1112 +#define lambda_param_maybe_default_type 1113 +#define lambda_param_type 1114 +#define disjunction_type 1115 +#define conjunction_type 1116 +#define inversion_type 1117 +#define comparison_type 1118 +#define compare_op_bitwise_or_pair_type 1119 +#define eq_bitwise_or_type 1120 +#define noteq_bitwise_or_type 1121 +#define lte_bitwise_or_type 1122 +#define lt_bitwise_or_type 1123 +#define gte_bitwise_or_type 1124 +#define gt_bitwise_or_type 1125 +#define notin_bitwise_or_type 1126 +#define in_bitwise_or_type 1127 +#define isnot_bitwise_or_type 1128 +#define is_bitwise_or_type 1129 +#define bitwise_or_type 1130 // Left-recursive +#define bitwise_xor_type 1131 // Left-recursive +#define bitwise_and_type 1132 // Left-recursive +#define shift_expr_type 1133 // Left-recursive +#define sum_type 1134 // Left-recursive +#define term_type 1135 // Left-recursive +#define factor_type 1136 +#define power_type 1137 +#define await_primary_type 1138 +#define primary_type 1139 // Left-recursive +#define slices_type 1140 +#define slice_type 1141 +#define atom_type 1142 +#define strings_type 1143 +#define list_type 1144 +#define listcomp_type 1145 +#define tuple_type 1146 +#define group_type 1147 +#define genexp_type 1148 +#define set_type 1149 +#define setcomp_type 1150 +#define dict_type 1151 +#define dictcomp_type 1152 +#define double_starred_kvpairs_type 1153 +#define double_starred_kvpair_type 1154 +#define kvpair_type 1155 +#define for_if_clauses_type 1156 +#define for_if_clause_type 1157 +#define yield_expr_type 1158 +#define arguments_type 1159 +#define args_type 1160 +#define kwargs_type 1161 +#define starred_expression_type 1162 +#define kwarg_or_starred_type 1163 +#define kwarg_or_double_starred_type 1164 +#define star_targets_type 1165 +#define star_targets_list_seq_type 1166 +#define star_targets_tuple_seq_type 1167 +#define star_target_type 1168 +#define target_with_star_atom_type 1169 +#define star_atom_type 1170 +#define single_target_type 1171 +#define single_subscript_attribute_target_type 1172 +#define del_targets_type 1173 +#define del_target_type 1174 +#define del_t_atom_type 1175 +#define t_primary_type 1176 // Left-recursive +#define t_lookahead_type 1177 +#define invalid_arguments_type 1178 +#define invalid_kwarg_type 1179 +#define expression_without_invalid_type 1180 +#define invalid_legacy_expression_type 1181 +#define invalid_expression_type 1182 +#define invalid_named_expression_type 1183 +#define invalid_assignment_type 1184 +#define invalid_ann_assign_target_type 1185 +#define invalid_del_stmt_type 1186 +#define invalid_block_type 1187 +#define invalid_comprehension_type 1188 +#define invalid_dict_comprehension_type 1189 +#define invalid_parameters_type 1190 +#define invalid_parameters_helper_type 1191 +#define invalid_lambda_parameters_type 1192 +#define invalid_lambda_parameters_helper_type 1193 +#define invalid_star_etc_type 1194 +#define invalid_lambda_star_etc_type 1195 +#define invalid_double_type_comments_type 1196 +#define invalid_with_item_type 1197 +#define invalid_for_target_type 1198 +#define invalid_group_type 1199 +#define invalid_import_from_targets_type 1200 +#define invalid_with_stmt_type 1201 +#define invalid_with_stmt_indent_type 1202 +#define invalid_try_stmt_type 1203 +#define invalid_except_stmt_type 1204 +#define invalid_finally_stmt_type 1205 +#define invalid_except_stmt_indent_type 1206 +#define invalid_match_stmt_type 1207 +#define invalid_case_block_type 1208 +#define invalid_as_pattern_type 1209 +#define invalid_class_pattern_type 1210 +#define invalid_class_argument_pattern_type 1211 +#define invalid_if_stmt_type 1212 +#define invalid_elif_stmt_type 1213 +#define invalid_else_stmt_type 1214 +#define invalid_while_stmt_type 1215 +#define invalid_for_stmt_type 1216 +#define invalid_def_raw_type 1217 +#define invalid_class_def_raw_type 1218 +#define invalid_double_starred_kvpairs_type 1219 +#define invalid_kvpair_type 1220 +#define _loop0_1_type 1221 +#define _loop0_2_type 1222 +#define _loop0_4_type 1223 +#define _gather_3_type 1224 +#define _loop0_6_type 1225 +#define _gather_5_type 1226 +#define _loop0_8_type 1227 +#define _gather_7_type 1228 +#define _loop0_10_type 1229 +#define _gather_9_type 1230 +#define _loop1_11_type 1231 +#define _loop0_13_type 1232 +#define _gather_12_type 1233 +#define _tmp_14_type 1234 +#define _tmp_15_type 1235 +#define _tmp_16_type 1236 +#define _tmp_17_type 1237 +#define _tmp_18_type 1238 +#define _tmp_19_type 1239 +#define _tmp_20_type 1240 +#define _tmp_21_type 1241 +#define _loop1_22_type 1242 +#define _tmp_23_type 1243 +#define _tmp_24_type 1244 +#define _loop0_26_type 1245 +#define _gather_25_type 1246 +#define _loop0_28_type 1247 +#define _gather_27_type 1248 +#define _tmp_29_type 1249 +#define _tmp_30_type 1250 +#define _loop0_31_type 1251 +#define _loop1_32_type 1252 +#define _loop0_34_type 1253 +#define _gather_33_type 1254 +#define _tmp_35_type 1255 +#define _loop0_37_type 1256 +#define _gather_36_type 1257 +#define _tmp_38_type 1258 +#define _loop0_40_type 1259 +#define _gather_39_type 1260 +#define _loop0_42_type 1261 +#define _gather_41_type 1262 +#define _loop0_44_type 1263 +#define _gather_43_type 1264 +#define _loop0_46_type 1265 +#define _gather_45_type 1266 +#define _tmp_47_type 1267 +#define _loop1_48_type 1268 +#define _tmp_49_type 1269 +#define _loop1_50_type 1270 +#define _loop0_52_type 1271 +#define _gather_51_type 1272 +#define _tmp_53_type 1273 +#define _tmp_54_type 1274 +#define _tmp_55_type 1275 +#define _tmp_56_type 1276 +#define _loop0_58_type 1277 +#define _gather_57_type 1278 +#define _loop0_60_type 1279 +#define _gather_59_type 1280 +#define _tmp_61_type 1281 +#define _loop0_63_type 1282 +#define _gather_62_type 1283 +#define _loop0_65_type 1284 +#define _gather_64_type 1285 +#define _tmp_66_type 1286 +#define _tmp_67_type 1287 +#define _tmp_68_type 1288 +#define _tmp_69_type 1289 +#define _loop0_70_type 1290 +#define _loop0_71_type 1291 +#define _loop0_72_type 1292 +#define _loop1_73_type 1293 +#define _loop0_74_type 1294 +#define _loop1_75_type 1295 +#define _loop1_76_type 1296 +#define _loop1_77_type 1297 +#define _loop0_78_type 1298 +#define _loop1_79_type 1299 +#define _loop0_80_type 1300 +#define _loop1_81_type 1301 +#define _loop0_82_type 1302 +#define _loop1_83_type 1303 +#define _loop1_84_type 1304 +#define _tmp_85_type 1305 +#define _loop1_86_type 1306 +#define _loop0_88_type 1307 +#define _gather_87_type 1308 +#define _loop1_89_type 1309 +#define _loop0_90_type 1310 +#define _loop0_91_type 1311 +#define _loop0_92_type 1312 +#define _loop1_93_type 1313 +#define _loop0_94_type 1314 +#define _loop1_95_type 1315 +#define _loop1_96_type 1316 +#define _loop1_97_type 1317 +#define _loop0_98_type 1318 +#define _loop1_99_type 1319 +#define _loop0_100_type 1320 +#define _loop1_101_type 1321 +#define _loop0_102_type 1322 +#define _loop1_103_type 1323 +#define _loop1_104_type 1324 +#define _loop1_105_type 1325 +#define _loop1_106_type 1326 +#define _tmp_107_type 1327 +#define _loop0_109_type 1328 +#define _gather_108_type 1329 +#define _tmp_110_type 1330 +#define _tmp_111_type 1331 +#define _tmp_112_type 1332 +#define _tmp_113_type 1333 +#define _loop1_114_type 1334 +#define _tmp_115_type 1335 +#define _tmp_116_type 1336 +#define _tmp_117_type 1337 +#define _loop0_119_type 1338 +#define _gather_118_type 1339 +#define _loop1_120_type 1340 +#define _loop0_121_type 1341 +#define _loop0_122_type 1342 +#define _loop0_124_type 1343 +#define _gather_123_type 1344 +#define _tmp_125_type 1345 +#define _loop0_127_type 1346 +#define _gather_126_type 1347 +#define _loop0_129_type 1348 +#define _gather_128_type 1349 +#define _loop0_131_type 1350 +#define _gather_130_type 1351 +#define _loop0_133_type 1352 +#define _gather_132_type 1353 +#define _loop0_134_type 1354 +#define _loop0_136_type 1355 +#define _gather_135_type 1356 +#define _loop1_137_type 1357 +#define _tmp_138_type 1358 +#define _loop0_140_type 1359 +#define _gather_139_type 1360 +#define _tmp_141_type 1361 +#define _tmp_142_type 1362 +#define _tmp_143_type 1363 +#define _tmp_144_type 1364 +#define _tmp_145_type 1365 +#define _tmp_146_type 1366 +#define _tmp_147_type 1367 +#define _tmp_148_type 1368 +#define _loop0_149_type 1369 +#define _loop0_150_type 1370 +#define _loop0_151_type 1371 +#define _tmp_152_type 1372 +#define _tmp_153_type 1373 +#define _tmp_154_type 1374 +#define _tmp_155_type 1375 +#define _loop0_156_type 1376 +#define _loop1_157_type 1377 +#define _loop0_158_type 1378 +#define _loop1_159_type 1379 +#define _tmp_160_type 1380 +#define _tmp_161_type 1381 +#define _tmp_162_type 1382 +#define _loop0_164_type 1383 +#define _gather_163_type 1384 +#define _loop0_166_type 1385 +#define _gather_165_type 1386 +#define _loop0_168_type 1387 +#define _gather_167_type 1388 +#define _loop0_170_type 1389 +#define _gather_169_type 1390 +#define _tmp_171_type 1391 +#define _tmp_172_type 1392 +#define _tmp_173_type 1393 +#define _tmp_174_type 1394 +#define _tmp_175_type 1395 +#define _tmp_176_type 1396 +#define _tmp_177_type 1397 +#define _loop0_179_type 1398 +#define _gather_178_type 1399 +#define _tmp_180_type 1400 +#define _tmp_181_type 1401 +#define _tmp_182_type 1402 +#define _tmp_183_type 1403 +#define _tmp_184_type 1404 +#define _tmp_185_type 1405 +#define _tmp_186_type 1406 +#define _tmp_187_type 1407 +#define _tmp_188_type 1408 +#define _tmp_189_type 1409 +#define _tmp_190_type 1410 +#define _tmp_191_type 1411 +#define _tmp_192_type 1412 +#define _tmp_193_type 1413 +#define _tmp_194_type 1414 +#define _tmp_195_type 1415 +#define _tmp_196_type 1416 +#define _tmp_197_type 1417 +#define _tmp_198_type 1418 +#define _tmp_199_type 1419 +#define _tmp_200_type 1420 +#define _tmp_201_type 1421 +#define _tmp_202_type 1422 +#define _tmp_203_type 1423 +#define _tmp_204_type 1424 +#define _tmp_205_type 1425 +#define _tmp_206_type 1426 + +static mod_ty file_rule(Parser *p); +static mod_ty interactive_rule(Parser *p); +static mod_ty eval_rule(Parser *p); +static mod_ty func_type_rule(Parser *p); +static expr_ty fstring_rule(Parser *p); +static asdl_expr_seq* type_expressions_rule(Parser *p); +static asdl_stmt_seq* statements_rule(Parser *p); +static asdl_stmt_seq* statement_rule(Parser *p); +static asdl_stmt_seq* statement_newline_rule(Parser *p); +static asdl_stmt_seq* simple_stmts_rule(Parser *p); +static stmt_ty simple_stmt_rule(Parser *p); +static stmt_ty compound_stmt_rule(Parser *p); +static stmt_ty assignment_rule(Parser *p); +static AugOperator* augassign_rule(Parser *p); +static stmt_ty global_stmt_rule(Parser *p); +static stmt_ty nonlocal_stmt_rule(Parser *p); +static stmt_ty yield_stmt_rule(Parser *p); +static stmt_ty assert_stmt_rule(Parser *p); +static stmt_ty del_stmt_rule(Parser *p); +static stmt_ty import_stmt_rule(Parser *p); +static stmt_ty import_name_rule(Parser *p); +static stmt_ty import_from_rule(Parser *p); +static asdl_alias_seq* import_from_targets_rule(Parser *p); +static asdl_alias_seq* import_from_as_names_rule(Parser *p); +static alias_ty import_from_as_name_rule(Parser *p); +static asdl_alias_seq* dotted_as_names_rule(Parser *p); +static alias_ty dotted_as_name_rule(Parser *p); +static expr_ty dotted_name_rule(Parser *p); +static stmt_ty if_stmt_rule(Parser *p); +static stmt_ty elif_stmt_rule(Parser *p); +static asdl_stmt_seq* else_block_rule(Parser *p); +static stmt_ty while_stmt_rule(Parser *p); +static stmt_ty for_stmt_rule(Parser *p); +static stmt_ty with_stmt_rule(Parser *p); +static withitem_ty with_item_rule(Parser *p); +static stmt_ty try_stmt_rule(Parser *p); +static excepthandler_ty except_block_rule(Parser *p); +static asdl_stmt_seq* finally_block_rule(Parser *p); +static stmt_ty match_stmt_rule(Parser *p); +static expr_ty subject_expr_rule(Parser *p); +static match_case_ty case_block_rule(Parser *p); +static expr_ty guard_rule(Parser *p); +static pattern_ty patterns_rule(Parser *p); +static pattern_ty pattern_rule(Parser *p); +static pattern_ty as_pattern_rule(Parser *p); +static pattern_ty or_pattern_rule(Parser *p); +static pattern_ty closed_pattern_rule(Parser *p); +static pattern_ty literal_pattern_rule(Parser *p); +static expr_ty literal_expr_rule(Parser *p); +static expr_ty complex_number_rule(Parser *p); +static expr_ty signed_number_rule(Parser *p); +static expr_ty signed_real_number_rule(Parser *p); +static expr_ty real_number_rule(Parser *p); +static expr_ty imaginary_number_rule(Parser *p); +static pattern_ty capture_pattern_rule(Parser *p); +static expr_ty pattern_capture_target_rule(Parser *p); +static pattern_ty wildcard_pattern_rule(Parser *p); +static pattern_ty value_pattern_rule(Parser *p); +static expr_ty attr_rule(Parser *p); +static expr_ty name_or_attr_rule(Parser *p); +static pattern_ty group_pattern_rule(Parser *p); +static pattern_ty sequence_pattern_rule(Parser *p); +static asdl_seq* open_sequence_pattern_rule(Parser *p); +static asdl_seq* maybe_sequence_pattern_rule(Parser *p); +static pattern_ty maybe_star_pattern_rule(Parser *p); +static pattern_ty star_pattern_rule(Parser *p); +static pattern_ty mapping_pattern_rule(Parser *p); +static asdl_seq* items_pattern_rule(Parser *p); +static KeyPatternPair* key_value_pattern_rule(Parser *p); +static expr_ty double_star_pattern_rule(Parser *p); +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 return_stmt_rule(Parser *p); +static stmt_ty raise_stmt_rule(Parser *p); +static stmt_ty function_def_rule(Parser *p); +static stmt_ty function_def_raw_rule(Parser *p); +static Token* func_type_comment_rule(Parser *p); +static arguments_ty params_rule(Parser *p); +static arguments_ty parameters_rule(Parser *p); +static asdl_arg_seq* slash_no_default_rule(Parser *p); +static SlashWithDefault* slash_with_default_rule(Parser *p); +static StarEtc* star_etc_rule(Parser *p); +static arg_ty kwds_rule(Parser *p); +static arg_ty param_no_default_rule(Parser *p); +static NameDefaultPair* param_with_default_rule(Parser *p); +static NameDefaultPair* param_maybe_default_rule(Parser *p); +static arg_ty param_rule(Parser *p); +static expr_ty annotation_rule(Parser *p); +static expr_ty default_rule(Parser *p); +static asdl_expr_seq* decorators_rule(Parser *p); +static stmt_ty class_def_rule(Parser *p); +static stmt_ty class_def_raw_rule(Parser *p); +static asdl_stmt_seq* block_rule(Parser *p); +static expr_ty star_expressions_rule(Parser *p); +static expr_ty star_expression_rule(Parser *p); +static asdl_expr_seq* star_named_expressions_rule(Parser *p); +static expr_ty star_named_expression_rule(Parser *p); +static expr_ty assignment_expression_rule(Parser *p); +static expr_ty named_expression_rule(Parser *p); +static expr_ty annotated_rhs_rule(Parser *p); +static expr_ty expressions_rule(Parser *p); +static expr_ty expression_rule(Parser *p); +static expr_ty lambdef_rule(Parser *p); +static arguments_ty lambda_params_rule(Parser *p); +static arguments_ty lambda_parameters_rule(Parser *p); +static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p); +static SlashWithDefault* lambda_slash_with_default_rule(Parser *p); +static StarEtc* lambda_star_etc_rule(Parser *p); +static arg_ty lambda_kwds_rule(Parser *p); +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 disjunction_rule(Parser *p); +static expr_ty conjunction_rule(Parser *p); +static expr_ty inversion_rule(Parser *p); +static expr_ty comparison_rule(Parser *p); +static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p); +static CmpopExprPair* eq_bitwise_or_rule(Parser *p); +static CmpopExprPair* noteq_bitwise_or_rule(Parser *p); +static CmpopExprPair* lte_bitwise_or_rule(Parser *p); +static CmpopExprPair* lt_bitwise_or_rule(Parser *p); +static CmpopExprPair* gte_bitwise_or_rule(Parser *p); +static CmpopExprPair* gt_bitwise_or_rule(Parser *p); +static CmpopExprPair* notin_bitwise_or_rule(Parser *p); +static CmpopExprPair* in_bitwise_or_rule(Parser *p); +static CmpopExprPair* isnot_bitwise_or_rule(Parser *p); +static CmpopExprPair* is_bitwise_or_rule(Parser *p); +static expr_ty bitwise_or_rule(Parser *p); +static expr_ty bitwise_xor_rule(Parser *p); +static expr_ty bitwise_and_rule(Parser *p); +static expr_ty shift_expr_rule(Parser *p); +static expr_ty sum_rule(Parser *p); +static expr_ty term_rule(Parser *p); +static expr_ty factor_rule(Parser *p); +static expr_ty power_rule(Parser *p); +static expr_ty await_primary_rule(Parser *p); +static expr_ty primary_rule(Parser *p); +static expr_ty slices_rule(Parser *p); +static expr_ty slice_rule(Parser *p); +static expr_ty atom_rule(Parser *p); +static expr_ty strings_rule(Parser *p); +static expr_ty list_rule(Parser *p); +static expr_ty listcomp_rule(Parser *p); +static expr_ty tuple_rule(Parser *p); +static expr_ty group_rule(Parser *p); +static expr_ty genexp_rule(Parser *p); +static expr_ty set_rule(Parser *p); +static expr_ty setcomp_rule(Parser *p); +static expr_ty dict_rule(Parser *p); +static expr_ty dictcomp_rule(Parser *p); +static asdl_seq* double_starred_kvpairs_rule(Parser *p); +static KeyValuePair* double_starred_kvpair_rule(Parser *p); +static KeyValuePair* kvpair_rule(Parser *p); +static asdl_comprehension_seq* for_if_clauses_rule(Parser *p); +static comprehension_ty for_if_clause_rule(Parser *p); +static expr_ty yield_expr_rule(Parser *p); +static expr_ty arguments_rule(Parser *p); +static expr_ty args_rule(Parser *p); +static asdl_seq* kwargs_rule(Parser *p); +static expr_ty starred_expression_rule(Parser *p); +static KeywordOrStarred* kwarg_or_starred_rule(Parser *p); +static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p); +static expr_ty star_targets_rule(Parser *p); +static asdl_expr_seq* star_targets_list_seq_rule(Parser *p); +static asdl_expr_seq* star_targets_tuple_seq_rule(Parser *p); +static expr_ty star_target_rule(Parser *p); +static expr_ty target_with_star_atom_rule(Parser *p); +static expr_ty star_atom_rule(Parser *p); +static expr_ty single_target_rule(Parser *p); +static expr_ty single_subscript_attribute_target_rule(Parser *p); +static asdl_expr_seq* del_targets_rule(Parser *p); +static expr_ty del_target_rule(Parser *p); +static expr_ty del_t_atom_rule(Parser *p); +static expr_ty t_primary_rule(Parser *p); +static void *t_lookahead_rule(Parser *p); +static void *invalid_arguments_rule(Parser *p); +static void *invalid_kwarg_rule(Parser *p); +static expr_ty expression_without_invalid_rule(Parser *p); +static void *invalid_legacy_expression_rule(Parser *p); +static void *invalid_expression_rule(Parser *p); +static void *invalid_named_expression_rule(Parser *p); +static void *invalid_assignment_rule(Parser *p); +static expr_ty invalid_ann_assign_target_rule(Parser *p); +static void *invalid_del_stmt_rule(Parser *p); +static void *invalid_block_rule(Parser *p); +static void *invalid_comprehension_rule(Parser *p); +static void *invalid_dict_comprehension_rule(Parser *p); +static void *invalid_parameters_rule(Parser *p); +static void *invalid_parameters_helper_rule(Parser *p); +static void *invalid_lambda_parameters_rule(Parser *p); +static void *invalid_lambda_parameters_helper_rule(Parser *p); +static void *invalid_star_etc_rule(Parser *p); +static void *invalid_lambda_star_etc_rule(Parser *p); +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_from_targets_rule(Parser *p); +static void *invalid_with_stmt_rule(Parser *p); +static void *invalid_with_stmt_indent_rule(Parser *p); +static void *invalid_try_stmt_rule(Parser *p); +static void *invalid_except_stmt_rule(Parser *p); +static void *invalid_finally_stmt_rule(Parser *p); +static void *invalid_except_stmt_indent_rule(Parser *p); +static void *invalid_match_stmt_rule(Parser *p); +static void *invalid_case_block_rule(Parser *p); +static void *invalid_as_pattern_rule(Parser *p); +static void *invalid_class_pattern_rule(Parser *p); +static asdl_pattern_seq* invalid_class_argument_pattern_rule(Parser *p); +static void *invalid_if_stmt_rule(Parser *p); +static void *invalid_elif_stmt_rule(Parser *p); +static void *invalid_else_stmt_rule(Parser *p); +static void *invalid_while_stmt_rule(Parser *p); +static void *invalid_for_stmt_rule(Parser *p); +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 asdl_seq *_loop0_1_rule(Parser *p); +static asdl_seq *_loop0_2_rule(Parser *p); +static asdl_seq *_loop0_4_rule(Parser *p); +static asdl_seq *_gather_3_rule(Parser *p); +static asdl_seq *_loop0_6_rule(Parser *p); +static asdl_seq *_gather_5_rule(Parser *p); +static asdl_seq *_loop0_8_rule(Parser *p); +static asdl_seq *_gather_7_rule(Parser *p); +static asdl_seq *_loop0_10_rule(Parser *p); +static asdl_seq *_gather_9_rule(Parser *p); +static asdl_seq *_loop1_11_rule(Parser *p); +static asdl_seq *_loop0_13_rule(Parser *p); +static asdl_seq *_gather_12_rule(Parser *p); +static void *_tmp_14_rule(Parser *p); +static void *_tmp_15_rule(Parser *p); +static void *_tmp_16_rule(Parser *p); +static void *_tmp_17_rule(Parser *p); +static void *_tmp_18_rule(Parser *p); +static void *_tmp_19_rule(Parser *p); +static void *_tmp_20_rule(Parser *p); +static void *_tmp_21_rule(Parser *p); +static asdl_seq *_loop1_22_rule(Parser *p); +static void *_tmp_23_rule(Parser *p); +static void *_tmp_24_rule(Parser *p); +static asdl_seq *_loop0_26_rule(Parser *p); +static asdl_seq *_gather_25_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 void *_tmp_30_rule(Parser *p); +static asdl_seq *_loop0_31_rule(Parser *p); +static asdl_seq *_loop1_32_rule(Parser *p); +static asdl_seq *_loop0_34_rule(Parser *p); +static asdl_seq *_gather_33_rule(Parser *p); +static void *_tmp_35_rule(Parser *p); +static asdl_seq *_loop0_37_rule(Parser *p); +static asdl_seq *_gather_36_rule(Parser *p); +static void *_tmp_38_rule(Parser *p); +static asdl_seq *_loop0_40_rule(Parser *p); +static asdl_seq *_gather_39_rule(Parser *p); +static asdl_seq *_loop0_42_rule(Parser *p); +static asdl_seq *_gather_41_rule(Parser *p); +static asdl_seq *_loop0_44_rule(Parser *p); +static asdl_seq *_gather_43_rule(Parser *p); +static asdl_seq *_loop0_46_rule(Parser *p); +static asdl_seq *_gather_45_rule(Parser *p); +static void *_tmp_47_rule(Parser *p); +static asdl_seq *_loop1_48_rule(Parser *p); +static void *_tmp_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 void *_tmp_53_rule(Parser *p); +static void *_tmp_54_rule(Parser *p); +static void *_tmp_55_rule(Parser *p); +static void *_tmp_56_rule(Parser *p); +static asdl_seq *_loop0_58_rule(Parser *p); +static asdl_seq *_gather_57_rule(Parser *p); +static asdl_seq *_loop0_60_rule(Parser *p); +static asdl_seq *_gather_59_rule(Parser *p); +static void *_tmp_61_rule(Parser *p); +static asdl_seq *_loop0_63_rule(Parser *p); +static asdl_seq *_gather_62_rule(Parser *p); +static asdl_seq *_loop0_65_rule(Parser *p); +static asdl_seq *_gather_64_rule(Parser *p); +static void *_tmp_66_rule(Parser *p); +static void *_tmp_67_rule(Parser *p); +static void *_tmp_68_rule(Parser *p); +static void *_tmp_69_rule(Parser *p); +static asdl_seq *_loop0_70_rule(Parser *p); +static asdl_seq *_loop0_71_rule(Parser *p); +static asdl_seq *_loop0_72_rule(Parser *p); +static asdl_seq *_loop1_73_rule(Parser *p); +static asdl_seq *_loop0_74_rule(Parser *p); +static asdl_seq *_loop1_75_rule(Parser *p); +static asdl_seq *_loop1_76_rule(Parser *p); +static asdl_seq *_loop1_77_rule(Parser *p); +static asdl_seq *_loop0_78_rule(Parser *p); +static asdl_seq *_loop1_79_rule(Parser *p); +static asdl_seq *_loop0_80_rule(Parser *p); +static asdl_seq *_loop1_81_rule(Parser *p); +static asdl_seq *_loop0_82_rule(Parser *p); +static asdl_seq *_loop1_83_rule(Parser *p); +static asdl_seq *_loop1_84_rule(Parser *p); +static void *_tmp_85_rule(Parser *p); +static asdl_seq *_loop1_86_rule(Parser *p); +static asdl_seq *_loop0_88_rule(Parser *p); +static asdl_seq *_gather_87_rule(Parser *p); +static asdl_seq *_loop1_89_rule(Parser *p); +static asdl_seq *_loop0_90_rule(Parser *p); +static asdl_seq *_loop0_91_rule(Parser *p); +static asdl_seq *_loop0_92_rule(Parser *p); +static asdl_seq *_loop1_93_rule(Parser *p); +static asdl_seq *_loop0_94_rule(Parser *p); +static asdl_seq *_loop1_95_rule(Parser *p); +static asdl_seq *_loop1_96_rule(Parser *p); +static asdl_seq *_loop1_97_rule(Parser *p); +static asdl_seq *_loop0_98_rule(Parser *p); +static asdl_seq *_loop1_99_rule(Parser *p); +static asdl_seq *_loop0_100_rule(Parser *p); +static asdl_seq *_loop1_101_rule(Parser *p); +static asdl_seq *_loop0_102_rule(Parser *p); +static asdl_seq *_loop1_103_rule(Parser *p); +static asdl_seq *_loop1_104_rule(Parser *p); +static asdl_seq *_loop1_105_rule(Parser *p); +static asdl_seq *_loop1_106_rule(Parser *p); +static void *_tmp_107_rule(Parser *p); +static asdl_seq *_loop0_109_rule(Parser *p); +static asdl_seq *_gather_108_rule(Parser *p); +static void *_tmp_110_rule(Parser *p); +static void *_tmp_111_rule(Parser *p); +static void *_tmp_112_rule(Parser *p); +static void *_tmp_113_rule(Parser *p); +static asdl_seq *_loop1_114_rule(Parser *p); +static void *_tmp_115_rule(Parser *p); +static void *_tmp_116_rule(Parser *p); +static void *_tmp_117_rule(Parser *p); +static asdl_seq *_loop0_119_rule(Parser *p); +static asdl_seq *_gather_118_rule(Parser *p); +static asdl_seq *_loop1_120_rule(Parser *p); +static asdl_seq *_loop0_121_rule(Parser *p); +static asdl_seq *_loop0_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_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 *_loop0_136_rule(Parser *p); +static asdl_seq *_gather_135_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 void *_tmp_141_rule(Parser *p); +static void *_tmp_142_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_149_rule(Parser *p); +static asdl_seq *_loop0_150_rule(Parser *p); +static asdl_seq *_loop0_151_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 asdl_seq *_loop0_156_rule(Parser *p); +static asdl_seq *_loop1_157_rule(Parser *p); +static asdl_seq *_loop0_158_rule(Parser *p); +static asdl_seq *_loop1_159_rule(Parser *p); +static void *_tmp_160_rule(Parser *p); +static void *_tmp_161_rule(Parser *p); +static void *_tmp_162_rule(Parser *p); +static asdl_seq *_loop0_164_rule(Parser *p); +static asdl_seq *_gather_163_rule(Parser *p); +static asdl_seq *_loop0_166_rule(Parser *p); +static asdl_seq *_gather_165_rule(Parser *p); +static asdl_seq *_loop0_168_rule(Parser *p); +static asdl_seq *_gather_167_rule(Parser *p); +static asdl_seq *_loop0_170_rule(Parser *p); +static asdl_seq *_gather_169_rule(Parser *p); +static void *_tmp_171_rule(Parser *p); +static void *_tmp_172_rule(Parser *p); +static void *_tmp_173_rule(Parser *p); +static void *_tmp_174_rule(Parser *p); +static void *_tmp_175_rule(Parser *p); +static void *_tmp_176_rule(Parser *p); +static void *_tmp_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 void *_tmp_181_rule(Parser *p); +static void *_tmp_182_rule(Parser *p); +static void *_tmp_183_rule(Parser *p); +static void *_tmp_184_rule(Parser *p); +static void *_tmp_185_rule(Parser *p); +static void *_tmp_186_rule(Parser *p); +static void *_tmp_187_rule(Parser *p); +static void *_tmp_188_rule(Parser *p); +static void *_tmp_189_rule(Parser *p); +static void *_tmp_190_rule(Parser *p); +static void *_tmp_191_rule(Parser *p); +static void *_tmp_192_rule(Parser *p); +static void *_tmp_193_rule(Parser *p); +static void *_tmp_194_rule(Parser *p); +static void *_tmp_195_rule(Parser *p); +static void *_tmp_196_rule(Parser *p); +static void *_tmp_197_rule(Parser *p); +static void *_tmp_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 void *_tmp_202_rule(Parser *p); +static void *_tmp_203_rule(Parser *p); +static void *_tmp_204_rule(Parser *p); +static void *_tmp_205_rule(Parser *p); +static void *_tmp_206_rule(Parser *p); + + +// file: statements? $ +static mod_ty +file_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + mod_ty _res = NULL; + int _mark = p->mark; + { // statements? $ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> file[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statements? $")); + void *a; + Token * endmarker_var; + if ( + (a = statements_rule(p), !p->error_indicator) // statements? + && + (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' + ) + { + D(fprintf(stderr, "%*c+ file[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statements? $")); + _res = _PyPegen_make_module ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s file[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statements? $")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// interactive: statement_newline +static mod_ty +interactive_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + mod_ty _res = NULL; + int _mark = p->mark; + { // statement_newline + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> interactive[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement_newline")); + asdl_stmt_seq* a; + if ( + (a = statement_newline_rule(p)) // statement_newline + ) + { + D(fprintf(stderr, "%*c+ interactive[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement_newline")); + _res = _PyAST_Interactive ( a , p -> arena ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s interactive[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statement_newline")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// eval: expressions NEWLINE* $ +static mod_ty +eval_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + mod_ty _res = NULL; + int _mark = p->mark; + { // expressions NEWLINE* $ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> eval[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions NEWLINE* $")); + asdl_seq * _loop0_1_var; + expr_ty a; + Token * endmarker_var; + if ( + (a = expressions_rule(p)) // expressions + && + (_loop0_1_var = _loop0_1_rule(p)) // NEWLINE* + && + (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' + ) + { + D(fprintf(stderr, "%*c+ eval[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions NEWLINE* $")); + _res = _PyAST_Expression ( a , p -> arena ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s eval[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions NEWLINE* $")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// func_type: '(' type_expressions? ')' '->' expression NEWLINE* $ +static mod_ty +func_type_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + mod_ty _res = NULL; + int _mark = p->mark; + { // '(' type_expressions? ')' '->' expression NEWLINE* $ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> func_type[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); + Token * _literal; + Token * _literal_1; + Token * _literal_2; + asdl_seq * _loop0_2_var; + void *a; + expr_ty b; + Token * endmarker_var; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = type_expressions_rule(p), !p->error_indicator) // type_expressions? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (_literal_2 = _PyPegen_expect_token(p, 51)) // token='->' + && + (b = expression_rule(p)) // expression + && + (_loop0_2_var = _loop0_2_rule(p)) // NEWLINE* + && + (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' + ) + { + D(fprintf(stderr, "%*c+ func_type[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); + _res = _PyAST_FunctionType ( a , b , p -> arena ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s func_type[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// fstring: star_expressions +static expr_ty +fstring_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // star_expressions + 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; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ fstring[%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 fstring[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// type_expressions: +// | ','.expression+ ',' '*' expression ',' '**' expression +// | ','.expression+ ',' '*' expression +// | ','.expression+ ',' '**' expression +// | '*' expression ',' '**' expression +// | '*' expression +// | '**' expression +// | ','.expression+ +static asdl_expr_seq* +type_expressions_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_expr_seq* _res = NULL; + int _mark = p->mark; + { // ','.expression+ ',' '*' expression ',' '**' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); + Token * _literal; + Token * _literal_1; + Token * _literal_2; + Token * _literal_3; + asdl_seq * a; + expr_ty b; + expr_ty c; + if ( + (a = _gather_3_rule(p)) // ','.expression+ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_literal_1 = _PyPegen_expect_token(p, 16)) // token='*' + && + (b = expression_rule(p)) // expression + && + (_literal_2 = _PyPegen_expect_token(p, 12)) // token=',' + && + (_literal_3 = _PyPegen_expect_token(p, 35)) // token='**' + && + (c = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , CHECK ( asdl_seq * , _PyPegen_seq_append_to_end ( p , a , 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 type_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); + } + { // ','.expression+ ',' '*' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression")); + Token * _literal; + Token * _literal_1; + asdl_seq * a; + expr_ty b; + if ( + (a = _gather_5_rule(p)) // ','.expression+ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_literal_1 = _PyPegen_expect_token(p, 16)) // token='*' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression")); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+ ',' '*' expression")); + } + { // ','.expression+ ',' '**' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression")); + Token * _literal; + Token * _literal_1; + asdl_seq * a; + expr_ty b; + if ( + (a = _gather_7_rule(p)) // ','.expression+ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_literal_1 = _PyPegen_expect_token(p, 35)) // token='**' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression")); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+ ',' '**' expression")); + } + { // '*' expression ',' '**' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression")); + Token * _literal; + Token * _literal_1; + Token * _literal_2; + expr_ty a; + expr_ty b; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = expression_rule(p)) // expression + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (_literal_2 = _PyPegen_expect_token(p, 35)) // token='**' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression")); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , CHECK ( asdl_seq * , _PyPegen_singleton_seq ( p , a ) ) , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression ',' '**' expression")); + } + { // '*' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression")); + _res = ( asdl_expr_seq * ) _PyPegen_singleton_seq ( p , 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_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression")); + } + { // '**' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression")); + _res = ( asdl_expr_seq * ) _PyPegen_singleton_seq ( p , 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_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' expression")); + } + { // ','.expression+ + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_9_rule(p)) // ','.expression+ + ) + { + D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+")); + _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_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// statements: statement+ +static asdl_stmt_seq* +statements_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_stmt_seq* _res = NULL; + int _mark = p->mark; + { // statement+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> statements[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement+")); + asdl_seq * a; + if ( + (a = _loop1_11_rule(p)) // statement+ + ) + { + D(fprintf(stderr, "%*c+ statements[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement+")); + _res = ( asdl_stmt_seq * ) _PyPegen_seq_flatten ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s statements[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statement+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// statement: compound_stmt | simple_stmts +static asdl_stmt_seq* +statement_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_stmt_seq* _res = NULL; + int _mark = p->mark; + { // compound_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt")); + stmt_ty a; + if ( + (a = compound_stmt_rule(p)) // compound_stmt + ) + { + D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt")); + _res = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s statement[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compound_stmt")); + } + { // simple_stmts + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmts")); + asdl_stmt_seq* a; + if ( + (a = (asdl_stmt_seq*)simple_stmts_rule(p)) // simple_stmts + ) + { + D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmts")); + _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 statement[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmts")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// statement_newline: compound_stmt NEWLINE | simple_stmts | NEWLINE | $ +static asdl_stmt_seq* +statement_newline_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_stmt_seq* _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 + { // compound_stmt NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt NEWLINE")); + stmt_ty a; + Token * newline_var; + if ( + (a = compound_stmt_rule(p)) // compound_stmt + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt NEWLINE")); + _res = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s statement_newline[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compound_stmt NEWLINE")); + } + { // simple_stmts + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmts")); + asdl_stmt_seq* simple_stmts_var; + if ( + (simple_stmts_var = simple_stmts_rule(p)) // simple_stmts + ) + { + D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmts")); + _res = simple_stmts_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s statement_newline[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmts")); + } + { // NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> statement_newline[%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+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + 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 = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , CHECK ( stmt_ty , _PyAST_Pass ( EXTRA ) ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s statement_newline[%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> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "$")); + Token * endmarker_var; + if ( + (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' + ) + { + D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "$")); + _res = _PyPegen_interactive_exit ( p ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s statement_newline[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "$")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// simple_stmts: simple_stmt !';' NEWLINE | ';'.simple_stmt+ ';'? NEWLINE +static asdl_stmt_seq* +simple_stmts_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_stmt_seq* _res = NULL; + int _mark = p->mark; + { // simple_stmt !';' NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmts[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt !';' NEWLINE")); + stmt_ty a; + Token * newline_var; + if ( + (a = simple_stmt_rule(p)) // simple_stmt + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 13) // token=';' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ simple_stmts[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt !';' NEWLINE")); + _res = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s simple_stmts[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt !';' NEWLINE")); + } + { // ';'.simple_stmt+ ';'? NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmts[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'.simple_stmt+ ';'? NEWLINE")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_stmt_seq* a; + Token * newline_var; + if ( + (a = (asdl_stmt_seq*)_gather_12_rule(p)) // ';'.simple_stmt+ + && + (_opt_var = _PyPegen_expect_token(p, 13), !p->error_indicator) // ';'? + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ simple_stmts[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'.simple_stmt+ ';'? NEWLINE")); + _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 simple_stmts[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';'.simple_stmt+ ';'? NEWLINE")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// simple_stmt: +// | assignment +// | star_expressions +// | &'return' return_stmt +// | &('import' | 'from') import_stmt +// | &'raise' raise_stmt +// | 'pass' +// | &'del' del_stmt +// | &'yield' yield_stmt +// | &'assert' assert_stmt +// | 'break' +// | 'continue' +// | &'global' global_stmt +// | &'nonlocal' nonlocal_stmt +static stmt_ty +simple_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + stmt_ty _res = NULL; + if (_PyPegen_is_memoized(p, simple_stmt_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 + { // assignment + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment")); + stmt_ty assignment_var; + if ( + (assignment_var = assignment_rule(p)) // assignment + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment")); + _res = assignment_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, "assignment")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty e; + if ( + (e = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + 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_Expr ( e , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "star_expressions")); + } + { // &'return' return_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'return' return_stmt")); + stmt_ty return_stmt_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 500) // token='return' + && + (return_stmt_var = return_stmt_rule(p)) // return_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'return' return_stmt")); + _res = return_stmt_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, "&'return' return_stmt")); + } + { // &('import' | 'from') import_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_14_rule, p) + && + (import_stmt_var = import_stmt_rule(p)) // import_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); + _res = import_stmt_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, "&('import' | 'from') import_stmt")); + } + { // &'raise' raise_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'raise' raise_stmt")); + stmt_ty raise_stmt_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 501) // token='raise' + && + (raise_stmt_var = raise_stmt_rule(p)) // raise_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'raise' raise_stmt")); + _res = raise_stmt_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, "&'raise' raise_stmt")); + } + { // 'pass' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'pass'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 502)) // token='pass' + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'pass'")); + 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_Pass ( EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'pass'")); + } + { // &'del' del_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + 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, 503) // token='del' + && + (del_stmt_var = del_stmt_rule(p)) // del_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'del' del_stmt")); + _res = del_stmt_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, "&'del' del_stmt")); + } + { // &'yield' yield_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'yield' yield_stmt")); + stmt_ty yield_stmt_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 504) // token='yield' + && + (yield_stmt_var = yield_stmt_rule(p)) // yield_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'yield' yield_stmt")); + _res = yield_stmt_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, "&'yield' yield_stmt")); + } + { // &'assert' assert_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'assert' assert_stmt")); + stmt_ty assert_stmt_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 505) // token='assert' + && + (assert_stmt_var = assert_stmt_rule(p)) // assert_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'assert' assert_stmt")); + _res = assert_stmt_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, "&'assert' assert_stmt")); + } + { // 'break' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'break'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 506)) // token='break' + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'break'")); + 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_Break ( EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'break'")); + } + { // 'continue' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'continue'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 507)) // token='continue' + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'continue'")); + 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_Continue ( EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'continue'")); + } + { // &'global' global_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'global' global_stmt")); + stmt_ty global_stmt_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 508) // token='global' + && + (global_stmt_var = global_stmt_rule(p)) // global_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'global' global_stmt")); + _res = global_stmt_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, "&'global' global_stmt")); + } + { // &'nonlocal' nonlocal_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'nonlocal' nonlocal_stmt")); + stmt_ty nonlocal_stmt_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 509) // token='nonlocal' + && + (nonlocal_stmt_var = nonlocal_stmt_rule(p)) // nonlocal_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'nonlocal' nonlocal_stmt")); + _res = nonlocal_stmt_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, "&'nonlocal' nonlocal_stmt")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, simple_stmt_type, _res); + p->level--; + return _res; +} + +// compound_stmt: +// | &('def' | '@' | ASYNC) function_def +// | &'if' if_stmt +// | &('class' | '@') class_def +// | &('with' | ASYNC) with_stmt +// | &('for' | ASYNC) for_stmt +// | &'try' try_stmt +// | &'while' while_stmt +// | match_stmt +static stmt_ty +compound_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + stmt_ty _res = NULL; + int _mark = p->mark; + { // &('def' | '@' | ASYNC) function_def + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_15_rule, p) + && + (function_def_var = function_def_rule(p)) // function_def + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); + _res = function_def_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); + } + { // &'if' if_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + 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, 510) // token='if' + && + (if_stmt_var = if_stmt_rule(p)) // if_stmt + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt")); + _res = if_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'if' if_stmt")); + } + { // &('class' | '@') class_def + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_16_rule, p) + && + (class_def_var = class_def_rule(p)) // class_def + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('class' | '@') class_def")); + _res = class_def_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('class' | '@') class_def")); + } + { // &('with' | ASYNC) with_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_17_rule, p) + && + (with_stmt_var = with_stmt_rule(p)) // with_stmt + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('with' | ASYNC) with_stmt")); + _res = with_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('with' | ASYNC) with_stmt")); + } + { // &('for' | ASYNC) for_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_18_rule, p) + && + (for_stmt_var = for_stmt_rule(p)) // for_stmt + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('for' | ASYNC) for_stmt")); + _res = for_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('for' | ASYNC) for_stmt")); + } + { // &'try' try_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + 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, 511) // token='try' + && + (try_stmt_var = try_stmt_rule(p)) // try_stmt + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt")); + _res = try_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'try' try_stmt")); + } + { // &'while' while_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + 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, 512) // token='while' + && + (while_stmt_var = while_stmt_rule(p)) // while_stmt + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt")); + _res = while_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'while' while_stmt")); + } + { // match_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "match_stmt")); + stmt_ty match_stmt_var; + if ( + (match_stmt_var = match_stmt_rule(p)) // match_stmt + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "match_stmt")); + _res = match_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "match_stmt")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// assignment: +// | NAME ':' expression ['=' annotated_rhs] +// | ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs] +// | ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT? +// | single_target augassign ~ (yield_expr | star_expressions) +// | invalid_assignment +static stmt_ty +assignment_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // NAME ':' expression ['=' annotated_rhs] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); + Token * _literal; + expr_ty a; + expr_ty b; + void *c; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = expression_rule(p)) // expression + && + (c = _tmp_19_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]")); + 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 , 6 , "Variable annotation syntax is" , _PyAST_AnnAssign ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , b , c , 1 , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); + } + { // ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); + Token * _literal; + void *a; + expr_ty b; + void *c; + if ( + (a = _tmp_20_rule(p)) // '(' single_target ')' | single_subscript_attribute_target + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = expression_rule(p)) // expression + && + (c = _tmp_21_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]")); + 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 , 6 , "Variable annotations syntax is" , _PyAST_AnnAssign ( a , b , c , 0 , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); + } + { // ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); + asdl_expr_seq* a; + void *b; + void *tc; + if ( + (a = (asdl_expr_seq*)_loop1_22_rule(p)) // ((star_targets '='))+ + && + (b = _tmp_23_rule(p)) // yield_expr | star_expressions + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + ) + { + D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); + 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_Assign ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); + } + { // single_target augassign ~ (yield_expr | star_expressions) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); + int _cut_var = 0; + expr_ty a; + AugOperator* b; + void *c; + if ( + (a = single_target_rule(p)) // single_target + && + (b = augassign_rule(p)) // augassign + && + (_cut_var = 1) + && + (c = _tmp_24_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)")); + 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_AugAssign ( a , b -> kind , c , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); + if (_cut_var) { + p->level--; + return NULL; + } + } + if (p->call_invalid_rules) { // invalid_assignment + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_assignment")); + void *invalid_assignment_var; + if ( + (invalid_assignment_var = invalid_assignment_rule(p)) // invalid_assignment + ) + { + D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_assignment")); + _res = invalid_assignment_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_assignment")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// augassign: +// | '+=' +// | '-=' +// | '*=' +// | '@=' +// | '/=' +// | '%=' +// | '&=' +// | '|=' +// | '^=' +// | '<<=' +// | '>>=' +// | '**=' +// | '//=' +static AugOperator* +augassign_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + AugOperator* _res = NULL; + int _mark = p->mark; + { // '+=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 36)) // token='+=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+='")); + _res = _PyPegen_augoperator ( p , Add ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 37)) // token='-=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-='")); + _res = _PyPegen_augoperator ( p , Sub ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 38)) // token='*=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*='")); + _res = _PyPegen_augoperator ( p , Mult ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 50)) // token='@=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@='")); + _res = CHECK_VERSION ( AugOperator * , 5 , "The '@' operator is" , _PyPegen_augoperator ( p , MatMult ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 39)) // token='/=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/='")); + _res = _PyPegen_augoperator ( p , Div ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'%='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 40)) // token='%=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'%='")); + _res = _PyPegen_augoperator ( p , Mod ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'&='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 41)) // token='&=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'&='")); + _res = _PyPegen_augoperator ( p , BitAnd ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 42)) // token='|=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|='")); + _res = _PyPegen_augoperator ( p , BitOr ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'^='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 43)) // token='^=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'^='")); + _res = _PyPegen_augoperator ( p , BitXor ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<<='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 44)) // token='<<=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<<='")); + _res = _PyPegen_augoperator ( p , LShift ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>>='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 45)) // token='>>=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>>='")); + _res = _PyPegen_augoperator ( p , RShift ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 46)) // token='**=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**='")); + _res = _PyPegen_augoperator ( p , Pow ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'//='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 48)) // token='//=' + ) + { + D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'//='")); + _res = _PyPegen_augoperator ( p , FloorDiv ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s augassign[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'//='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// global_stmt: 'global' ','.NAME+ +static stmt_ty +global_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'global' ','.NAME+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> global_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); + Token * _keyword; + asdl_expr_seq* a; + if ( + (_keyword = _PyPegen_expect_token(p, 508)) // token='global' + && + (a = (asdl_expr_seq*)_gather_25_rule(p)) // ','.NAME+ + ) + { + D(fprintf(stderr, "%*c+ global_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'global' ','.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_Global ( CHECK ( asdl_identifier_seq * , _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s global_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'global' ','.NAME+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// nonlocal_stmt: 'nonlocal' ','.NAME+ +static stmt_ty +nonlocal_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'nonlocal' ','.NAME+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> nonlocal_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); + Token * _keyword; + asdl_expr_seq* a; + if ( + (_keyword = _PyPegen_expect_token(p, 509)) // token='nonlocal' + && + (a = (asdl_expr_seq*)_gather_27_rule(p)) // ','.NAME+ + ) + { + D(fprintf(stderr, "%*c+ nonlocal_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.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_Nonlocal ( CHECK ( asdl_identifier_seq * , _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s nonlocal_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'nonlocal' ','.NAME+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// yield_stmt: yield_expr +static stmt_ty +yield_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> yield_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty y; + if ( + (y = yield_expr_rule(p)) // yield_expr + ) + { + D(fprintf(stderr, "%*c+ yield_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + 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_Expr ( y , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s yield_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// assert_stmt: 'assert' expression [',' expression] +static stmt_ty +assert_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'assert' expression [',' expression] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> assert_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]")); + Token * _keyword; + expr_ty a; + void *b; + if ( + (_keyword = _PyPegen_expect_token(p, 505)) // token='assert' + && + (a = expression_rule(p)) // expression + && + (b = _tmp_29_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]")); + 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_Assert ( a , 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 assert_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'assert' expression [',' expression]")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// del_stmt: 'del' del_targets &(';' | NEWLINE) | invalid_del_stmt +static stmt_ty +del_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'del' del_targets &(';' | NEWLINE) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); + Token * _keyword; + asdl_expr_seq* a; + if ( + (_keyword = _PyPegen_expect_token(p, 503)) // token='del' + && + (a = del_targets_rule(p)) // del_targets + && + _PyPegen_lookahead(1, _tmp_30_rule, p) + ) + { + D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); + 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_Delete ( a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); + } + if (p->call_invalid_rules) { // invalid_del_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_del_stmt")); + void *invalid_del_stmt_var; + if ( + (invalid_del_stmt_var = invalid_del_stmt_rule(p)) // invalid_del_stmt + ) + { + D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_del_stmt")); + _res = invalid_del_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_del_stmt")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// import_stmt: import_name | import_from +static stmt_ty +import_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + stmt_ty _res = NULL; + int _mark = p->mark; + { // import_name + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_name")); + stmt_ty import_name_var; + if ( + (import_name_var = import_name_rule(p)) // import_name + ) + { + D(fprintf(stderr, "%*c+ import_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_name")); + _res = import_name_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, "import_name")); + } + { // import_from + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from")); + stmt_ty import_from_var; + if ( + (import_from_var = import_from_rule(p)) // import_from + ) + { + D(fprintf(stderr, "%*c+ import_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from")); + _res = import_from_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, "import_from")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// import_name: 'import' dotted_as_names +static stmt_ty +import_name_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'import' dotted_as_names + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); + Token * _keyword; + asdl_alias_seq* a; + if ( + (_keyword = _PyPegen_expect_token(p, 513)) // token='import' + && + (a = dotted_as_names_rule(p)) // dotted_as_names + ) + { + D(fprintf(stderr, "%*c+ import_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); + 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_Import ( a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_name[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import' dotted_as_names")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// import_from: +// | 'from' (('.' | '...'))* dotted_name 'import' import_from_targets +// | 'from' (('.' | '...'))+ 'import' import_from_targets +static stmt_ty +import_from_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'from' (('.' | '...'))* dotted_name 'import' import_from_targets + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); + Token * _keyword; + Token * _keyword_1; + asdl_seq * a; + expr_ty b; + asdl_alias_seq* c; + if ( + (_keyword = _PyPegen_expect_token(p, 514)) // token='from' + && + (a = _loop0_31_rule(p)) // (('.' | '...'))* + && + (b = dotted_name_rule(p)) // dotted_name + && + (_keyword_1 = _PyPegen_expect_token(p, 513)) // token='import' + && + (c = import_from_targets_rule(p)) // import_from_targets + ) + { + D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); + 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_ImportFrom ( b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_from[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); + } + { // 'from' (('.' | '...'))+ 'import' import_from_targets + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); + Token * _keyword; + Token * _keyword_1; + asdl_seq * a; + asdl_alias_seq* b; + if ( + (_keyword = _PyPegen_expect_token(p, 514)) // token='from' + && + (a = _loop1_32_rule(p)) // (('.' | '...'))+ + && + (_keyword_1 = _PyPegen_expect_token(p, 513)) // token='import' + && + (b = import_from_targets_rule(p)) // import_from_targets + ) + { + D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); + 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_ImportFrom ( NULL , b , _PyPegen_seq_count_dots ( a ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_from[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// import_from_targets: +// | '(' import_from_as_names ','? ')' +// | import_from_as_names !',' +// | '*' +// | invalid_import_from_targets +static asdl_alias_seq* +import_from_targets_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_alias_seq* _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 + { // '(' import_from_as_names ','? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' import_from_as_names ','? ')'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_alias_seq* a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = import_from_as_names_rule(p)) // import_from_as_names + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' import_from_as_names ','? ')'")); + _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 import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' import_from_as_names ','? ')'")); + } + { // import_from_as_names !',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names !','")); + asdl_alias_seq* import_from_as_names_var; + if ( + (import_from_as_names_var = import_from_as_names_rule(p)) // import_from_as_names + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 12) // token=',' + ) + { + D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_names !','")); + _res = import_from_as_names_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_names !','")); + } + { // '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + 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 = ( asdl_alias_seq * ) _PyPegen_singleton_seq ( p , CHECK ( alias_ty , _PyPegen_alias_for_star ( p , EXTRA ) ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + } + if (p->call_invalid_rules) { // invalid_import_from_targets + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_import_from_targets")); + void *invalid_import_from_targets_var; + if ( + (invalid_import_from_targets_var = invalid_import_from_targets_rule(p)) // invalid_import_from_targets + ) + { + D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_import_from_targets")); + _res = invalid_import_from_targets_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_import_from_targets")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// import_from_as_names: ','.import_from_as_name+ +static asdl_alias_seq* +import_from_as_names_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_alias_seq* _res = NULL; + int _mark = p->mark; + { // ','.import_from_as_name+ + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_33_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+")); + _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 import_from_as_names[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.import_from_as_name+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// import_from_as_name: NAME ['as' NAME] +static alias_ty +import_from_as_name_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + alias_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 + { // NAME ['as' NAME] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ['as' NAME]")); + expr_ty a; + void *b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (b = _tmp_35_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]")); + 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_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_from_as_name[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ['as' NAME]")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// dotted_as_names: ','.dotted_as_name+ +static asdl_alias_seq* +dotted_as_names_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_alias_seq* _res = NULL; + int _mark = p->mark; + { // ','.dotted_as_name+ + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_36_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+")); + _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 dotted_as_names[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.dotted_as_name+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// dotted_as_name: dotted_name ['as' NAME] +static alias_ty +dotted_as_name_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + alias_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 + { // dotted_name ['as' NAME] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> dotted_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name ['as' NAME]")); + expr_ty a; + void *b; + if ( + (a = dotted_name_rule(p)) // dotted_name + && + (b = _tmp_38_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]")); + 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_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s dotted_as_name[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name ['as' NAME]")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// dotted_name: dotted_name '.' NAME | NAME +static expr_ty dotted_name_raw(Parser *); +static expr_ty +dotted_name_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, dotted_name_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_0 = _PyPegen_update_memo(p, _mark, dotted_name_type, _res); + if (tmpvar_0) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = dotted_name_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +dotted_name_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // dotted_name '.' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name '.' NAME")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = dotted_name_rule(p)) // dotted_name + && + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + && + (b = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ dotted_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name '.' NAME")); + _res = _PyPegen_join_names_with_dot ( p , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s dotted_name[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name '.' NAME")); + } + { // NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); + expr_ty name_var; + if ( + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ dotted_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); + _res = name_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s dotted_name[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// if_stmt: +// | invalid_if_stmt +// | 'if' named_expression ':' block elif_stmt +// | 'if' named_expression ':' block else_block? +static stmt_ty +if_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + if (p->call_invalid_rules) { // invalid_if_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_if_stmt")); + void *invalid_if_stmt_var; + if ( + (invalid_if_stmt_var = invalid_if_stmt_rule(p)) // invalid_if_stmt + ) + { + D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_if_stmt")); + _res = invalid_if_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s if_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_if_stmt")); + } + { // 'if' named_expression ':' block elif_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt")); + Token * _keyword; + Token * _literal; + expr_ty a; + asdl_stmt_seq* b; + stmt_ty c; + if ( + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (a = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + && + (c = elif_stmt_rule(p)) // elif_stmt + ) + { + D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt")); + 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_If ( a , b , CHECK ( asdl_stmt_seq * , _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s if_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' named_expression ':' block elif_stmt")); + } + { // 'if' named_expression ':' block else_block? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?")); + Token * _keyword; + Token * _literal; + expr_ty a; + asdl_stmt_seq* b; + void *c; + if ( + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (a = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + && + (c = else_block_rule(p), !p->error_indicator) // else_block? + ) + { + D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?")); + 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_If ( a , b , c , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s if_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' named_expression ':' block else_block?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// elif_stmt: +// | invalid_elif_stmt +// | 'elif' named_expression ':' block elif_stmt +// | 'elif' named_expression ':' block else_block? +static stmt_ty +elif_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + if (p->call_invalid_rules) { // invalid_elif_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_elif_stmt")); + void *invalid_elif_stmt_var; + if ( + (invalid_elif_stmt_var = invalid_elif_stmt_rule(p)) // invalid_elif_stmt + ) + { + D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_elif_stmt")); + _res = invalid_elif_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s elif_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_elif_stmt")); + } + { // 'elif' named_expression ':' block elif_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); + Token * _keyword; + Token * _literal; + expr_ty a; + asdl_stmt_seq* b; + stmt_ty c; + if ( + (_keyword = _PyPegen_expect_token(p, 515)) // token='elif' + && + (a = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + && + (c = elif_stmt_rule(p)) // elif_stmt + ) + { + D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); + 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_If ( a , b , CHECK ( asdl_stmt_seq * , _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s elif_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); + } + { // 'elif' named_expression ':' block else_block? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?")); + Token * _keyword; + Token * _literal; + expr_ty a; + asdl_stmt_seq* b; + void *c; + if ( + (_keyword = _PyPegen_expect_token(p, 515)) // token='elif' + && + (a = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + && + (c = else_block_rule(p), !p->error_indicator) // else_block? + ) + { + D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?")); + 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_If ( a , b , c , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s elif_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'elif' named_expression ':' block else_block?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// else_block: invalid_else_stmt | 'else' &&':' block +static asdl_stmt_seq* +else_block_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_stmt_seq* _res = NULL; + int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_else_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> else_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_else_stmt")); + void *invalid_else_stmt_var; + if ( + (invalid_else_stmt_var = invalid_else_stmt_rule(p)) // invalid_else_stmt + ) + { + D(fprintf(stderr, "%*c+ else_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_else_stmt")); + _res = invalid_else_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s else_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_else_stmt")); + } + { // 'else' &&':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> else_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' &&':' block")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* b; + if ( + (_keyword = _PyPegen_expect_token(p, 516)) // token='else' + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ else_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' &&':' block")); + _res = b; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s else_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else' &&':' block")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// while_stmt: invalid_while_stmt | 'while' named_expression ':' block else_block? +static stmt_ty +while_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + if (p->call_invalid_rules) { // invalid_while_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_while_stmt")); + void *invalid_while_stmt_var; + if ( + (invalid_while_stmt_var = invalid_while_stmt_rule(p)) // invalid_while_stmt + ) + { + D(fprintf(stderr, "%*c+ while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_while_stmt")); + _res = invalid_while_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s while_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_while_stmt")); + } + { // 'while' named_expression ':' block else_block? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?")); + Token * _keyword; + Token * _literal; + expr_ty a; + asdl_stmt_seq* b; + void *c; + if ( + (_keyword = _PyPegen_expect_token(p, 512)) // token='while' + && + (a = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + && + (c = else_block_rule(p), !p->error_indicator) // else_block? + ) + { + D(fprintf(stderr, "%*c+ while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?")); + 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_While ( a , b , c , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s while_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'while' named_expression ':' block else_block?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// for_stmt: +// | invalid_for_stmt +// | 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? +// | ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? +// | invalid_for_target +static stmt_ty +for_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + if (p->call_invalid_rules) { // invalid_for_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_stmt")); + void *invalid_for_stmt_var; + if ( + (invalid_for_stmt_var = invalid_for_stmt_rule(p)) // invalid_for_stmt + ) + { + D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_for_stmt")); + _res = invalid_for_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_for_stmt")); + } + { // 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + int _cut_var = 0; + Token * _keyword; + Token * _keyword_1; + Token * _literal; + asdl_stmt_seq* b; + void *el; + expr_ty ex; + expr_ty t; + void *tc; + if ( + (_keyword = _PyPegen_expect_token(p, 517)) // token='for' + && + (t = star_targets_rule(p)) // star_targets + && + (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' + && + (_cut_var = 1) + && + (ex = star_expressions_rule(p)) // star_expressions + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + (b = block_rule(p)) // block + && + (el = else_block_rule(p), !p->error_indicator) // else_block? + ) + { + D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + 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_For ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + if (_cut_var) { + p->level--; + return NULL; + } + } + { // ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + int _cut_var = 0; + Token * _keyword; + Token * _keyword_1; + Token * _literal; + Token * async_var; + asdl_stmt_seq* b; + void *el; + expr_ty ex; + expr_ty t; + void *tc; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + && + (_keyword = _PyPegen_expect_token(p, 517)) // token='for' + && + (t = star_targets_rule(p)) // star_targets + && + (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' + && + (_cut_var = 1) + && + (ex = star_expressions_rule(p)) // star_expressions + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + (b = block_rule(p)) // block + && + (el = else_block_rule(p), !p->error_indicator) // else_block? + ) + { + D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + 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 , 5 , "Async for loops are" , _PyAST_AsyncFor ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + if (_cut_var) { + p->level--; + return NULL; + } + } + if (p->call_invalid_rules) { // invalid_for_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); + void *invalid_for_target_var; + if ( + (invalid_for_target_var = invalid_for_target_rule(p)) // invalid_for_target + ) + { + D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); + _res = invalid_for_target_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_for_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// with_stmt: +// | invalid_with_stmt_indent +// | 'with' '(' ','.with_item+ ','? ')' ':' block +// | 'with' ','.with_item+ ':' TYPE_COMMENT? block +// | ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block +// | ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block +// | invalid_with_stmt +static stmt_ty +with_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + if (p->call_invalid_rules) { // invalid_with_stmt_indent + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_stmt_indent")); + void *invalid_with_stmt_indent_var; + if ( + (invalid_with_stmt_indent_var = invalid_with_stmt_indent_rule(p)) // invalid_with_stmt_indent + ) + { + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_with_stmt_indent")); + _res = invalid_with_stmt_indent_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_with_stmt_indent")); + } + { // 'with' '(' ','.with_item+ ','? ')' ':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_withitem_seq* a; + asdl_stmt_seq* b; + if ( + (_keyword = _PyPegen_expect_token(p, 519)) // token='with' + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = (asdl_withitem_seq*)_gather_39_rule(p)) // ','.with_item+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); + 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_With ( a , b , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); + } + { // 'with' ','.with_item+ ':' TYPE_COMMENT? block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); + Token * _keyword; + Token * _literal; + asdl_withitem_seq* a; + asdl_stmt_seq* b; + void *tc; + if ( + (_keyword = _PyPegen_expect_token(p, 519)) // token='with' + && + (a = (asdl_withitem_seq*)_gather_41_rule(p)) // ','.with_item+ + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); + 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_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); + } + { // ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_withitem_seq* a; + Token * async_var; + asdl_stmt_seq* b; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + && + (_keyword = _PyPegen_expect_token(p, 519)) // token='with' + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = (asdl_withitem_seq*)_gather_43_rule(p)) // ','.with_item+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); + 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 , 5 , "Async with statements are" , _PyAST_AsyncWith ( a , b , NULL , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); + } + { // ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); + Token * _keyword; + Token * _literal; + asdl_withitem_seq* a; + Token * async_var; + asdl_stmt_seq* b; + void *tc; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + && + (_keyword = _PyPegen_expect_token(p, 519)) // token='with' + && + (a = (asdl_withitem_seq*)_gather_45_rule(p)) // ','.with_item+ + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); + 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 , 5 , "Async with statements are" , _PyAST_AsyncWith ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); + } + if (p->call_invalid_rules) { // invalid_with_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_stmt")); + void *invalid_with_stmt_var; + if ( + (invalid_with_stmt_var = invalid_with_stmt_rule(p)) // invalid_with_stmt + ) + { + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_with_stmt")); + _res = invalid_with_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_with_stmt")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// with_item: +// | expression 'as' star_target &(',' | ')' | ':') +// | invalid_with_item +// | expression +static withitem_ty +with_item_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + withitem_ty _res = NULL; + int _mark = p->mark; + { // expression 'as' star_target &(',' | ')' | ':') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); + Token * _keyword; + expr_ty e; + expr_ty t; + if ( + (e = expression_rule(p)) // expression + && + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (t = star_target_rule(p)) // star_target + && + _PyPegen_lookahead(1, _tmp_47_rule, p) + ) + { + D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); + _res = _PyAST_withitem ( e , t , p -> arena ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_item[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); + } + if (p->call_invalid_rules) { // invalid_with_item + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_item")); + void *invalid_with_item_var; + if ( + (invalid_with_item_var = invalid_with_item_rule(p)) // invalid_with_item + ) + { + D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_with_item")); + _res = invalid_with_item_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_item[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_with_item")); + } + { // expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); + expr_ty e; + if ( + (e = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); + _res = _PyAST_withitem ( e , NULL , p -> arena ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s with_item[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// try_stmt: +// | invalid_try_stmt +// | 'try' &&':' block finally_block +// | 'try' &&':' block except_block+ else_block? finally_block? +static stmt_ty +try_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + if (p->call_invalid_rules) { // invalid_try_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_try_stmt")); + void *invalid_try_stmt_var; + if ( + (invalid_try_stmt_var = invalid_try_stmt_rule(p)) // invalid_try_stmt + ) + { + D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_try_stmt")); + _res = invalid_try_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_try_stmt")); + } + { // 'try' &&':' block finally_block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' &&':' block finally_block")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* b; + asdl_stmt_seq* f; + if ( + (_keyword = _PyPegen_expect_token(p, 511)) // token='try' + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (b = block_rule(p)) // block + && + (f = finally_block_rule(p)) // finally_block + ) + { + D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' &&':' block finally_block")); + 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_Try ( b , NULL , NULL , f , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' &&':' block finally_block")); + } + { // 'try' &&':' block except_block+ else_block? finally_block? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' &&':' block except_block+ else_block? finally_block?")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* b; + void *el; + asdl_excepthandler_seq* ex; + void *f; + if ( + (_keyword = _PyPegen_expect_token(p, 511)) // token='try' + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (b = block_rule(p)) // block + && + (ex = (asdl_excepthandler_seq*)_loop1_48_rule(p)) // except_block+ + && + (el = else_block_rule(p), !p->error_indicator) // else_block? + && + (f = finally_block_rule(p), !p->error_indicator) // finally_block? + ) + { + D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' &&':' block except_block+ else_block? finally_block?")); + 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_Try ( b , ex , el , f , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' &&':' block except_block+ else_block? finally_block?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// except_block: +// | invalid_except_stmt_indent +// | 'except' expression ['as' NAME] ':' block +// | 'except' ':' block +// | invalid_except_stmt +static excepthandler_ty +except_block_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + excepthandler_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 + if (p->call_invalid_rules) { // invalid_except_stmt_indent + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt_indent")); + void *invalid_except_stmt_indent_var; + if ( + (invalid_except_stmt_indent_var = invalid_except_stmt_indent_rule(p)) // invalid_except_stmt_indent + ) + { + D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt_indent")); + _res = invalid_except_stmt_indent_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s except_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_except_stmt_indent")); + } + { // 'except' expression ['as' NAME] ':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* b; + expr_ty e; + void *t; + if ( + (_keyword = _PyPegen_expect_token(p, 521)) // token='except' + && + (e = expression_rule(p)) // expression + && + (t = _tmp_49_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block")); + 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_ExceptHandler ( e , ( t ) ? ( ( expr_ty ) t ) -> v . Name . id : NULL , 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 except_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' expression ['as' NAME] ':' block")); + } + { // 'except' ':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' ':' block")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* b; + if ( + (_keyword = _PyPegen_expect_token(p, 521)) // token='except' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' block")); + 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_ExceptHandler ( NULL , NULL , 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 except_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' ':' block")); + } + if (p->call_invalid_rules) { // invalid_except_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt")); + void *invalid_except_stmt_var; + if ( + (invalid_except_stmt_var = invalid_except_stmt_rule(p)) // invalid_except_stmt + ) + { + D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt")); + _res = invalid_except_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s except_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_except_stmt")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// finally_block: invalid_finally_stmt | 'finally' &&':' block +static asdl_stmt_seq* +finally_block_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_stmt_seq* _res = NULL; + int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_finally_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> finally_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_finally_stmt")); + void *invalid_finally_stmt_var; + if ( + (invalid_finally_stmt_var = invalid_finally_stmt_rule(p)) // invalid_finally_stmt + ) + { + D(fprintf(stderr, "%*c+ finally_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_finally_stmt")); + _res = invalid_finally_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s finally_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_finally_stmt")); + } + { // 'finally' &&':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> finally_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally' &&':' block")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* a; + if ( + (_keyword = _PyPegen_expect_token(p, 522)) // token='finally' + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (a = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ finally_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally' &&':' block")); + _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 finally_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally' &&':' block")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// match_stmt: +// | "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT +// | invalid_match_stmt +static stmt_ty +match_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE INDENT case_block+ DEDENT")); + expr_ty _keyword; + Token * _literal; + asdl_match_case_seq* cases; + Token * dedent_var; + Token * indent_var; + Token * newline_var; + expr_ty subject; + if ( + (_keyword = _PyPegen_expect_soft_keyword(p, "match")) // soft_keyword='"match"' + && + (subject = subject_expr_rule(p)) // subject_expr + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' + && + (cases = (asdl_match_case_seq*)_loop1_50_rule(p)) // case_block+ + && + (dedent_var = _PyPegen_expect_token(p, DEDENT)) // token='DEDENT' + ) + { + D(fprintf(stderr, "%*c+ match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE INDENT case_block+ DEDENT")); + 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 , 10 , "Pattern matching is" , _PyAST_Match ( subject , cases , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s match_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"match\" subject_expr ':' NEWLINE INDENT case_block+ DEDENT")); + } + if (p->call_invalid_rules) { // invalid_match_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_match_stmt")); + void *invalid_match_stmt_var; + if ( + (invalid_match_stmt_var = invalid_match_stmt_rule(p)) // invalid_match_stmt + ) + { + D(fprintf(stderr, "%*c+ match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_match_stmt")); + _res = invalid_match_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s match_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_match_stmt")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// subject_expr: star_named_expression ',' star_named_expressions? | named_expression +static expr_ty +subject_expr_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // star_named_expression ',' star_named_expressions? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> subject_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + Token * _literal; + expr_ty value; + void *values; + if ( + (value = star_named_expression_rule(p)) // star_named_expression + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (values = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? + ) + { + D(fprintf(stderr, "%*c+ subject_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + 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_Tuple ( CHECK ( asdl_expr_seq * , _PyPegen_seq_insert_in_front ( p , value , values ) ) , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s subject_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + } + { // named_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> subject_expr[%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+ subject_expr[%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 subject_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// case_block: invalid_case_block | "case" patterns guard? ':' block +static match_case_ty +case_block_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + match_case_ty _res = NULL; + int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_case_block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_case_block")); + void *invalid_case_block_var; + if ( + (invalid_case_block_var = invalid_case_block_rule(p)) // invalid_case_block + ) + { + D(fprintf(stderr, "%*c+ case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_case_block")); + _res = invalid_case_block_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s case_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_case_block")); + } + { // "case" patterns guard? ':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' block")); + expr_ty _keyword; + Token * _literal; + asdl_stmt_seq* body; + void *guard; + pattern_ty pattern; + if ( + (_keyword = _PyPegen_expect_soft_keyword(p, "case")) // soft_keyword='"case"' + && + (pattern = patterns_rule(p)) // patterns + && + (guard = guard_rule(p), !p->error_indicator) // guard? + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (body = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' block")); + _res = _PyAST_match_case ( pattern , guard , body , p -> arena ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s case_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"case\" patterns guard? ':' block")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// guard: 'if' named_expression +static expr_ty +guard_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // 'if' named_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> guard[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression")); + Token * _keyword; + expr_ty guard; + if ( + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (guard = named_expression_rule(p)) // named_expression + ) + { + D(fprintf(stderr, "%*c+ guard[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression")); + _res = guard; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s guard[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' named_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// patterns: open_sequence_pattern | pattern +static pattern_ty +patterns_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // open_sequence_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "open_sequence_pattern")); + asdl_pattern_seq* patterns; + if ( + (patterns = (asdl_pattern_seq*)open_sequence_pattern_rule(p)) // open_sequence_pattern + ) + { + D(fprintf(stderr, "%*c+ patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "open_sequence_pattern")); + 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_MatchSequence ( patterns , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s patterns[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "open_sequence_pattern")); + } + { // pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern")); + pattern_ty pattern_var; + if ( + (pattern_var = pattern_rule(p)) // pattern + ) + { + D(fprintf(stderr, "%*c+ patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern")); + _res = pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s patterns[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// pattern: as_pattern | or_pattern +static pattern_ty +pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_ty _res = NULL; + int _mark = p->mark; + { // as_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "as_pattern")); + pattern_ty as_pattern_var; + if ( + (as_pattern_var = as_pattern_rule(p)) // as_pattern + ) + { + D(fprintf(stderr, "%*c+ pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "as_pattern")); + _res = as_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "as_pattern")); + } + { // or_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern")); + pattern_ty or_pattern_var; + if ( + (or_pattern_var = or_pattern_rule(p)) // or_pattern + ) + { + D(fprintf(stderr, "%*c+ pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "or_pattern")); + _res = or_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "or_pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// as_pattern: or_pattern 'as' pattern_capture_target | invalid_as_pattern +static pattern_ty +as_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // or_pattern 'as' pattern_capture_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' pattern_capture_target")); + Token * _keyword; + pattern_ty pattern; + expr_ty target; + if ( + (pattern = or_pattern_rule(p)) // or_pattern + && + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (target = pattern_capture_target_rule(p)) // pattern_capture_target + ) + { + D(fprintf(stderr, "%*c+ as_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' pattern_capture_target")); + 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_MatchAs ( pattern , target -> 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 as_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "or_pattern 'as' pattern_capture_target")); + } + if (p->call_invalid_rules) { // invalid_as_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_as_pattern")); + void *invalid_as_pattern_var; + if ( + (invalid_as_pattern_var = invalid_as_pattern_rule(p)) // invalid_as_pattern + ) + { + D(fprintf(stderr, "%*c+ as_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_as_pattern")); + _res = invalid_as_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s as_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_as_pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// or_pattern: '|'.closed_pattern+ +static pattern_ty +or_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // '|'.closed_pattern+ + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_51_rule(p)) // '|'.closed_pattern+ + ) + { + D(fprintf(stderr, "%*c+ or_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); + 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 = asdl_seq_LEN ( patterns ) == 1 ? asdl_seq_GET ( patterns , 0 ) : _PyAST_MatchOr ( patterns , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s or_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'|'.closed_pattern+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// closed_pattern: +// | literal_pattern +// | capture_pattern +// | wildcard_pattern +// | value_pattern +// | group_pattern +// | sequence_pattern +// | mapping_pattern +// | class_pattern +static pattern_ty +closed_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_ty _res = NULL; + int _mark = p->mark; + { // literal_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_pattern")); + pattern_ty literal_pattern_var; + if ( + (literal_pattern_var = literal_pattern_rule(p)) // literal_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_pattern")); + _res = literal_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "literal_pattern")); + } + { // capture_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "capture_pattern")); + pattern_ty capture_pattern_var; + if ( + (capture_pattern_var = capture_pattern_rule(p)) // capture_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "capture_pattern")); + _res = capture_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "capture_pattern")); + } + { // wildcard_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "wildcard_pattern")); + pattern_ty wildcard_pattern_var; + if ( + (wildcard_pattern_var = wildcard_pattern_rule(p)) // wildcard_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "wildcard_pattern")); + _res = wildcard_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "wildcard_pattern")); + } + { // value_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "value_pattern")); + pattern_ty value_pattern_var; + if ( + (value_pattern_var = value_pattern_rule(p)) // value_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "value_pattern")); + _res = value_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "value_pattern")); + } + { // group_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group_pattern")); + pattern_ty group_pattern_var; + if ( + (group_pattern_var = group_pattern_rule(p)) // group_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group_pattern")); + _res = group_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group_pattern")); + } + { // sequence_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sequence_pattern")); + pattern_ty sequence_pattern_var; + if ( + (sequence_pattern_var = sequence_pattern_rule(p)) // sequence_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sequence_pattern")); + _res = sequence_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "sequence_pattern")); + } + { // mapping_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "mapping_pattern")); + pattern_ty mapping_pattern_var; + if ( + (mapping_pattern_var = mapping_pattern_rule(p)) // mapping_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "mapping_pattern")); + _res = mapping_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "mapping_pattern")); + } + { // class_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "class_pattern")); + pattern_ty class_pattern_var; + if ( + (class_pattern_var = class_pattern_rule(p)) // class_pattern + ) + { + D(fprintf(stderr, "%*c+ closed_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "class_pattern")); + _res = class_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s closed_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "class_pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// literal_pattern: +// | signed_number !('+' | '-') +// | complex_number +// | strings +// | 'None' +// | 'True' +// | 'False' +static pattern_ty +literal_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // signed_number !('+' | '-') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); + expr_ty value; + if ( + (value = signed_number_rule(p)) // signed_number + && + _PyPegen_lookahead(0, _tmp_53_rule, p) + ) + { + D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); + 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_MatchValue ( value , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "signed_number !('+' | '-')")); + } + { // complex_number + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "complex_number")); + expr_ty value; + if ( + (value = complex_number_rule(p)) // complex_number + ) + { + D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "complex_number")); + 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_MatchValue ( value , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "complex_number")); + } + { // strings + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "strings")); + expr_ty value; + if ( + (value = strings_rule(p)) // strings + ) + { + D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "strings")); + 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_MatchValue ( value , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "strings")); + } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 523)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + 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_MatchSingleton ( Py_None , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + { // 'True' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 524)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + 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_MatchSingleton ( Py_True , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_pattern[%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> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 525)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + 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_MatchSingleton ( Py_False , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// literal_expr: +// | signed_number !('+' | '-') +// | complex_number +// | strings +// | 'None' +// | 'True' +// | 'False' +static expr_ty +literal_expr_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // signed_number !('+' | '-') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); + expr_ty signed_number_var; + if ( + (signed_number_var = signed_number_rule(p)) // signed_number + && + _PyPegen_lookahead(0, _tmp_54_rule, p) + ) + { + D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); + _res = signed_number_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "signed_number !('+' | '-')")); + } + { // complex_number + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "complex_number")); + expr_ty complex_number_var; + if ( + (complex_number_var = complex_number_rule(p)) // complex_number + ) + { + D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "complex_number")); + _res = complex_number_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "complex_number")); + } + { // strings + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "strings")); + expr_ty strings_var; + if ( + (strings_var = strings_rule(p)) // strings + ) + { + D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "strings")); + _res = strings_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "strings")); + } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 523)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + 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_Constant ( Py_None , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + { // 'True' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 524)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + 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_Constant ( Py_True , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_expr[%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> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 525)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + 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_Constant ( Py_False , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s literal_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// complex_number: +// | signed_real_number '+' imaginary_number +// | signed_real_number '-' imaginary_number +static expr_ty +complex_number_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // signed_real_number '+' imaginary_number + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> complex_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_real_number '+' imaginary_number")); + Token * _literal; + expr_ty imag; + expr_ty real; + if ( + (real = signed_real_number_rule(p)) // signed_real_number + && + (_literal = _PyPegen_expect_token(p, 14)) // token='+' + && + (imag = imaginary_number_rule(p)) // imaginary_number + ) + { + D(fprintf(stderr, "%*c+ complex_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_real_number '+' imaginary_number")); + 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_BinOp ( real , Add , imag , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s complex_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "signed_real_number '+' imaginary_number")); + } + { // signed_real_number '-' imaginary_number + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> complex_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_real_number '-' imaginary_number")); + Token * _literal; + expr_ty imag; + expr_ty real; + if ( + (real = signed_real_number_rule(p)) // signed_real_number + && + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + && + (imag = imaginary_number_rule(p)) // imaginary_number + ) + { + D(fprintf(stderr, "%*c+ complex_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_real_number '-' imaginary_number")); + 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_BinOp ( real , Sub , imag , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s complex_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "signed_real_number '-' imaginary_number")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// signed_number: NUMBER | '-' NUMBER +static expr_ty +signed_number_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // NUMBER + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> signed_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); + expr_ty number_var; + if ( + (number_var = _PyPegen_number_token(p)) // NUMBER + ) + { + D(fprintf(stderr, "%*c+ signed_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NUMBER")); + _res = number_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s signed_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NUMBER")); + } + { // '-' NUMBER + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> signed_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' NUMBER")); + Token * _literal; + expr_ty number; + if ( + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + && + (number = _PyPegen_number_token(p)) // NUMBER + ) + { + D(fprintf(stderr, "%*c+ signed_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' NUMBER")); + 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_UnaryOp ( USub , number , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s signed_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-' NUMBER")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// signed_real_number: real_number | '-' real_number +static expr_ty +signed_real_number_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // real_number + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> signed_real_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "real_number")); + expr_ty real_number_var; + if ( + (real_number_var = real_number_rule(p)) // real_number + ) + { + D(fprintf(stderr, "%*c+ signed_real_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "real_number")); + _res = real_number_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s signed_real_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "real_number")); + } + { // '-' real_number + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> signed_real_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' real_number")); + Token * _literal; + expr_ty real; + if ( + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + && + (real = real_number_rule(p)) // real_number + ) + { + D(fprintf(stderr, "%*c+ signed_real_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' real_number")); + 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_UnaryOp ( USub , real , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s signed_real_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-' real_number")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// real_number: NUMBER +static expr_ty +real_number_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // NUMBER + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> real_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); + expr_ty real; + if ( + (real = _PyPegen_number_token(p)) // NUMBER + ) + { + D(fprintf(stderr, "%*c+ real_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NUMBER")); + _res = _PyPegen_ensure_real ( p , real ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s real_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NUMBER")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// imaginary_number: NUMBER +static expr_ty +imaginary_number_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // NUMBER + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> imaginary_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); + expr_ty imag; + if ( + (imag = _PyPegen_number_token(p)) // NUMBER + ) + { + D(fprintf(stderr, "%*c+ imaginary_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NUMBER")); + _res = _PyPegen_ensure_imaginary ( p , imag ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s imaginary_number[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NUMBER")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// capture_pattern: pattern_capture_target +static pattern_ty +capture_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // pattern_capture_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> capture_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern_capture_target")); + expr_ty target; + if ( + (target = pattern_capture_target_rule(p)) // pattern_capture_target + ) + { + D(fprintf(stderr, "%*c+ capture_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern_capture_target")); + 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_MatchAs ( NULL , target -> 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 capture_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern_capture_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// pattern_capture_target: !"_" NAME !('.' | '(' | '=') +static expr_ty +pattern_capture_target_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // !"_" NAME !('.' | '(' | '=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> pattern_capture_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); + expr_ty name; + if ( + _PyPegen_lookahead_with_string(0, _PyPegen_expect_soft_keyword, p, "_") + && + (name = _PyPegen_name_token(p)) // NAME + && + _PyPegen_lookahead(0, _tmp_55_rule, p) + ) + { + D(fprintf(stderr, "%*c+ pattern_capture_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); + _res = _PyPegen_set_expr_context ( p , name , Store ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s pattern_capture_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// wildcard_pattern: "_" +static pattern_ty +wildcard_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // "_" + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> wildcard_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"_\"")); + expr_ty _keyword; + if ( + (_keyword = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' + ) + { + D(fprintf(stderr, "%*c+ wildcard_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"_\"")); + 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_MatchAs ( NULL , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s wildcard_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"_\"")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// value_pattern: attr !('.' | '(' | '=') +static pattern_ty +value_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // attr !('.' | '(' | '=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> value_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')")); + expr_ty attr; + if ( + (attr = attr_rule(p)) // attr + && + _PyPegen_lookahead(0, _tmp_56_rule, p) + ) + { + D(fprintf(stderr, "%*c+ value_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')")); + 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_MatchValue ( attr , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s value_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr !('.' | '(' | '=')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// attr: name_or_attr '.' NAME +static expr_ty attr_raw(Parser *); +static expr_ty +attr_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, attr_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_1 = _PyPegen_update_memo(p, _mark, attr_type, _res); + if (tmpvar_1) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = attr_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +attr_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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_or_attr '.' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> attr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '.' NAME")); + Token * _literal; + expr_ty attr; + expr_ty value; + if ( + (value = name_or_attr_rule(p)) // name_or_attr + && + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + && + (attr = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ attr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '.' 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_Attribute ( value , attr -> v . Name . id , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s attr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "name_or_attr '.' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// name_or_attr: attr | NAME +static expr_ty +name_or_attr_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // attr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> name_or_attr[%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+ name_or_attr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); + _res = attr_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s name_or_attr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr")); + } + { // NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> name_or_attr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); + expr_ty name_var; + if ( + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ name_or_attr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); + _res = name_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s name_or_attr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// group_pattern: '(' pattern ')' +static pattern_ty +group_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_ty _res = NULL; + int _mark = p->mark; + { // '(' pattern ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> group_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' pattern ')'")); + Token * _literal; + Token * _literal_1; + pattern_ty pattern; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (pattern = pattern_rule(p)) // pattern + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ group_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' pattern ')'")); + _res = pattern; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s group_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' pattern ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// sequence_pattern: '[' maybe_sequence_pattern? ']' | '(' open_sequence_pattern? ')' +static pattern_ty +sequence_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // '[' maybe_sequence_pattern? ']' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' maybe_sequence_pattern? ']'")); + Token * _literal; + Token * _literal_1; + void *patterns; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (patterns = maybe_sequence_pattern_rule(p), !p->error_indicator) // maybe_sequence_pattern? + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + ) + { + D(fprintf(stderr, "%*c+ sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' maybe_sequence_pattern? ']'")); + 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_MatchSequence ( patterns , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s sequence_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' maybe_sequence_pattern? ']'")); + } + { // '(' open_sequence_pattern? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' open_sequence_pattern? ')'")); + Token * _literal; + Token * _literal_1; + void *patterns; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (patterns = open_sequence_pattern_rule(p), !p->error_indicator) // open_sequence_pattern? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' open_sequence_pattern? ')'")); + 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_MatchSequence ( patterns , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s sequence_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' open_sequence_pattern? ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// open_sequence_pattern: maybe_star_pattern ',' maybe_sequence_pattern? +static asdl_seq* +open_sequence_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq* _res = NULL; + int _mark = p->mark; + { // maybe_star_pattern ',' maybe_sequence_pattern? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> open_sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern ',' maybe_sequence_pattern?")); + Token * _literal; + pattern_ty pattern; + void *patterns; + if ( + (pattern = maybe_star_pattern_rule(p)) // maybe_star_pattern + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (patterns = maybe_sequence_pattern_rule(p), !p->error_indicator) // maybe_sequence_pattern? + ) + { + D(fprintf(stderr, "%*c+ open_sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern ',' maybe_sequence_pattern?")); + _res = _PyPegen_seq_insert_in_front ( p , pattern , patterns ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s open_sequence_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern ',' maybe_sequence_pattern?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// maybe_sequence_pattern: ','.maybe_star_pattern+ ','? +static asdl_seq* +maybe_sequence_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq* _res = NULL; + int _mark = p->mark; + { // ','.maybe_star_pattern+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> maybe_sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.maybe_star_pattern+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_seq * patterns; + if ( + (patterns = _gather_57_rule(p)) // ','.maybe_star_pattern+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ maybe_sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.maybe_star_pattern+ ','?")); + _res = patterns; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s maybe_sequence_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.maybe_star_pattern+ ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// maybe_star_pattern: star_pattern | pattern +static pattern_ty +maybe_star_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_ty _res = NULL; + int _mark = p->mark; + { // star_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> maybe_star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_pattern")); + pattern_ty star_pattern_var; + if ( + (star_pattern_var = star_pattern_rule(p)) // star_pattern + ) + { + D(fprintf(stderr, "%*c+ maybe_star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_pattern")); + _res = star_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s maybe_star_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_pattern")); + } + { // pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> maybe_star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern")); + pattern_ty pattern_var; + if ( + (pattern_var = pattern_rule(p)) // pattern + ) + { + D(fprintf(stderr, "%*c+ maybe_star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern")); + _res = pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s maybe_star_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_pattern: '*' pattern_capture_target | '*' wildcard_pattern +static pattern_ty +star_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // '*' pattern_capture_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' pattern_capture_target")); + Token * _literal; + expr_ty target; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (target = pattern_capture_target_rule(p)) // pattern_capture_target + ) + { + D(fprintf(stderr, "%*c+ star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' pattern_capture_target")); + 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_MatchStar ( target -> 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 star_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' pattern_capture_target")); + } + { // '*' wildcard_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' wildcard_pattern")); + Token * _literal; + pattern_ty wildcard_pattern_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (wildcard_pattern_var = wildcard_pattern_rule(p)) // wildcard_pattern + ) + { + D(fprintf(stderr, "%*c+ star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' wildcard_pattern")); + 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_MatchStar ( NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' wildcard_pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// mapping_pattern: +// | '{' '}' +// | '{' double_star_pattern ','? '}' +// | '{' items_pattern ',' double_star_pattern ','? '}' +// | '{' items_pattern ','? '}' +static pattern_ty +mapping_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // '{' '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '}'")); + Token * _literal; + Token * _literal_1; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '}'")); + 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_MatchMapping ( NULL , NULL , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s mapping_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' '}'")); + } + { // '{' double_star_pattern ','? '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' double_star_pattern ','? '}'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty rest; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (rest = double_star_pattern_rule(p)) // double_star_pattern + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' double_star_pattern ','? '}'")); + 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_MatchMapping ( NULL , NULL , rest -> 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 mapping_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' double_star_pattern ','? '}'")); + } + { // '{' items_pattern ',' double_star_pattern ','? '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ',' double_star_pattern ','? '}'")); + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_seq* items; + expr_ty rest; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (items = items_pattern_rule(p)) // items_pattern + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (rest = double_star_pattern_rule(p)) // double_star_pattern + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_2 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ',' double_star_pattern ','? '}'")); + 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_MatchMapping ( CHECK ( asdl_expr_seq * , _PyPegen_get_pattern_keys ( p , items ) ) , CHECK ( asdl_pattern_seq * , _PyPegen_get_patterns ( p , items ) ) , rest -> 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 mapping_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' items_pattern ',' double_star_pattern ','? '}'")); + } + { // '{' items_pattern ','? '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ','? '}'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_seq* items; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (items = items_pattern_rule(p)) // items_pattern + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ','? '}'")); + 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_MatchMapping ( CHECK ( asdl_expr_seq * , _PyPegen_get_pattern_keys ( p , items ) ) , CHECK ( asdl_pattern_seq * , _PyPegen_get_patterns ( p , items ) ) , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s mapping_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' items_pattern ','? '}'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// items_pattern: ','.key_value_pattern+ +static asdl_seq* +items_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq* _res = NULL; + int _mark = p->mark; + { // ','.key_value_pattern+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> items_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); + asdl_seq * _gather_59_var; + if ( + (_gather_59_var = _gather_59_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_59_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s items_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.key_value_pattern+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// key_value_pattern: (literal_expr | attr) ':' pattern +static KeyPatternPair* +key_value_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + KeyPatternPair* _res = NULL; + int _mark = p->mark; + { // (literal_expr | attr) ':' pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> key_value_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(literal_expr | attr) ':' pattern")); + Token * _literal; + void *key; + pattern_ty pattern; + if ( + (key = _tmp_61_rule(p)) // literal_expr | attr + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (pattern = pattern_rule(p)) // pattern + ) + { + D(fprintf(stderr, "%*c+ key_value_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(literal_expr | attr) ':' pattern")); + _res = _PyPegen_key_pattern_pair ( p , key , pattern ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s key_value_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(literal_expr | attr) ':' pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// double_star_pattern: '**' pattern_capture_target +static expr_ty +double_star_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // '**' pattern_capture_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> double_star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' pattern_capture_target")); + Token * _literal; + expr_ty target; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (target = pattern_capture_target_rule(p)) // pattern_capture_target + ) + { + D(fprintf(stderr, "%*c+ double_star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' pattern_capture_target")); + _res = target; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s double_star_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' pattern_capture_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// class_pattern: +// | name_or_attr '(' ')' +// | name_or_attr '(' positional_patterns ','? ')' +// | name_or_attr '(' keyword_patterns ','? ')' +// | name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')' +// | invalid_class_pattern +static pattern_ty +class_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + pattern_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 + { // name_or_attr '(' ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' ')'")); + Token * _literal; + Token * _literal_1; + expr_ty cls; + if ( + (cls = name_or_attr_rule(p)) // name_or_attr + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' ')'")); + 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_MatchClass ( cls , NULL , NULL , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s class_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "name_or_attr '(' ')'")); + } + { // name_or_attr '(' positional_patterns ','? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ','? ')'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty cls; + asdl_pattern_seq* patterns; + if ( + (cls = name_or_attr_rule(p)) // name_or_attr + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (patterns = positional_patterns_rule(p)) // positional_patterns + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ','? ')'")); + 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_MatchClass ( cls , patterns , NULL , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s class_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "name_or_attr '(' positional_patterns ','? ')'")); + } + { // name_or_attr '(' keyword_patterns ','? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' keyword_patterns ','? ')'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty cls; + asdl_seq* keywords; + if ( + (cls = name_or_attr_rule(p)) // name_or_attr + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (keywords = keyword_patterns_rule(p)) // keyword_patterns + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' keyword_patterns ','? ')'")); + 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_MatchClass ( cls , NULL , CHECK ( asdl_identifier_seq * , _PyPegen_map_names_to_ids ( p , CHECK ( asdl_expr_seq * , _PyPegen_get_pattern_keys ( p , keywords ) ) ) ) , CHECK ( asdl_pattern_seq * , _PyPegen_get_patterns ( p , keywords ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s class_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "name_or_attr '(' keyword_patterns ','? ')'")); + } + { // name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')'")); + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty cls; + asdl_seq* keywords; + asdl_pattern_seq* patterns; + if ( + (cls = name_or_attr_rule(p)) // name_or_attr + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (patterns = positional_patterns_rule(p)) // positional_patterns + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (keywords = keyword_patterns_rule(p)) // keyword_patterns + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_2 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')'")); + 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_MatchClass ( cls , patterns , CHECK ( asdl_identifier_seq * , _PyPegen_map_names_to_ids ( p , CHECK ( asdl_expr_seq * , _PyPegen_get_pattern_keys ( p , keywords ) ) ) ) , CHECK ( asdl_pattern_seq * , _PyPegen_get_patterns ( p , keywords ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s class_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')'")); + } + if (p->call_invalid_rules) { // invalid_class_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_class_pattern")); + void *invalid_class_pattern_var; + if ( + (invalid_class_pattern_var = invalid_class_pattern_rule(p)) // invalid_class_pattern + ) + { + D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_class_pattern")); + _res = invalid_class_pattern_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s class_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_class_pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// positional_patterns: ','.pattern+ +static asdl_pattern_seq* +positional_patterns_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_pattern_seq* _res = NULL; + int _mark = p->mark; + { // ','.pattern+ + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_62_rule(p)) // ','.pattern+ + ) + { + D(fprintf(stderr, "%*c+ positional_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.pattern+")); + _res = args; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s positional_patterns[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.pattern+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// keyword_patterns: ','.keyword_pattern+ +static asdl_seq* +keyword_patterns_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq* _res = NULL; + int _mark = p->mark; + { // ','.keyword_pattern+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> keyword_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); + asdl_seq * _gather_64_var; + if ( + (_gather_64_var = _gather_64_rule(p)) // ','.keyword_pattern+ + ) + { + D(fprintf(stderr, "%*c+ keyword_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); + _res = _gather_64_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s keyword_patterns[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.keyword_pattern+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// keyword_pattern: NAME '=' pattern +static KeyPatternPair* +keyword_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + KeyPatternPair* _res = NULL; + int _mark = p->mark; + { // NAME '=' pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> keyword_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' pattern")); + Token * _literal; + expr_ty arg; + pattern_ty value; + if ( + (arg = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (value = pattern_rule(p)) // pattern + ) + { + D(fprintf(stderr, "%*c+ keyword_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' pattern")); + _res = _PyPegen_key_pattern_pair ( p , arg , value ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s keyword_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// return_stmt: 'return' star_expressions? +static stmt_ty +return_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'return' star_expressions? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> return_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?")); + Token * _keyword; + void *a; + if ( + (_keyword = _PyPegen_expect_token(p, 500)) // token='return' + && + (a = star_expressions_rule(p), !p->error_indicator) // star_expressions? + ) + { + D(fprintf(stderr, "%*c+ return_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?")); + 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_Return ( a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s return_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'return' star_expressions?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// raise_stmt: 'raise' expression ['from' expression] | 'raise' +static stmt_ty +raise_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + { // 'raise' expression ['from' expression] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]")); + Token * _keyword; + expr_ty a; + void *b; + if ( + (_keyword = _PyPegen_expect_token(p, 501)) // token='raise' + && + (a = expression_rule(p)) // expression + && + (b = _tmp_66_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]")); + 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_Raise ( a , 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 raise_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'raise' expression ['from' expression]")); + } + { // 'raise' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 501)) // token='raise' + ) + { + D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise'")); + 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_Raise ( NULL , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s raise_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'raise'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// function_def: decorators function_def_raw | function_def_raw +static stmt_ty +function_def_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + stmt_ty _res = NULL; + int _mark = p->mark; + { // decorators function_def_raw + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw")); + asdl_expr_seq* d; + stmt_ty f; + if ( + (d = decorators_rule(p)) // decorators + && + (f = function_def_raw_rule(p)) // function_def_raw + ) + { + D(fprintf(stderr, "%*c+ function_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw")); + _res = _PyPegen_function_def_decorators ( p , d , f ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s function_def[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "decorators function_def_raw")); + } + { // function_def_raw + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "function_def_raw")); + stmt_ty function_def_raw_var; + if ( + (function_def_raw_var = function_def_raw_rule(p)) // function_def_raw + ) + { + D(fprintf(stderr, "%*c+ function_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "function_def_raw")); + _res = function_def_raw_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s function_def[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "function_def_raw")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// function_def_raw: +// | invalid_def_raw +// | 'def' NAME '(' params? ')' ['->' expression] &&':' func_type_comment? block +// | ASYNC 'def' NAME '(' 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(); + } + 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 + if (p->call_invalid_rules) { // invalid_def_raw + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_def_raw")); + void *invalid_def_raw_var; + if ( + (invalid_def_raw_var = invalid_def_raw_rule(p)) // invalid_def_raw + ) + { + D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_def_raw")); + _res = invalid_def_raw_var; + goto done; + } + 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, "invalid_def_raw")); + } + { // 'def' NAME '(' 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")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *a; + asdl_stmt_seq* b; + expr_ty n; + void *params; + void *tc; + if ( + (_keyword = _PyPegen_expect_token(p, 526)) // token='def' + && + (n = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (params = params_rule(p), !p->error_indicator) // params? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (a = _tmp_67_rule(p), !p->error_indicator) // ['->' expression] + && + (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (tc = func_type_comment_rule(p), !p->error_indicator) // func_type_comment? + && + (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")); + 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_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + 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")); + } + { // ASYNC 'def' NAME '(' 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")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *a; + Token * async_var; + asdl_stmt_seq* b; + expr_ty n; + void *params; + void *tc; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + && + (_keyword = _PyPegen_expect_token(p, 526)) // token='def' + && + (n = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (params = params_rule(p), !p->error_indicator) // params? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (a = _tmp_68_rule(p), !p->error_indicator) // ['->' expression] + && + (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (tc = func_type_comment_rule(p), !p->error_indicator) // func_type_comment? + && + (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")); + 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 , 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 ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + 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")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// func_type_comment: +// | NEWLINE TYPE_COMMENT &(NEWLINE INDENT) +// | invalid_double_type_comments +// | TYPE_COMMENT +static Token* +func_type_comment_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + Token* _res = NULL; + int _mark = p->mark; + { // NEWLINE TYPE_COMMENT &(NEWLINE INDENT) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); + Token * newline_var; + Token * t; + if ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + (t = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' + && + _PyPegen_lookahead(1, _tmp_69_rule, p) + ) + { + D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); + _res = t; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s func_type_comment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); + } + if (p->call_invalid_rules) { // invalid_double_type_comments + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_double_type_comments")); + void *invalid_double_type_comments_var; + if ( + (invalid_double_type_comments_var = invalid_double_type_comments_rule(p)) // invalid_double_type_comments + ) + { + D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_double_type_comments")); + _res = invalid_double_type_comments_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s func_type_comment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_double_type_comments")); + } + { // TYPE_COMMENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT")); + Token * type_comment_var; + if ( + (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' + ) + { + D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT")); + _res = type_comment_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s func_type_comment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "TYPE_COMMENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// params: invalid_parameters | parameters +static arguments_ty +params_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arguments_ty _res = NULL; + int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_parameters + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_parameters")); + void *invalid_parameters_var; + if ( + (invalid_parameters_var = invalid_parameters_rule(p)) // invalid_parameters + ) + { + D(fprintf(stderr, "%*c+ params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_parameters")); + _res = invalid_parameters_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s params[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_parameters")); + } + { // parameters + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "parameters")); + arguments_ty parameters_var; + if ( + (parameters_var = parameters_rule(p)) // parameters + ) + { + D(fprintf(stderr, "%*c+ params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "parameters")); + _res = parameters_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s params[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "parameters")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// parameters: +// | slash_no_default param_no_default* param_with_default* star_etc? +// | slash_with_default param_with_default* star_etc? +// | param_no_default+ param_with_default* star_etc? +// | param_with_default+ star_etc? +// | star_etc +static arguments_ty +parameters_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arguments_ty _res = NULL; + int _mark = p->mark; + { // slash_no_default param_no_default* param_with_default* star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); + asdl_arg_seq* a; + asdl_arg_seq* b; + asdl_seq * c; + void *d; + if ( + (a = slash_no_default_rule(p)) // slash_no_default + && + (b = (asdl_arg_seq*)_loop0_70_rule(p)) // param_no_default* + && + (c = _loop0_71_rule(p)) // param_with_default* + && + (d = star_etc_rule(p), !p->error_indicator) // star_etc? + ) + { + D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); + _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); + } + { // slash_with_default param_with_default* star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); + SlashWithDefault* a; + asdl_seq * b; + void *c; + if ( + (a = slash_with_default_rule(p)) // slash_with_default + && + (b = _loop0_72_rule(p)) // param_with_default* + && + (c = star_etc_rule(p), !p->error_indicator) // star_etc? + ) + { + D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); + _res = _PyPegen_make_arguments ( p , NULL , a , NULL , 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 parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default param_with_default* star_etc?")); + } + { // param_no_default+ param_with_default* star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); + asdl_arg_seq* a; + asdl_seq * b; + void *c; + if ( + (a = (asdl_arg_seq*)_loop1_73_rule(p)) // param_no_default+ + && + (b = _loop0_74_rule(p)) // param_with_default* + && + (c = star_etc_rule(p), !p->error_indicator) // star_etc? + ) + { + D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); + _res = _PyPegen_make_arguments ( p , NULL , NULL , a , 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 parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); + } + { // param_with_default+ star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+ star_etc?")); + asdl_seq * a; + void *b; + if ( + (a = _loop1_75_rule(p)) // param_with_default+ + && + (b = star_etc_rule(p), !p->error_indicator) // star_etc? + ) + { + D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+ star_etc?")); + _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+ star_etc?")); + } + { // star_etc + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_etc")); + StarEtc* a; + if ( + (a = star_etc_rule(p)) // star_etc + ) + { + D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_etc")); + _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_etc")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// slash_no_default: param_no_default+ '/' ',' | param_no_default+ '/' &')' +static asdl_arg_seq* +slash_no_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_arg_seq* _res = NULL; + int _mark = p->mark; + { // param_no_default+ '/' ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','")); + Token * _literal; + Token * _literal_1; + asdl_arg_seq* a; + if ( + (a = (asdl_arg_seq*)_loop1_76_rule(p)) // param_no_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','")); + _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 slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default+ '/' ','")); + } + { // param_no_default+ '/' &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'")); + Token * _literal; + asdl_arg_seq* a; + if ( + (a = (asdl_arg_seq*)_loop1_77_rule(p)) // param_no_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'")); + _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 slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default+ '/' &')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// slash_with_default: +// | param_no_default* param_with_default+ '/' ',' +// | param_no_default* param_with_default+ '/' &')' +static SlashWithDefault* +slash_with_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + SlashWithDefault* _res = NULL; + int _mark = p->mark; + { // param_no_default* param_with_default+ '/' ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); + Token * _literal; + Token * _literal_1; + asdl_seq * a; + asdl_seq * b; + if ( + (a = _loop0_78_rule(p)) // param_no_default* + && + (b = _loop1_79_rule(p)) // param_with_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); + } + { // param_no_default* param_with_default+ '/' &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); + Token * _literal; + asdl_seq * a; + asdl_seq * b; + if ( + (a = _loop0_80_rule(p)) // param_no_default* + && + (b = _loop1_81_rule(p)) // param_with_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_etc: +// | '*' param_no_default param_maybe_default* kwds? +// | '*' ',' param_maybe_default+ kwds? +// | kwds +// | invalid_star_etc +static StarEtc* +star_etc_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + StarEtc* _res = NULL; + int _mark = p->mark; + { // '*' param_no_default param_maybe_default* kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); + Token * _literal; + arg_ty a; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = param_no_default_rule(p)) // param_no_default + && + (b = _loop0_82_rule(p)) // param_maybe_default* + && + (c = kwds_rule(p), !p->error_indicator) // kwds? + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); + _res = _PyPegen_star_etc ( p , a , 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 star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); + } + { // '*' ',' param_maybe_default+ kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); + Token * _literal; + Token * _literal_1; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (b = _loop1_83_rule(p)) // param_maybe_default+ + && + (c = kwds_rule(p), !p->error_indicator) // kwds? + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); + _res = _PyPegen_star_etc ( p , NULL , 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 star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); + } + { // kwds + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwds")); + arg_ty a; + if ( + (a = kwds_rule(p)) // kwds + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwds")); + _res = _PyPegen_star_etc ( p , NULL , NULL , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwds")); + } + if (p->call_invalid_rules) { // invalid_star_etc + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); + void *invalid_star_etc_var; + if ( + (invalid_star_etc_var = invalid_star_etc_rule(p)) // invalid_star_etc + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); + _res = invalid_star_etc_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_star_etc")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// kwds: '**' param_no_default +static arg_ty +kwds_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + { // '**' param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param_no_default")); + Token * _literal; + arg_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (a = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param_no_default")); + _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 kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param_no_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// param_no_default: param ',' TYPE_COMMENT? | param TYPE_COMMENT? &')' +static arg_ty +param_no_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + { // param ',' TYPE_COMMENT? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param ',' TYPE_COMMENT?")); + Token * _literal; + arg_ty a; + void *tc; + if ( + (a = param_rule(p)) // param + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + ) + { + D(fprintf(stderr, "%*c+ param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param ',' TYPE_COMMENT?")); + _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param ',' TYPE_COMMENT?")); + } + { // param TYPE_COMMENT? &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param TYPE_COMMENT? &')'")); + arg_ty a; + void *tc; + if ( + (a = param_rule(p)) // param + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param TYPE_COMMENT? &')'")); + _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param TYPE_COMMENT? &')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// param_with_default: param default ',' TYPE_COMMENT? | param default TYPE_COMMENT? &')' +static NameDefaultPair* +param_with_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + NameDefaultPair* _res = NULL; + int _mark = p->mark; + { // param default ',' TYPE_COMMENT? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default ',' TYPE_COMMENT?")); + Token * _literal; + arg_ty a; + expr_ty c; + void *tc; + if ( + (a = param_rule(p)) // param + && + (c = default_rule(p)) // default + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + ) + { + D(fprintf(stderr, "%*c+ param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default ',' TYPE_COMMENT?")); + _res = _PyPegen_name_default_pair ( p , a , c , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default ',' TYPE_COMMENT?")); + } + { // param default TYPE_COMMENT? &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default TYPE_COMMENT? &')'")); + arg_ty a; + expr_ty c; + void *tc; + if ( + (a = param_rule(p)) // param + && + (c = default_rule(p)) // default + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default TYPE_COMMENT? &')'")); + _res = _PyPegen_name_default_pair ( p , a , c , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default TYPE_COMMENT? &')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// param_maybe_default: +// | param default? ',' TYPE_COMMENT? +// | param default? TYPE_COMMENT? &')' +static NameDefaultPair* +param_maybe_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + NameDefaultPair* _res = NULL; + int _mark = p->mark; + { // param default? ',' TYPE_COMMENT? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? ',' TYPE_COMMENT?")); + Token * _literal; + arg_ty a; + void *c; + void *tc; + if ( + (a = param_rule(p)) // param + && + (c = default_rule(p), !p->error_indicator) // default? + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + ) + { + D(fprintf(stderr, "%*c+ param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default? ',' TYPE_COMMENT?")); + _res = _PyPegen_name_default_pair ( p , a , c , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default? ',' TYPE_COMMENT?")); + } + { // param default? TYPE_COMMENT? &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? TYPE_COMMENT? &')'")); + arg_ty a; + void *c; + void *tc; + if ( + (a = param_rule(p)) // param + && + (c = default_rule(p), !p->error_indicator) // default? + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default? TYPE_COMMENT? &')'")); + _res = _PyPegen_name_default_pair ( p , a , c , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default? TYPE_COMMENT? &')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// param: NAME annotation? +static arg_ty +param_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_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 + { // NAME annotation? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME annotation?")); + expr_ty a; + void *b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (b = annotation_rule(p), !p->error_indicator) // annotation? + ) + { + D(fprintf(stderr, "%*c+ param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME annotation?")); + 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_arg ( a -> v . Name . id , b , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME annotation?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// annotation: ':' expression +static expr_ty +annotation_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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> annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression")); + _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 annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// default: '=' expression +static expr_ty +default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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> default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' expression")); + _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 default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// decorators: (('@' named_expression NEWLINE))+ +static asdl_expr_seq* +decorators_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_expr_seq* _res = NULL; + int _mark = p->mark; + { // (('@' named_expression NEWLINE))+ + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_84_rule(p)) // (('@' named_expression NEWLINE))+ + ) + { + D(fprintf(stderr, "%*c+ decorators[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); + _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 decorators[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(('@' named_expression NEWLINE))+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// class_def: decorators class_def_raw | class_def_raw +static stmt_ty +class_def_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + stmt_ty _res = NULL; + int _mark = p->mark; + { // decorators class_def_raw + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw")); + asdl_expr_seq* a; + stmt_ty b; + if ( + (a = decorators_rule(p)) // decorators + && + (b = class_def_raw_rule(p)) // class_def_raw + ) + { + D(fprintf(stderr, "%*c+ class_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw")); + _res = _PyPegen_class_def_decorators ( p , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s class_def[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "decorators class_def_raw")); + } + { // class_def_raw + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "class_def_raw")); + stmt_ty class_def_raw_var; + if ( + (class_def_raw_var = class_def_raw_rule(p)) // class_def_raw + ) + { + D(fprintf(stderr, "%*c+ class_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "class_def_raw")); + _res = class_def_raw_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s class_def[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "class_def_raw")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// class_def_raw: invalid_class_def_raw | 'class' NAME ['(' arguments? ')'] &&':' block +static stmt_ty +class_def_raw_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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 + if (p->call_invalid_rules) { // invalid_class_def_raw + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_class_def_raw")); + void *invalid_class_def_raw_var; + if ( + (invalid_class_def_raw_var = invalid_class_def_raw_rule(p)) // invalid_class_def_raw + ) + { + D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_class_def_raw")); + _res = invalid_class_def_raw_var; + goto done; + } + 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, "invalid_class_def_raw")); + } + { // 'class' NAME ['(' 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")); + Token * _keyword; + Token * _literal; + expr_ty a; + void *b; + asdl_stmt_seq* c; + if ( + (_keyword = _PyPegen_expect_token(p, 527)) // token='class' + && + (a = _PyPegen_name_token(p)) // NAME + && + (b = _tmp_85_rule(p), !p->error_indicator) // ['(' arguments? ')'] + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_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")); + 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_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + 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")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// block: NEWLINE INDENT statements DEDENT | simple_stmts | invalid_block +static asdl_stmt_seq* +block_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_stmt_seq* _res = NULL; + if (_PyPegen_is_memoized(p, block_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + { // NEWLINE INDENT statements DEDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT")); + asdl_stmt_seq* a; + Token * dedent_var; + Token * indent_var; + Token * newline_var; + if ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' + && + (a = statements_rule(p)) // statements + && + (dedent_var = _PyPegen_expect_token(p, DEDENT)) // token='DEDENT' + ) + { + D(fprintf(stderr, "%*c+ block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT")); + _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 block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT statements DEDENT")); + } + { // simple_stmts + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmts")); + asdl_stmt_seq* simple_stmts_var; + if ( + (simple_stmts_var = simple_stmts_rule(p)) // simple_stmts + ) + { + D(fprintf(stderr, "%*c+ block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmts")); + _res = simple_stmts_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmts")); + } + if (p->call_invalid_rules) { // invalid_block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_block")); + void *invalid_block_var; + if ( + (invalid_block_var = invalid_block_rule(p)) // invalid_block + ) + { + D(fprintf(stderr, "%*c+ block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_block")); + _res = invalid_block_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_block")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, block_type, _res); + p->level--; + return _res; +} + +// star_expressions: +// | star_expression ((',' star_expression))+ ','? +// | star_expression ',' +// | star_expression +static expr_ty +star_expressions_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // star_expression ((',' star_expression))+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_expression))+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + asdl_seq * b; + if ( + (a = star_expression_rule(p)) // star_expression + && + (b = _loop1_86_rule(p)) // ((',' star_expression))+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_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 = _PyAST_Tuple ( CHECK ( asdl_expr_seq * , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expression ((',' star_expression))+ ','?")); + } + { // star_expression ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ','")); + Token * _literal; + expr_ty a; + if ( + (a = star_expression_rule(p)) // star_expression + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_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 = _PyAST_Tuple ( CHECK ( asdl_expr_seq * , _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expression ','")); + } + { // star_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression")); + expr_ty star_expression_var; + if ( + (star_expression_var = star_expression_rule(p)) // star_expression + ) + { + D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression")); + _res = star_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_expression: '*' bitwise_or | expression +static expr_ty +star_expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, star_expression_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 + { // '*' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ star_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); + 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_Starred ( a , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' bitwise_or")); + } + { // expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ star_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); + _res = expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, star_expression_type, _res); + p->level--; + return _res; +} + +// star_named_expressions: ','.star_named_expression+ ','? +static asdl_expr_seq* +star_named_expressions_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_expr_seq* _res = NULL; + int _mark = p->mark; + { // ','.star_named_expression+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_named_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_expr_seq* a; + if ( + (a = (asdl_expr_seq*)_gather_87_rule(p)) // ','.star_named_expression+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ star_named_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?")); + _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 star_named_expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.star_named_expression+ ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_named_expression: '*' bitwise_or | named_expression +static expr_ty +star_named_expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '*' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ star_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); + 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_Starred ( a , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' bitwise_or")); + } + { // named_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_named_expression[%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+ star_named_expression[%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 star_named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// assignment_expression: NAME ':=' ~ expression +static expr_ty +assignment_expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 ':=' ~ expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> assignment_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ expression")); + int _cut_var = 0; + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + && + (_cut_var = 1) + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ assignment_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ 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 = _PyAST_NamedExpr ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , 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 assignment_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ':=' ~ expression")); + if (_cut_var) { + p->level--; + return NULL; + } + } + _res = NULL; + done: + p->level--; + return _res; +} + +// named_expression: assignment_expression | invalid_named_expression | expression !':=' +static expr_ty +named_expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // assignment_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> named_expression[%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+ named_expression[%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 named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); + } + if (p->call_invalid_rules) { // invalid_named_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_named_expression")); + void *invalid_named_expression_var; + if ( + (invalid_named_expression_var = invalid_named_expression_rule(p)) // invalid_named_expression + ) + { + D(fprintf(stderr, "%*c+ named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_named_expression")); + _res = invalid_named_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_named_expression")); + } + { // expression !':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + _res = expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// annotated_rhs: yield_expr | star_expressions +static expr_ty +annotated_rhs_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> annotated_rhs[%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+ annotated_rhs[%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 annotated_rhs[%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> annotated_rhs[%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+ annotated_rhs[%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 annotated_rhs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _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(); + } + 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; + 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 + { // expression ((',' expression))+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ((',' expression))+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + asdl_seq * b; + if ( + (a = expression_rule(p)) // expression + && + (b = _loop1_89_rule(p)) // ((',' expression))+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ((',' 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 = _PyAST_Tuple ( CHECK ( asdl_expr_seq * , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ((',' expression))+ ','?")); + } + { // expression ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ','")); + Token * _literal; + expr_ty a; + if ( + (a = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "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 = _PyAST_Tuple ( CHECK ( asdl_expr_seq * , _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ','")); + } + { // expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); + _res = expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expressions[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// expression: +// | invalid_expression +// | invalid_legacy_expression +// | disjunction 'if' disjunction 'else' expression +// | disjunction +// | lambdef +static expr_ty +expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, expression_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 + if (p->call_invalid_rules) { // invalid_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_expression")); + void *invalid_expression_var; + if ( + (invalid_expression_var = invalid_expression_rule(p)) // invalid_expression + ) + { + D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_expression")); + _res = invalid_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_expression")); + } + if (p->call_invalid_rules) { // invalid_legacy_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_legacy_expression")); + void *invalid_legacy_expression_var; + if ( + (invalid_legacy_expression_var = invalid_legacy_expression_rule(p)) // invalid_legacy_expression + ) + { + D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_legacy_expression")); + _res = invalid_legacy_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_legacy_expression")); + } + { // disjunction 'if' disjunction 'else' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); + Token * _keyword; + Token * _keyword_1; + expr_ty a; + expr_ty b; + expr_ty c; + if ( + (a = disjunction_rule(p)) // disjunction + && + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (b = disjunction_rule(p)) // disjunction + && + (_keyword_1 = _PyPegen_expect_token(p, 516)) // token='else' + && + (c = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' 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 = _PyAST_IfExp ( b , a , c , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); + } + { // disjunction + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction")); + expr_ty disjunction_var; + if ( + (disjunction_var = disjunction_rule(p)) // disjunction + ) + { + D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction")); + _res = disjunction_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction")); + } + { // lambdef + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambdef")); + expr_ty lambdef_var; + if ( + (lambdef_var = lambdef_rule(p)) // lambdef + ) + { + D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambdef")); + _res = lambdef_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambdef")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, expression_type, _res); + p->level--; + return _res; +} + +// lambdef: 'lambda' lambda_params? ':' expression +static expr_ty +lambdef_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // 'lambda' lambda_params? ':' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambdef[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression")); + Token * _keyword; + Token * _literal; + void *a; + expr_ty b; + if ( + (_keyword = _PyPegen_expect_token(p, 528)) // token='lambda' + && + (a = lambda_params_rule(p), !p->error_indicator) // lambda_params? + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ lambdef[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_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 = _PyAST_Lambda ( ( a ) ? a : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , 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 lambdef[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_params: invalid_lambda_parameters | lambda_parameters +static arguments_ty +lambda_params_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arguments_ty _res = NULL; + int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_lambda_parameters + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters")); + void *invalid_lambda_parameters_var; + if ( + (invalid_lambda_parameters_var = invalid_lambda_parameters_rule(p)) // invalid_lambda_parameters + ) + { + D(fprintf(stderr, "%*c+ lambda_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters")); + _res = invalid_lambda_parameters_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_params[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_parameters")); + } + { // lambda_parameters + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_parameters")); + arguments_ty lambda_parameters_var; + if ( + (lambda_parameters_var = lambda_parameters_rule(p)) // lambda_parameters + ) + { + D(fprintf(stderr, "%*c+ lambda_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_parameters")); + _res = lambda_parameters_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_params[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_parameters")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_parameters: +// | lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc? +// | lambda_slash_with_default lambda_param_with_default* lambda_star_etc? +// | lambda_param_no_default+ lambda_param_with_default* lambda_star_etc? +// | lambda_param_with_default+ lambda_star_etc? +// | lambda_star_etc +static arguments_ty +lambda_parameters_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arguments_ty _res = NULL; + int _mark = p->mark; + { // lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); + asdl_arg_seq* a; + asdl_arg_seq* b; + asdl_seq * c; + void *d; + if ( + (a = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + && + (b = (asdl_arg_seq*)_loop0_90_rule(p)) // lambda_param_no_default* + && + (c = _loop0_91_rule(p)) // lambda_param_with_default* + && + (d = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? + ) + { + D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); + _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); + } + { // lambda_slash_with_default lambda_param_with_default* lambda_star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); + SlashWithDefault* a; + asdl_seq * b; + void *c; + if ( + (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + && + (b = _loop0_92_rule(p)) // lambda_param_with_default* + && + (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? + ) + { + D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); + _res = _PyPegen_make_arguments ( p , NULL , a , NULL , 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 lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); + } + { // lambda_param_no_default+ lambda_param_with_default* lambda_star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); + asdl_arg_seq* a; + asdl_seq * b; + void *c; + if ( + (a = (asdl_arg_seq*)_loop1_93_rule(p)) // lambda_param_no_default+ + && + (b = _loop0_94_rule(p)) // lambda_param_with_default* + && + (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? + ) + { + D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); + _res = _PyPegen_make_arguments ( p , NULL , NULL , a , 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 lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); + } + { // lambda_param_with_default+ lambda_star_etc? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); + asdl_seq * a; + void *b; + if ( + (a = _loop1_95_rule(p)) // lambda_param_with_default+ + && + (b = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? + ) + { + D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); + _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); + } + { // lambda_star_etc + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_star_etc")); + StarEtc* a; + if ( + (a = lambda_star_etc_rule(p)) // lambda_star_etc + ) + { + D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_star_etc")); + _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_star_etc")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_slash_no_default: +// | lambda_param_no_default+ '/' ',' +// | lambda_param_no_default+ '/' &':' +static asdl_arg_seq* +lambda_slash_no_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_arg_seq* _res = NULL; + int _mark = p->mark; + { // lambda_param_no_default+ '/' ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','")); + Token * _literal; + Token * _literal_1; + asdl_arg_seq* a; + if ( + (a = (asdl_arg_seq*)_loop1_96_rule(p)) // lambda_param_no_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ lambda_slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','")); + _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 lambda_slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default+ '/' ','")); + } + { // lambda_param_no_default+ '/' &':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'")); + Token * _literal; + asdl_arg_seq* a; + if ( + (a = (asdl_arg_seq*)_loop1_97_rule(p)) // lambda_param_no_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' + ) + { + D(fprintf(stderr, "%*c+ lambda_slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'")); + _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 lambda_slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default+ '/' &':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_slash_with_default: +// | lambda_param_no_default* lambda_param_with_default+ '/' ',' +// | lambda_param_no_default* lambda_param_with_default+ '/' &':' +static SlashWithDefault* +lambda_slash_with_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + SlashWithDefault* _res = NULL; + int _mark = p->mark; + { // lambda_param_no_default* lambda_param_with_default+ '/' ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); + Token * _literal; + Token * _literal_1; + asdl_seq * a; + asdl_seq * b; + if ( + (a = _loop0_98_rule(p)) // lambda_param_no_default* + && + (b = _loop1_99_rule(p)) // lambda_param_with_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); + } + { // lambda_param_no_default* lambda_param_with_default+ '/' &':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); + Token * _literal; + asdl_seq * a; + asdl_seq * b; + if ( + (a = _loop0_100_rule(p)) // lambda_param_no_default* + && + (b = _loop1_101_rule(p)) // lambda_param_with_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' + ) + { + D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_star_etc: +// | '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? +// | '*' ',' lambda_param_maybe_default+ lambda_kwds? +// | lambda_kwds +// | invalid_lambda_star_etc +static StarEtc* +lambda_star_etc_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + StarEtc* _res = NULL; + int _mark = p->mark; + { // '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); + Token * _literal; + arg_ty a; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = lambda_param_no_default_rule(p)) // lambda_param_no_default + && + (b = _loop0_102_rule(p)) // lambda_param_maybe_default* + && + (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); + _res = _PyPegen_star_etc ( p , a , 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 lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); + } + { // '*' ',' lambda_param_maybe_default+ lambda_kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); + Token * _literal; + Token * _literal_1; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (b = _loop1_103_rule(p)) // lambda_param_maybe_default+ + && + (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); + _res = _PyPegen_star_etc ( p , NULL , 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 lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); + } + { // lambda_kwds + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); + arg_ty a; + if ( + (a = lambda_kwds_rule(p)) // lambda_kwds + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); + _res = _PyPegen_star_etc ( p , NULL , NULL , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_kwds")); + } + if (p->call_invalid_rules) { // invalid_lambda_star_etc + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); + void *invalid_lambda_star_etc_var; + if ( + (invalid_lambda_star_etc_var = invalid_lambda_star_etc_rule(p)) // invalid_lambda_star_etc + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); + _res = invalid_lambda_star_etc_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_star_etc")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_kwds: '**' lambda_param_no_default +static arg_ty +lambda_kwds_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + { // '**' lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param_no_default")); + Token * _literal; + arg_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (a = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + D(fprintf(stderr, "%*c+ lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param_no_default")); + _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 lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param_no_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_param_no_default: lambda_param ',' | lambda_param &':' +static arg_ty +lambda_param_no_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + { // lambda_param ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param ','")); + Token * _literal; + arg_ty a; + if ( + (a = lambda_param_rule(p)) // lambda_param + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ lambda_param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_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 lambda_param_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param ','")); + } + { // lambda_param &':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param &':'")); + arg_ty a; + if ( + (a = lambda_param_rule(p)) // lambda_param + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' + ) + { + D(fprintf(stderr, "%*c+ lambda_param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_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 lambda_param_no_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param &':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_param_with_default: lambda_param default ',' | lambda_param default &':' +static NameDefaultPair* +lambda_param_with_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + NameDefaultPair* _res = NULL; + int _mark = p->mark; + { // lambda_param default ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default ','")); + Token * _literal; + arg_ty a; + expr_ty c; + if ( + (a = lambda_param_rule(p)) // lambda_param + && + (c = default_rule(p)) // default + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ lambda_param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default ','")); + _res = _PyPegen_name_default_pair ( p , a , c , NULL ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_param_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default ','")); + } + { // lambda_param default &':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default &':'")); + arg_ty a; + expr_ty c; + if ( + (a = lambda_param_rule(p)) // lambda_param + && + (c = default_rule(p)) // default + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' + ) + { + D(fprintf(stderr, "%*c+ lambda_param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default &':'")); + _res = _PyPegen_name_default_pair ( p , a , c , NULL ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_param_with_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default &':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_param_maybe_default: lambda_param default? ',' | lambda_param default? &':' +static NameDefaultPair* +lambda_param_maybe_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + NameDefaultPair* _res = NULL; + int _mark = p->mark; + { // lambda_param default? ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? ','")); + Token * _literal; + arg_ty a; + void *c; + if ( + (a = lambda_param_rule(p)) // lambda_param + && + (c = default_rule(p), !p->error_indicator) // default? + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ lambda_param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default? ','")); + _res = _PyPegen_name_default_pair ( p , a , c , NULL ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default? ','")); + } + { // lambda_param default? &':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? &':'")); + arg_ty a; + void *c; + if ( + (a = lambda_param_rule(p)) // lambda_param + && + (c = default_rule(p), !p->error_indicator) // default? + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' + ) + { + D(fprintf(stderr, "%*c+ lambda_param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default? &':'")); + _res = _PyPegen_name_default_pair ( p , a , c , NULL ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default? &':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lambda_param: NAME +static arg_ty +lambda_param_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_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 + { // NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); + expr_ty a; + if ( + (a = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ lambda_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_arg ( a -> v . Name . id , NULL , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_param[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// disjunction: conjunction (('or' conjunction))+ | conjunction +static expr_ty +disjunction_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, disjunction_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 + { // conjunction (('or' conjunction))+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); + expr_ty a; + asdl_seq * b; + if ( + (a = conjunction_rule(p)) // conjunction + && + (b = _loop1_104_rule(p)) // (('or' conjunction))+ + ) + { + D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); + 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_BoolOp ( Or , CHECK ( asdl_expr_seq * , _PyPegen_seq_insert_in_front ( p , a , 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 disjunction[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "conjunction (('or' conjunction))+")); + } + { // conjunction + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction")); + expr_ty conjunction_var; + if ( + (conjunction_var = conjunction_rule(p)) // conjunction + ) + { + D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction")); + _res = conjunction_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s disjunction[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "conjunction")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, disjunction_type, _res); + p->level--; + return _res; +} + +// conjunction: inversion (('and' inversion))+ | inversion +static expr_ty +conjunction_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, conjunction_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 + { // inversion (('and' inversion))+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); + expr_ty a; + asdl_seq * b; + if ( + (a = inversion_rule(p)) // inversion + && + (b = _loop1_105_rule(p)) // (('and' inversion))+ + ) + { + D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); + 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_BoolOp ( And , CHECK ( asdl_expr_seq * , _PyPegen_seq_insert_in_front ( p , a , 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 conjunction[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "inversion (('and' inversion))+")); + } + { // inversion + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion")); + expr_ty inversion_var; + if ( + (inversion_var = inversion_rule(p)) // inversion + ) + { + D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion")); + _res = inversion_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s conjunction[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "inversion")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, conjunction_type, _res); + p->level--; + return _res; +} + +// inversion: 'not' inversion | comparison +static expr_ty +inversion_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, inversion_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 + { // 'not' inversion + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' inversion")); + Token * _keyword; + expr_ty a; + if ( + (_keyword = _PyPegen_expect_token(p, 529)) // token='not' + && + (a = inversion_rule(p)) // inversion + ) + { + D(fprintf(stderr, "%*c+ inversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'not' inversion")); + 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_UnaryOp ( Not , a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s inversion[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'not' inversion")); + } + { // comparison + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "comparison")); + expr_ty comparison_var; + if ( + (comparison_var = comparison_rule(p)) // comparison + ) + { + D(fprintf(stderr, "%*c+ inversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "comparison")); + _res = comparison_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s inversion[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "comparison")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, inversion_type, _res); + p->level--; + return _res; +} + +// comparison: bitwise_or compare_op_bitwise_or_pair+ | bitwise_or +static expr_ty +comparison_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // bitwise_or compare_op_bitwise_or_pair+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); + expr_ty a; + asdl_seq * b; + if ( + (a = bitwise_or_rule(p)) // bitwise_or + && + (b = _loop1_106_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+")); + 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_Compare ( a , CHECK ( asdl_int_seq * , _PyPegen_get_cmpops ( p , b ) ) , CHECK ( asdl_expr_seq * , _PyPegen_get_exprs ( p , 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 comparison[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); + } + { // bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or")); + expr_ty bitwise_or_var; + if ( + (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or")); + _res = bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s comparison[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// compare_op_bitwise_or_pair: +// | eq_bitwise_or +// | noteq_bitwise_or +// | lte_bitwise_or +// | lt_bitwise_or +// | gte_bitwise_or +// | gt_bitwise_or +// | notin_bitwise_or +// | in_bitwise_or +// | isnot_bitwise_or +// | is_bitwise_or +static CmpopExprPair* +compare_op_bitwise_or_pair_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // eq_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "eq_bitwise_or")); + CmpopExprPair* eq_bitwise_or_var; + if ( + (eq_bitwise_or_var = eq_bitwise_or_rule(p)) // eq_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "eq_bitwise_or")); + _res = eq_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "eq_bitwise_or")); + } + { // noteq_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "noteq_bitwise_or")); + CmpopExprPair* noteq_bitwise_or_var; + if ( + (noteq_bitwise_or_var = noteq_bitwise_or_rule(p)) // noteq_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "noteq_bitwise_or")); + _res = noteq_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "noteq_bitwise_or")); + } + { // lte_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lte_bitwise_or")); + CmpopExprPair* lte_bitwise_or_var; + if ( + (lte_bitwise_or_var = lte_bitwise_or_rule(p)) // lte_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lte_bitwise_or")); + _res = lte_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lte_bitwise_or")); + } + { // lt_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lt_bitwise_or")); + CmpopExprPair* lt_bitwise_or_var; + if ( + (lt_bitwise_or_var = lt_bitwise_or_rule(p)) // lt_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lt_bitwise_or")); + _res = lt_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lt_bitwise_or")); + } + { // gte_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gte_bitwise_or")); + CmpopExprPair* gte_bitwise_or_var; + if ( + (gte_bitwise_or_var = gte_bitwise_or_rule(p)) // gte_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "gte_bitwise_or")); + _res = gte_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "gte_bitwise_or")); + } + { // gt_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gt_bitwise_or")); + CmpopExprPair* gt_bitwise_or_var; + if ( + (gt_bitwise_or_var = gt_bitwise_or_rule(p)) // gt_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "gt_bitwise_or")); + _res = gt_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "gt_bitwise_or")); + } + { // notin_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "notin_bitwise_or")); + CmpopExprPair* notin_bitwise_or_var; + if ( + (notin_bitwise_or_var = notin_bitwise_or_rule(p)) // notin_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "notin_bitwise_or")); + _res = notin_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "notin_bitwise_or")); + } + { // in_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "in_bitwise_or")); + CmpopExprPair* in_bitwise_or_var; + if ( + (in_bitwise_or_var = in_bitwise_or_rule(p)) // in_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "in_bitwise_or")); + _res = in_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "in_bitwise_or")); + } + { // isnot_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "isnot_bitwise_or")); + CmpopExprPair* isnot_bitwise_or_var; + if ( + (isnot_bitwise_or_var = isnot_bitwise_or_rule(p)) // isnot_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "isnot_bitwise_or")); + _res = isnot_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "isnot_bitwise_or")); + } + { // is_bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "is_bitwise_or")); + CmpopExprPair* is_bitwise_or_var; + if ( + (is_bitwise_or_var = is_bitwise_or_rule(p)) // is_bitwise_or + ) + { + D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "is_bitwise_or")); + _res = is_bitwise_or_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "is_bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// eq_bitwise_or: '==' bitwise_or +static CmpopExprPair* +eq_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // '==' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> eq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'==' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 27)) // token='==' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ eq_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'==' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , Eq , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s eq_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'==' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// noteq_bitwise_or: ('!=') bitwise_or +static CmpopExprPair* +noteq_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // ('!=') bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); + void *_tmp_107_var; + expr_ty a; + if ( + (_tmp_107_var = _tmp_107_rule(p)) // '!=' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ noteq_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , NotEq , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s noteq_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('!=') bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lte_bitwise_or: '<=' bitwise_or +static CmpopExprPair* +lte_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // '<=' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<=' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 29)) // token='<=' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ lte_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<=' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , LtE , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lte_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'<=' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// lt_bitwise_or: '<' bitwise_or +static CmpopExprPair* +lt_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // '<' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 20)) // token='<' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ lt_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , Lt , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lt_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'<' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// gte_bitwise_or: '>=' bitwise_or +static CmpopExprPair* +gte_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // '>=' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> gte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>=' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 30)) // token='>=' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ gte_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>=' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , GtE , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s gte_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'>=' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// gt_bitwise_or: '>' bitwise_or +static CmpopExprPair* +gt_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // '>' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> gt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 21)) // token='>' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ gt_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , Gt , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s gt_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'>' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// notin_bitwise_or: 'not' 'in' bitwise_or +static CmpopExprPair* +notin_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // 'not' 'in' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> notin_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' 'in' bitwise_or")); + Token * _keyword; + Token * _keyword_1; + expr_ty a; + if ( + (_keyword = _PyPegen_expect_token(p, 529)) // token='not' + && + (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ notin_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'not' 'in' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , NotIn , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s notin_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'not' 'in' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// in_bitwise_or: 'in' bitwise_or +static CmpopExprPair* +in_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // 'in' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> in_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'in' bitwise_or")); + Token * _keyword; + expr_ty a; + if ( + (_keyword = _PyPegen_expect_token(p, 518)) // token='in' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ in_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'in' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , In , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s in_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'in' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// isnot_bitwise_or: 'is' 'not' bitwise_or +static CmpopExprPair* +isnot_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // 'is' 'not' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> isnot_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' 'not' bitwise_or")); + Token * _keyword; + Token * _keyword_1; + expr_ty a; + if ( + (_keyword = _PyPegen_expect_token(p, 530)) // token='is' + && + (_keyword_1 = _PyPegen_expect_token(p, 529)) // token='not' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ isnot_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'is' 'not' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , IsNot , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s isnot_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'is' 'not' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// is_bitwise_or: 'is' bitwise_or +static CmpopExprPair* +is_bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + CmpopExprPair* _res = NULL; + int _mark = p->mark; + { // 'is' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> is_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' bitwise_or")); + Token * _keyword; + expr_ty a; + if ( + (_keyword = _PyPegen_expect_token(p, 530)) // token='is' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ is_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'is' bitwise_or")); + _res = _PyPegen_cmpop_expr_pair ( p , Is , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s is_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'is' bitwise_or")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// bitwise_or: bitwise_or '|' bitwise_xor | bitwise_xor +static expr_ty bitwise_or_raw(Parser *); +static expr_ty +bitwise_or_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, bitwise_or_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_2 = _PyPegen_update_memo(p, _mark, bitwise_or_type, _res); + if (tmpvar_2) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = bitwise_or_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +bitwise_or_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // bitwise_or '|' bitwise_xor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = bitwise_or_rule(p)) // bitwise_or + && + (_literal = _PyPegen_expect_token(p, 18)) // token='|' + && + (b = bitwise_xor_rule(p)) // bitwise_xor + ) + { + D(fprintf(stderr, "%*c+ bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor")); + 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_BinOp ( a , BitOr , 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 bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_or '|' bitwise_xor")); + } + { // bitwise_xor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor")); + expr_ty bitwise_xor_var; + if ( + (bitwise_xor_var = bitwise_xor_rule(p)) // bitwise_xor + ) + { + D(fprintf(stderr, "%*c+ bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_xor")); + _res = bitwise_xor_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_xor")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// bitwise_xor: bitwise_xor '^' bitwise_and | bitwise_and +static expr_ty bitwise_xor_raw(Parser *); +static expr_ty +bitwise_xor_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, bitwise_xor_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_3 = _PyPegen_update_memo(p, _mark, bitwise_xor_type, _res); + if (tmpvar_3) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = bitwise_xor_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +bitwise_xor_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // bitwise_xor '^' bitwise_and + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = bitwise_xor_rule(p)) // bitwise_xor + && + (_literal = _PyPegen_expect_token(p, 32)) // token='^' + && + (b = bitwise_and_rule(p)) // bitwise_and + ) + { + D(fprintf(stderr, "%*c+ bitwise_xor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and")); + 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_BinOp ( a , BitXor , 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 bitwise_xor[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_xor '^' bitwise_and")); + } + { // bitwise_and + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and")); + expr_ty bitwise_and_var; + if ( + (bitwise_and_var = bitwise_and_rule(p)) // bitwise_and + ) + { + D(fprintf(stderr, "%*c+ bitwise_xor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_and")); + _res = bitwise_and_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s bitwise_xor[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_and")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// bitwise_and: bitwise_and '&' shift_expr | shift_expr +static expr_ty bitwise_and_raw(Parser *); +static expr_ty +bitwise_and_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, bitwise_and_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_4 = _PyPegen_update_memo(p, _mark, bitwise_and_type, _res); + if (tmpvar_4) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = bitwise_and_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +bitwise_and_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // bitwise_and '&' shift_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = bitwise_and_rule(p)) // bitwise_and + && + (_literal = _PyPegen_expect_token(p, 19)) // token='&' + && + (b = shift_expr_rule(p)) // shift_expr + ) + { + D(fprintf(stderr, "%*c+ bitwise_and[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr")); + 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_BinOp ( a , BitAnd , 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 bitwise_and[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_and '&' shift_expr")); + } + { // shift_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr")); + expr_ty shift_expr_var; + if ( + (shift_expr_var = shift_expr_rule(p)) // shift_expr + ) + { + D(fprintf(stderr, "%*c+ bitwise_and[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr")); + _res = shift_expr_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s bitwise_and[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "shift_expr")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// shift_expr: shift_expr '<<' sum | shift_expr '>>' sum | sum +static expr_ty shift_expr_raw(Parser *); +static expr_ty +shift_expr_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, shift_expr_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_5 = _PyPegen_update_memo(p, _mark, shift_expr_type, _res); + if (tmpvar_5) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = shift_expr_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +shift_expr_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // shift_expr '<<' sum + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = shift_expr_rule(p)) // shift_expr + && + (_literal = _PyPegen_expect_token(p, 33)) // token='<<' + && + (b = sum_rule(p)) // sum + ) + { + D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum")); + 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_BinOp ( a , LShift , 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 shift_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "shift_expr '<<' sum")); + } + { // shift_expr '>>' sum + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = shift_expr_rule(p)) // shift_expr + && + (_literal = _PyPegen_expect_token(p, 34)) // token='>>' + && + (b = sum_rule(p)) // sum + ) + { + D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum")); + 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_BinOp ( a , RShift , 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 shift_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "shift_expr '>>' sum")); + } + { // sum + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum")); + expr_ty sum_var; + if ( + (sum_var = sum_rule(p)) // sum + ) + { + D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum")); + _res = sum_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s shift_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "sum")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// sum: sum '+' term | sum '-' term | term +static expr_ty sum_raw(Parser *); +static expr_ty +sum_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, sum_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_6 = _PyPegen_update_memo(p, _mark, sum_type, _res); + if (tmpvar_6) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = sum_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +sum_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // sum '+' term + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '+' term")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = sum_rule(p)) // sum + && + (_literal = _PyPegen_expect_token(p, 14)) // token='+' + && + (b = term_rule(p)) // term + ) + { + D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '+' term")); + 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_BinOp ( a , Add , 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 sum[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "sum '+' term")); + } + { // sum '-' term + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '-' term")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = sum_rule(p)) // sum + && + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + && + (b = term_rule(p)) // term + ) + { + D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '-' term")); + 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_BinOp ( a , Sub , 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 sum[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "sum '-' term")); + } + { // term + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term")); + expr_ty term_var; + if ( + (term_var = term_rule(p)) // term + ) + { + D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term")); + _res = term_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s sum[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// term: +// | term '*' factor +// | term '/' factor +// | term '//' factor +// | term '%' factor +// | term '@' factor +// | factor +static expr_ty term_raw(Parser *); +static expr_ty +term_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, term_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_7 = _PyPegen_update_memo(p, _mark, term_type, _res); + if (tmpvar_7) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = term_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +term_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // term '*' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '*' factor")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = term_rule(p)) // term + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (b = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '*' factor")); + 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_BinOp ( a , Mult , 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 term[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '*' factor")); + } + { // term '/' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '/' factor")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = term_rule(p)) // term + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (b = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '/' factor")); + 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_BinOp ( a , Div , 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 term[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '/' factor")); + } + { // term '//' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '//' factor")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = term_rule(p)) // term + && + (_literal = _PyPegen_expect_token(p, 47)) // token='//' + && + (b = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '//' factor")); + 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_BinOp ( a , FloorDiv , 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 term[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '//' factor")); + } + { // term '%' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '%' factor")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = term_rule(p)) // term + && + (_literal = _PyPegen_expect_token(p, 24)) // token='%' + && + (b = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '%' factor")); + 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_BinOp ( a , Mod , 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 term[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '%' factor")); + } + { // term '@' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '@' factor")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = term_rule(p)) // term + && + (_literal = _PyPegen_expect_token(p, 49)) // token='@' + && + (b = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '@' factor")); + 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 ( expr_ty , 5 , "The '@' operator is" , _PyAST_BinOp ( a , MatMult , 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 term[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '@' factor")); + } + { // factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "factor")); + expr_ty factor_var; + if ( + (factor_var = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "factor")); + _res = factor_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s term[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "factor")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// factor: '+' factor | '-' factor | '~' factor | power +static expr_ty +factor_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, factor_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 + { // '+' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+' factor")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 14)) // token='+' + && + (a = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+' factor")); + 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_UnaryOp ( UAdd , a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+' factor")); + } + { // '-' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' factor")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + && + (a = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' factor")); + 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_UnaryOp ( USub , a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-' factor")); + } + { // '~' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'~' factor")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 31)) // token='~' + && + (a = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'~' factor")); + 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_UnaryOp ( Invert , a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'~' factor")); + } + { // power + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "power")); + expr_ty power_var; + if ( + (power_var = power_rule(p)) // power + ) + { + D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "power")); + _res = power_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "power")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, factor_type, _res); + p->level--; + return _res; +} + +// power: await_primary '**' factor | await_primary +static expr_ty +power_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // await_primary '**' factor + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = await_primary_rule(p)) // await_primary + && + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (b = factor_rule(p)) // factor + ) + { + D(fprintf(stderr, "%*c+ power[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor")); + 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_BinOp ( a , Pow , 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 power[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "await_primary '**' factor")); + } + { // await_primary + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary")); + expr_ty await_primary_var; + if ( + (await_primary_var = await_primary_rule(p)) // await_primary + ) + { + D(fprintf(stderr, "%*c+ power[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "await_primary")); + _res = await_primary_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s power[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "await_primary")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// await_primary: AWAIT primary | primary +static expr_ty +await_primary_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, await_primary_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 + { // AWAIT primary + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); + expr_ty a; + Token * await_var; + if ( + (await_var = _PyPegen_expect_token(p, AWAIT)) // token='AWAIT' + && + (a = primary_rule(p)) // primary + ) + { + D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); + 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 ( expr_ty , 5 , "Await expressions are" , _PyAST_Await ( a , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s await_primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "AWAIT primary")); + } + { // primary + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary")); + expr_ty primary_var; + if ( + (primary_var = primary_rule(p)) // primary + ) + { + D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary")); + _res = primary_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s await_primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, await_primary_type, _res); + p->level--; + return _res; +} + +// Left-recursive +// primary: +// | primary '.' NAME +// | primary genexp +// | primary '(' arguments? ')' +// | primary '[' slices ']' +// | atom +static expr_ty primary_raw(Parser *); +static expr_ty +primary_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, primary_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_8 = _PyPegen_update_memo(p, _mark, primary_type, _res); + if (tmpvar_8) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = primary_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +primary_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // primary '.' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '.' NAME")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = primary_rule(p)) // primary + && + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + && + (b = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '.' 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_Attribute ( a , b -> v . Name . id , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary '.' NAME")); + } + { // primary genexp + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary genexp")); + expr_ty a; + expr_ty b; + if ( + (a = primary_rule(p)) // primary + && + (b = genexp_rule(p)) // genexp + ) + { + D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary genexp")); + 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_Call ( a , CHECK ( asdl_expr_seq * , ( asdl_expr_seq * ) _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary genexp")); + } + { // primary '(' arguments? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + void *b; + if ( + (a = primary_rule(p)) // primary + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (b = arguments_rule(p), !p->error_indicator) // arguments? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'")); + 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_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary '(' arguments? ')'")); + } + { // primary '[' slices ']' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + expr_ty b; + if ( + (a = primary_rule(p)) // primary + && + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (b = slices_rule(p)) // slices + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + ) + { + D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'")); + 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_Subscript ( a , b , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary '[' slices ']'")); + } + { // atom + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom")); + expr_ty atom_var; + if ( + (atom_var = atom_rule(p)) // atom + ) + { + D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "atom")); + _res = atom_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "atom")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// slices: slice !',' | ','.slice+ ','? +static expr_ty +slices_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // slice !',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice !','")); + expr_ty a; + if ( + (a = slice_rule(p)) // slice + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 12) // token=',' + ) + { + D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice !','")); + _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 slices[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice !','")); + } + { // ','.slice+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_expr_seq* a; + if ( + (a = (asdl_expr_seq*)_gather_108_rule(p)) // ','.slice+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); + 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_Tuple ( a , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s slices[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.slice+ ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// slice: expression? ':' expression? [':' expression?] | named_expression +static expr_ty +slice_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // expression? ':' expression? [':' expression?] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]")); + Token * _literal; + void *a; + void *b; + void *c; + if ( + (a = expression_rule(p), !p->error_indicator) // expression? + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = expression_rule(p), !p->error_indicator) // expression? + && + (c = _tmp_110_rule(p), !p->error_indicator) // [':' expression?] + ) + { + D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' 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 = _PyAST_Slice ( a , b , c , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s slice[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression? ':' expression? [':' expression?]")); + } + { // named_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); + expr_ty a; + if ( + (a = named_expression_rule(p)) // named_expression + ) + { + D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); + _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 slice[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// atom: +// | NAME +// | 'True' +// | 'False' +// | 'None' +// | &STRING strings +// | NUMBER +// | &'(' (tuple | group | genexp) +// | &'[' (list | listcomp) +// | &'{' (dict | set | dictcomp | setcomp) +// | '...' +static expr_ty +atom_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); + expr_ty name_var; + if ( + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); + _res = name_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, "NAME")); + } + { // 'True' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 524)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + 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_Constant ( Py_True , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'True'")); + } + { // 'False' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 525)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + 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_Constant ( Py_False , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'False'")); + } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 523)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + 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_Constant ( Py_None , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'None'")); + } + { // &STRING 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")); + expr_ty strings_var; + if ( + _PyPegen_lookahead(1, _PyPegen_string_token, p) + && + (strings_var = strings_rule(p)) // strings + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&STRING 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")); + } + { // NUMBER + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); + expr_ty number_var; + if ( + (number_var = _PyPegen_number_token(p)) // NUMBER + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NUMBER")); + _res = number_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, "NUMBER")); + } + { // &'(' (tuple | group | genexp) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); + void *_tmp_111_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 7) // token='(' + && + (_tmp_111_var = _tmp_111_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_111_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, "&'(' (tuple | group | genexp)")); + } + { // &'[' (list | listcomp) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); + void *_tmp_112_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 9) // token='[' + && + (_tmp_112_var = _tmp_112_rule(p)) // list | listcomp + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); + _res = _tmp_112_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, "&'[' (list | listcomp)")); + } + { // &'{' (dict | set | dictcomp | setcomp) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); + void *_tmp_113_var; + if ( + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 25) // token='{' + && + (_tmp_113_var = _tmp_113_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_113_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, "&'{' (dict | set | dictcomp | setcomp)")); + } + { // '...' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 52)) // token='...' + ) + { + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + 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_Constant ( Py_Ellipsis , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'...'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// strings: STRING+ +static expr_ty +strings_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, strings_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + { // 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; + if ( + (a = _loop1_114_rule(p)) // STRING+ + ) + { + D(fprintf(stderr, "%*c+ strings[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING+")); + _res = _PyPegen_concatenate_strings ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s strings[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING+")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, strings_type, _res); + p->level--; + return _res; +} + +// list: '[' star_named_expressions? ']' +static expr_ty +list_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '[' star_named_expressions? ']' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> list[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (a = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + ) + { + D(fprintf(stderr, "%*c+ list[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'")); + 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_List ( a , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s list[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' star_named_expressions? ']'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// listcomp: '[' named_expression for_if_clauses ']' | invalid_comprehension +static expr_ty +listcomp_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '[' named_expression for_if_clauses ']' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' named_expression for_if_clauses ']'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + asdl_comprehension_seq* b; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (a = named_expression_rule(p)) // named_expression + && + (b = for_if_clauses_rule(p)) // for_if_clauses + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + ) + { + D(fprintf(stderr, "%*c+ listcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' named_expression for_if_clauses ']'")); + 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_ListComp ( a , 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 listcomp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' named_expression for_if_clauses ']'")); + } + if (p->call_invalid_rules) { // invalid_comprehension + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); + void *invalid_comprehension_var; + if ( + (invalid_comprehension_var = invalid_comprehension_rule(p)) // invalid_comprehension + ) + { + D(fprintf(stderr, "%*c+ listcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); + _res = invalid_comprehension_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s listcomp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_comprehension")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// tuple: '(' [star_named_expression ',' star_named_expressions?] ')' +static expr_ty +tuple_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '(' [star_named_expression ',' star_named_expressions?] ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> tuple[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = _tmp_115_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ tuple[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); + 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_Tuple ( a , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s tuple[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// group: '(' (yield_expr | named_expression) ')' | invalid_group +static expr_ty +group_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // '(' (yield_expr | named_expression) ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = _tmp_116_rule(p)) // yield_expr | named_expression + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); + _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 group[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); + } + if (p->call_invalid_rules) { // invalid_group + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_group")); + void *invalid_group_var; + if ( + (invalid_group_var = invalid_group_rule(p)) // invalid_group + ) + { + D(fprintf(stderr, "%*c+ group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_group")); + _res = invalid_group_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s group[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_group")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// genexp: +// | '(' (assignment_expression | expression !':=') for_if_clauses ')' +// | invalid_comprehension +static expr_ty +genexp_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '(' (assignment_expression | expression !':=') for_if_clauses ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' (assignment_expression | expression !':=') for_if_clauses ')'")); + Token * _literal; + Token * _literal_1; + void *a; + asdl_comprehension_seq* b; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = _tmp_117_rule(p)) // assignment_expression | expression !':=' + && + (b = for_if_clauses_rule(p)) // for_if_clauses + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' (assignment_expression | expression !':=') for_if_clauses ')'")); + 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_GeneratorExp ( a , 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 genexp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' (assignment_expression | expression !':=') for_if_clauses ')'")); + } + if (p->call_invalid_rules) { // invalid_comprehension + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); + void *invalid_comprehension_var; + if ( + (invalid_comprehension_var = invalid_comprehension_rule(p)) // invalid_comprehension + ) + { + D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); + _res = invalid_comprehension_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s genexp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_comprehension")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// set: '{' star_named_expressions '}' +static expr_ty +set_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '{' star_named_expressions '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> set[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'")); + Token * _literal; + Token * _literal_1; + asdl_expr_seq* a; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = star_named_expressions_rule(p)) // star_named_expressions + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ set[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'")); + 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_Set ( a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s set[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' star_named_expressions '}'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// setcomp: '{' named_expression for_if_clauses '}' | invalid_comprehension +static expr_ty +setcomp_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '{' named_expression for_if_clauses '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' named_expression for_if_clauses '}'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + asdl_comprehension_seq* b; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = named_expression_rule(p)) // named_expression + && + (b = for_if_clauses_rule(p)) // for_if_clauses + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ setcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' named_expression for_if_clauses '}'")); + 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_SetComp ( a , 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 setcomp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' named_expression for_if_clauses '}'")); + } + if (p->call_invalid_rules) { // invalid_comprehension + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); + void *invalid_comprehension_var; + if ( + (invalid_comprehension_var = invalid_comprehension_rule(p)) // invalid_comprehension + ) + { + D(fprintf(stderr, "%*c+ setcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); + _res = invalid_comprehension_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s setcomp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_comprehension")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// dict: '{' double_starred_kvpairs? '}' | '{' invalid_double_starred_kvpairs '}' +static expr_ty +dict_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '{' double_starred_kvpairs? '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> dict[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = double_starred_kvpairs_rule(p), !p->error_indicator) // double_starred_kvpairs? + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ dict[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'")); + 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_Dict ( CHECK ( asdl_expr_seq * , _PyPegen_get_keys ( p , a ) ) , CHECK ( asdl_expr_seq * , _PyPegen_get_values ( p , a ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s dict[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' double_starred_kvpairs? '}'")); + } + { // '{' invalid_double_starred_kvpairs '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> dict[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' invalid_double_starred_kvpairs '}'")); + Token * _literal; + Token * _literal_1; + void *invalid_double_starred_kvpairs_var; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (invalid_double_starred_kvpairs_var = invalid_double_starred_kvpairs_rule(p)) // invalid_double_starred_kvpairs + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ dict[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' invalid_double_starred_kvpairs '}'")); + _res = _PyPegen_dummy_name(p, _literal, invalid_double_starred_kvpairs_var, _literal_1); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s dict[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' invalid_double_starred_kvpairs '}'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// dictcomp: '{' kvpair for_if_clauses '}' | invalid_dict_comprehension +static expr_ty +dictcomp_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '{' kvpair for_if_clauses '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'")); + Token * _literal; + Token * _literal_1; + KeyValuePair* a; + asdl_comprehension_seq* b; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = kvpair_rule(p)) // kvpair + && + (b = for_if_clauses_rule(p)) // for_if_clauses + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ dictcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'")); + 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_DictComp ( a -> key , a -> value , 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 dictcomp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' kvpair for_if_clauses '}'")); + } + if (p->call_invalid_rules) { // invalid_dict_comprehension + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_dict_comprehension")); + void *invalid_dict_comprehension_var; + if ( + (invalid_dict_comprehension_var = invalid_dict_comprehension_rule(p)) // invalid_dict_comprehension + ) + { + D(fprintf(stderr, "%*c+ dictcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_dict_comprehension")); + _res = invalid_dict_comprehension_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s dictcomp[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_dict_comprehension")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// double_starred_kvpairs: ','.double_starred_kvpair+ ','? +static asdl_seq* +double_starred_kvpairs_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq* _res = NULL; + int _mark = p->mark; + { // ','.double_starred_kvpair+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_seq * a; + if ( + (a = _gather_118_rule(p)) // ','.double_starred_kvpair+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ','?")); + _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 double_starred_kvpairs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.double_starred_kvpair+ ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// double_starred_kvpair: '**' bitwise_or | kvpair +static KeyValuePair* +double_starred_kvpair_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + KeyValuePair* _res = NULL; + int _mark = p->mark; + { // '**' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (a = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ double_starred_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or")); + _res = _PyPegen_key_value_pair ( p , NULL , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s double_starred_kvpair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' bitwise_or")); + } + { // kvpair + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kvpair")); + KeyValuePair* kvpair_var; + if ( + (kvpair_var = kvpair_rule(p)) // kvpair + ) + { + D(fprintf(stderr, "%*c+ double_starred_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kvpair")); + _res = kvpair_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s double_starred_kvpair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kvpair")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// kvpair: expression ':' expression +static KeyValuePair* +kvpair_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + KeyValuePair* _res = NULL; + int _mark = p->mark; + { // expression ':' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); + _res = _PyPegen_key_value_pair ( p , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kvpair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// for_if_clauses: for_if_clause+ +static asdl_comprehension_seq* +for_if_clauses_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_comprehension_seq* _res = NULL; + int _mark = p->mark; + { // for_if_clause+ + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_120_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+")); + _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 for_if_clauses[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// for_if_clause: +// | ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))* +// | 'for' star_targets 'in' ~ disjunction (('if' disjunction))* +// | invalid_for_target +static comprehension_ty +for_if_clause_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + comprehension_ty _res = NULL; + int _mark = p->mark; + { // ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))* + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + int _cut_var = 0; + Token * _keyword; + Token * _keyword_1; + expr_ty a; + Token * async_var; + expr_ty b; + asdl_expr_seq* c; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + && + (_keyword = _PyPegen_expect_token(p, 517)) // token='for' + && + (a = star_targets_rule(p)) // star_targets + && + (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' + && + (_cut_var = 1) + && + (b = disjunction_rule(p)) // 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, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + _res = CHECK_VERSION ( comprehension_ty , 6 , "Async comprehensions are" , _PyAST_comprehension ( a , b , c , 1 , p -> arena ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + if (_cut_var) { + p->level--; + return NULL; + } + } + { // 'for' star_targets 'in' ~ disjunction (('if' disjunction))* + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + int _cut_var = 0; + Token * _keyword; + Token * _keyword_1; + expr_ty a; + expr_ty b; + asdl_expr_seq* c; + if ( + (_keyword = _PyPegen_expect_token(p, 517)) // token='for' + && + (a = star_targets_rule(p)) // star_targets + && + (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' + && + (_cut_var = 1) + && + (b = disjunction_rule(p)) // disjunction + && + (c = (asdl_expr_seq*)_loop0_122_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))*")); + _res = _PyAST_comprehension ( a , b , c , 0 , p -> arena ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + if (_cut_var) { + p->level--; + return NULL; + } + } + if (p->call_invalid_rules) { // invalid_for_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); + void *invalid_for_target_var; + if ( + (invalid_for_target_var = invalid_for_target_rule(p)) // invalid_for_target + ) + { + D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); + _res = invalid_for_target_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_for_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// yield_expr: 'yield' 'from' expression | 'yield' star_expressions? +static expr_ty +yield_expr_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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' 'from' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' 'from' expression")); + Token * _keyword; + Token * _keyword_1; + expr_ty a; + if ( + (_keyword = _PyPegen_expect_token(p, 504)) // token='yield' + && + (_keyword_1 = _PyPegen_expect_token(p, 514)) // token='from' + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' 'from' 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 = _PyAST_YieldFrom ( a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s yield_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'yield' 'from' expression")); + } + { // 'yield' star_expressions? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?")); + Token * _keyword; + void *a; + if ( + (_keyword = _PyPegen_expect_token(p, 504)) // token='yield' + && + (a = star_expressions_rule(p), !p->error_indicator) // star_expressions? + ) + { + D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?")); + 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_Yield ( a , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s yield_expr[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'yield' star_expressions?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// arguments: args ','? &')' | invalid_arguments +static expr_ty +arguments_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, arguments_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + { // args ','? &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','? &')'")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + if ( + (a = args_rule(p)) // args + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','? &')'")); + _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 arguments[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ','? &')'")); + } + if (p->call_invalid_rules) { // invalid_arguments + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_arguments")); + void *invalid_arguments_var; + if ( + (invalid_arguments_var = invalid_arguments_rule(p)) // invalid_arguments + ) + { + D(fprintf(stderr, "%*c+ arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_arguments")); + _res = invalid_arguments_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s arguments[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_arguments")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, arguments_type, _res); + p->level--; + return _res; +} + +// args: +// | ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs] +// | kwargs +static expr_ty +args_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs]")); + asdl_expr_seq* a; + void *b; + if ( + (a = (asdl_expr_seq*)_gather_123_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ + && + (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]")); + 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_collect_call_seqs ( p , a , 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 args[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs]")); + } + { // kwargs + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwargs")); + asdl_seq* a; + if ( + (a = kwargs_rule(p)) // kwargs + ) + { + D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwargs")); + 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_Call ( _PyPegen_dummy_name ( p ) , CHECK_NULL_ALLOWED ( asdl_expr_seq * , _PyPegen_seq_extract_starred_exprs ( p , a ) ) , CHECK_NULL_ALLOWED ( asdl_keyword_seq * , _PyPegen_seq_delete_starred_exprs ( p , a ) ) , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s args[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwargs")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// kwargs: +// | ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+ +// | ','.kwarg_or_starred+ +// | ','.kwarg_or_double_starred+ +static asdl_seq* +kwargs_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq* _res = NULL; + int _mark = p->mark; + { // ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); + Token * _literal; + asdl_seq * a; + asdl_seq * b; + if ( + (a = _gather_126_rule(p)) // ','.kwarg_or_starred+ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (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+")); + _res = _PyPegen_join_sequences ( p , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwargs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); + } + { // ','.kwarg_or_starred+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); + asdl_seq * _gather_130_var; + if ( + (_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_130_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwargs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.kwarg_or_starred+")); + } + { // ','.kwarg_or_double_starred+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); + asdl_seq * _gather_132_var; + if ( + (_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_132_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwargs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.kwarg_or_double_starred+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// starred_expression: '*' expression +static expr_ty +starred_expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // '*' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' 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 = _PyAST_Starred ( a , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'*' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// kwarg_or_starred: invalid_kwarg | NAME '=' expression | starred_expression +static KeywordOrStarred* +kwarg_or_starred_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + KeywordOrStarred* _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 + if (p->call_invalid_rules) { // invalid_kwarg + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); + void *invalid_kwarg_var; + if ( + (invalid_kwarg_var = invalid_kwarg_rule(p)) // invalid_kwarg + ) + { + D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); + _res = invalid_kwarg_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwarg_or_starred[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_kwarg")); + } + { // NAME '=' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' 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 = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwarg_or_starred[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' expression")); + } + { // starred_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty a; + if ( + (a = starred_expression_rule(p)) // starred_expression + ) + { + D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = _PyPegen_keyword_or_starred ( p , a , 0 ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwarg_or_starred[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// kwarg_or_double_starred: invalid_kwarg | NAME '=' expression | '**' expression +static KeywordOrStarred* +kwarg_or_double_starred_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + KeywordOrStarred* _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 + if (p->call_invalid_rules) { // invalid_kwarg + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); + void *invalid_kwarg_var; + if ( + (invalid_kwarg_var = invalid_kwarg_rule(p)) // invalid_kwarg + ) + { + D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); + _res = invalid_kwarg_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwarg_or_double_starred[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_kwarg")); + } + { // NAME '=' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' 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 = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwarg_or_double_starred[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' expression")); + } + { // '**' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' 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 = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( NULL , a , EXTRA ) ) , 1 ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwarg_or_double_starred[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_targets: star_target !',' | star_target ((',' star_target))* ','? +static expr_ty +star_targets_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // star_target !',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target !','")); + expr_ty a; + if ( + (a = star_target_rule(p)) // star_target + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 12) // token=',' + ) + { + D(fprintf(stderr, "%*c+ star_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target !','")); + _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 star_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target !','")); + } + { // star_target ((',' star_target))* ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + asdl_seq * b; + if ( + (a = star_target_rule(p)) // star_target + && + (b = _loop0_134_rule(p)) // ((',' star_target))* + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ star_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?")); + 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_Tuple ( CHECK ( asdl_expr_seq * , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ((',' star_target))* ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_targets_list_seq: ','.star_target+ ','? +static asdl_expr_seq* +star_targets_list_seq_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_expr_seq* _res = NULL; + int _mark = p->mark; + { // ','.star_target+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_targets_list_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_expr_seq* a; + if ( + (a = (asdl_expr_seq*)_gather_135_rule(p)) // ','.star_target+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ star_targets_list_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?")); + _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 star_targets_list_seq[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.star_target+ ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_targets_tuple_seq: star_target ((',' star_target))+ ','? | star_target ',' +static asdl_expr_seq* +star_targets_tuple_seq_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_expr_seq* _res = NULL; + int _mark = p->mark; + { // star_target ((',' star_target))+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + asdl_seq * b; + if ( + (a = star_target_rule(p)) // star_target + && + (b = _loop1_137_rule(p)) // ((',' star_target))+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?")); + _res = ( asdl_expr_seq * ) _PyPegen_seq_insert_in_front ( p , a , b ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_targets_tuple_seq[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ((',' star_target))+ ','?")); + } + { // star_target ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ','")); + Token * _literal; + expr_ty a; + if ( + (a = star_target_rule(p)) // star_target + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ','")); + _res = ( asdl_expr_seq * ) _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_targets_tuple_seq[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// star_target: '*' (!'*' star_target) | target_with_star_atom +static expr_ty +star_target_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, star_target_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 + { // '*' (!'*' star_target) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); + Token * _literal; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (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)")); + 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_Starred ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (!'*' star_target)")); + } + { // target_with_star_atom + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target_with_star_atom")); + expr_ty target_with_star_atom_var; + if ( + (target_with_star_atom_var = target_with_star_atom_rule(p)) // target_with_star_atom + ) + { + D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "target_with_star_atom")); + _res = target_with_star_atom_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "target_with_star_atom")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, star_target_type, _res); + p->level--; + return _res; +} + +// target_with_star_atom: +// | t_primary '.' NAME !t_lookahead +// | t_primary '[' slices ']' !t_lookahead +// | star_atom +static expr_ty +target_with_star_atom_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, target_with_star_atom_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 + { // t_primary '.' NAME !t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + && + (b = _PyPegen_name_token(p)) // NAME + && + _PyPegen_lookahead(0, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + 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_Attribute ( a , b -> v . Name . id , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + } + { // t_primary '[' slices ']' !t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + Token * _literal; + Token * _literal_1; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (b = slices_rule(p)) // slices + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + && + _PyPegen_lookahead(0, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + 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_Subscript ( a , b , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + } + { // star_atom + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_atom")); + expr_ty star_atom_var; + if ( + (star_atom_var = star_atom_rule(p)) // star_atom + ) + { + D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_atom")); + _res = star_atom_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_atom")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, target_with_star_atom_type, _res); + p->level--; + return _res; +} + +// star_atom: +// | NAME +// | '(' target_with_star_atom ')' +// | '(' star_targets_tuple_seq? ')' +// | '[' star_targets_list_seq? ']' +static expr_ty +star_atom_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); + expr_ty a; + if ( + (a = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); + _res = _PyPegen_set_expr_context ( p , a , Store ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); + } + { // '(' target_with_star_atom ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = target_with_star_atom_rule(p)) // target_with_star_atom + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'")); + _res = _PyPegen_set_expr_context ( p , a , Store ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' target_with_star_atom ')'")); + } + { // '(' star_targets_tuple_seq? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = star_targets_tuple_seq_rule(p), !p->error_indicator) // star_targets_tuple_seq? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); + 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_Tuple ( a , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); + } + { // '[' star_targets_list_seq? ']' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (a = star_targets_list_seq_rule(p), !p->error_indicator) // star_targets_list_seq? + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + ) + { + D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'")); + 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_List ( a , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' star_targets_list_seq? ']'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// single_target: single_subscript_attribute_target | NAME | '(' single_target ')' +static expr_ty +single_target_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // single_subscript_attribute_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> single_target[%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+ single_target[%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 single_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_subscript_attribute_target")); + } + { // NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); + expr_ty a; + if ( + (a = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ single_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); + _res = _PyPegen_set_expr_context ( p , a , Store ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s single_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); + } + { // '(' single_target ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = single_target_rule(p)) // single_target + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ single_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); + _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 single_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' single_target ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// single_subscript_attribute_target: +// | t_primary '.' NAME !t_lookahead +// | t_primary '[' slices ']' !t_lookahead +static expr_ty +single_subscript_attribute_target_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // t_primary '.' NAME !t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + && + (b = _PyPegen_name_token(p)) // NAME + && + _PyPegen_lookahead(0, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + 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_Attribute ( a , b -> v . Name . id , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s single_subscript_attribute_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + } + { // t_primary '[' slices ']' !t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + Token * _literal; + Token * _literal_1; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (b = slices_rule(p)) // slices + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + && + _PyPegen_lookahead(0, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + 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_Subscript ( a , b , Store , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s single_subscript_attribute_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// del_targets: ','.del_target+ ','? +static asdl_expr_seq* +del_targets_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_expr_seq* _res = NULL; + int _mark = p->mark; + { // ','.del_target+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_expr_seq* a; + if ( + (a = (asdl_expr_seq*)_gather_139_rule(p)) // ','.del_target+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ del_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?")); + _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 del_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.del_target+ ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// del_target: +// | t_primary '.' NAME !t_lookahead +// | t_primary '[' slices ']' !t_lookahead +// | del_t_atom +static expr_ty +del_target_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, del_target_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 + { // t_primary '.' NAME !t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + && + (b = _PyPegen_name_token(p)) // NAME + && + _PyPegen_lookahead(0, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + 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_Attribute ( a , b -> v . Name . id , Del , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME !t_lookahead")); + } + { // t_primary '[' slices ']' !t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + Token * _literal; + Token * _literal_1; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (b = slices_rule(p)) // slices + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + && + _PyPegen_lookahead(0, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + 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_Subscript ( a , b , Del , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); + } + { // del_t_atom + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_t_atom")); + expr_ty del_t_atom_var; + if ( + (del_t_atom_var = del_t_atom_rule(p)) // del_t_atom + ) + { + D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_t_atom")); + _res = del_t_atom_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_t_atom")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, del_target_type, _res); + p->level--; + return _res; +} + +// del_t_atom: NAME | '(' del_target ')' | '(' del_targets? ')' | '[' del_targets? ']' +static expr_ty +del_t_atom_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); + expr_ty a; + if ( + (a = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); + _res = _PyPegen_set_expr_context ( p , a , Del ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); + } + { // '(' del_target ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_target ')'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = del_target_rule(p)) // del_target + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' del_target ')'")); + _res = _PyPegen_set_expr_context ( p , a , Del ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' del_target ')'")); + } + { // '(' del_targets? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = del_targets_rule(p), !p->error_indicator) // del_targets? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'")); + 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_Tuple ( a , Del , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' del_targets? ')'")); + } + { // '[' del_targets? ']' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'")); + Token * _literal; + Token * _literal_1; + void *a; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (a = del_targets_rule(p), !p->error_indicator) // del_targets? + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + ) + { + D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'")); + 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_List ( a , Del , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' del_targets? ']'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// Left-recursive +// t_primary: +// | t_primary '.' NAME &t_lookahead +// | t_primary '[' slices ']' &t_lookahead +// | t_primary genexp &t_lookahead +// | t_primary '(' arguments? ')' &t_lookahead +// | atom &t_lookahead +static expr_ty t_primary_raw(Parser *); +static expr_ty +t_primary_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + expr_ty _res = NULL; + if (_PyPegen_is_memoized(p, t_primary_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + int _resmark = p->mark; + while (1) { + int tmpvar_9 = _PyPegen_update_memo(p, _mark, t_primary_type, _res); + if (tmpvar_9) { + p->level--; + return _res; + } + p->mark = _mark; + void *_raw = t_primary_raw(p); + if (p->error_indicator) { + p->level--; + return NULL; + } + if (_raw == NULL || p->mark <= _resmark) + break; + _resmark = p->mark; + _res = _raw; + } + p->mark = _resmark; + p->level--; + return _res; +} +static expr_ty +t_primary_raw(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + 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; + 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 + { // t_primary '.' NAME &t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + && + (b = _PyPegen_name_token(p)) // NAME + && + _PyPegen_lookahead(1, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead")); + 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_Attribute ( a , b -> v . Name . id , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME &t_lookahead")); + } + { // t_primary '[' slices ']' &t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); + Token * _literal; + Token * _literal_1; + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (b = slices_rule(p)) // slices + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + && + _PyPegen_lookahead(1, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); + 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_Subscript ( a , b , Load , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); + } + { // t_primary genexp &t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead")); + expr_ty a; + expr_ty b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (b = genexp_rule(p)) // genexp + && + _PyPegen_lookahead(1, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead")); + 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_Call ( a , CHECK ( asdl_expr_seq * , ( asdl_expr_seq * ) _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary genexp &t_lookahead")); + } + { // t_primary '(' arguments? ')' &t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); + Token * _literal; + Token * _literal_1; + expr_ty a; + void *b; + if ( + (a = t_primary_rule(p)) // t_primary + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (b = arguments_rule(p), !p->error_indicator) // arguments? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + _PyPegen_lookahead(1, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); + 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_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); + } + { // atom &t_lookahead + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom &t_lookahead")); + expr_ty a; + if ( + (a = atom_rule(p)) // atom + && + _PyPegen_lookahead(1, t_lookahead_rule, p) + ) + { + D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "atom &t_lookahead")); + _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 t_primary[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "atom &t_lookahead")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// t_lookahead: '(' | '[' | '.' +static void * +t_lookahead_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; + { // '(' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + ) + { + D(fprintf(stderr, "%*c+ t_lookahead[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s t_lookahead[%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> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { + D(fprintf(stderr, "%*c+ t_lookahead[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s t_lookahead[%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> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + ) + { + D(fprintf(stderr, "%*c+ t_lookahead[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s t_lookahead[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_arguments: +// | args ',' '*' +// | expression for_if_clauses ',' [args | expression for_if_clauses] +// | NAME '=' expression for_if_clauses +// | args for_if_clauses +// | args ',' expression for_if_clauses +// | args ',' args +static void * +invalid_arguments_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; + { // args ',' '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' '*'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + if ( + (a = args_rule(p)) // args + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_literal_1 = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' '*'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "iterable argument unpacking follows 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_arguments[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ',' '*'")); + } + { // expression for_if_clauses ',' [args | expression for_if_clauses] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + asdl_comprehension_seq* b; + if ( + (a = expression_rule(p)) // expression + && + (b = for_if_clauses_rule(p)) // for_if_clauses + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_opt_var = _tmp_141_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]")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , PyPegen_last_item ( b , comprehension_ty ) -> target , "Generator expression must be parenthesized" ); + 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, "expression for_if_clauses ',' [args | expression for_if_clauses]")); + } + { // NAME '=' expression for_if_clauses + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); + expr_ty a; + Token * b; + expr_ty expression_var; + asdl_comprehension_seq* for_if_clauses_var; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + && + (expression_var = expression_rule(p)) // expression + && + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); + 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, "NAME '=' expression for_if_clauses")); + } + { // args for_if_clauses + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args for_if_clauses")); + expr_ty a; + asdl_comprehension_seq* b; + if ( + (a = args_rule(p)) // args + && + (b = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args for_if_clauses")); + _res = _PyPegen_nonparen_genexp_in_call ( p , a , b ); + 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 for_if_clauses")); + } + { // args ',' expression for_if_clauses + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); + Token * _literal; + expr_ty a; + expr_ty args_var; + asdl_comprehension_seq* b; + if ( + (args_var = args_rule(p)) // args + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = expression_rule(p)) // expression + && + (b = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , asdl_seq_GET ( b , b -> size - 1 ) -> target , "Generator expression must be parenthesized" ); + 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 ',' expression for_if_clauses")); + } + { // args ',' args + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' args")); + Token * _literal; + expr_ty a; + expr_ty args_var; + if ( + (a = args_rule(p)) // args + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (args_var = args_rule(p)) // args + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' args")); + _res = _PyPegen_arguments_parsing_error ( p , a ); + 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 ',' args")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_kwarg: +// | ('True' | 'False' | 'None') '=' +// | NAME '=' expression for_if_clauses +// | !(NAME '=') expression '=' +static void * +invalid_kwarg_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; + { // ('True' | 'False' | 'None') '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('True' | 'False' | 'None') '='")); + Token* a; + Token * b; + if ( + (a = (Token*)_tmp_142_rule(p)) // 'True' | 'False' | 'None' + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('True' | 'False' | 'None') '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to %s" , PyBytes_AS_STRING ( a -> bytes ) ); + 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, "('True' | 'False' | 'None') '='")); + } + { // NAME '=' expression for_if_clauses + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); + expr_ty a; + Token * b; + expr_ty expression_var; + asdl_comprehension_seq* for_if_clauses_var; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + && + (expression_var = expression_rule(p)) // expression + && + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); + 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, "NAME '=' expression for_if_clauses")); + } + { // !(NAME '=') expression '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(NAME '=') expression '='")); + expr_ty a; + Token * b; + if ( + _PyPegen_lookahead(0, _tmp_143_rule, p) + && + (a = expression_rule(p)) // expression + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(NAME '=') expression '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expression cannot contain assignment, perhaps you meant \"==\"?" ); + 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, "!(NAME '=') expression '='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// expression_without_invalid: +// | disjunction 'if' disjunction 'else' expression +// | disjunction +// | lambdef +static expr_ty +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(); + } + if (p->error_indicator) { + p->call_invalid_rules = _prev_call_invalid; + 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; + p->call_invalid_rules = _prev_call_invalid; + 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 + { // disjunction 'if' disjunction 'else' expression + if (p->error_indicator) { + p->call_invalid_rules = _prev_call_invalid; + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression_without_invalid[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); + Token * _keyword; + Token * _keyword_1; + expr_ty a; + expr_ty b; + expr_ty c; + if ( + (a = disjunction_rule(p)) // disjunction + && + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (b = disjunction_rule(p)) // disjunction + && + (_keyword_1 = _PyPegen_expect_token(p, 516)) // token='else' + && + (c = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ expression_without_invalid[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->call_invalid_rules = _prev_call_invalid; + 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_IfExp ( b , a , c , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->call_invalid_rules = _prev_call_invalid; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression_without_invalid[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); + } + { // disjunction + if (p->error_indicator) { + p->call_invalid_rules = _prev_call_invalid; + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression_without_invalid[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction")); + expr_ty disjunction_var; + if ( + (disjunction_var = disjunction_rule(p)) // disjunction + ) + { + D(fprintf(stderr, "%*c+ expression_without_invalid[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction")); + _res = disjunction_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression_without_invalid[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction")); + } + { // lambdef + if (p->error_indicator) { + p->call_invalid_rules = _prev_call_invalid; + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> expression_without_invalid[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambdef")); + expr_ty lambdef_var; + if ( + (lambdef_var = lambdef_rule(p)) // lambdef + ) + { + D(fprintf(stderr, "%*c+ expression_without_invalid[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambdef")); + _res = lambdef_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s expression_without_invalid[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambdef")); + } + _res = NULL; + done: + p->call_invalid_rules = _prev_call_invalid; + p->level--; + return _res; +} + +// invalid_legacy_expression: NAME !'(' star_expressions +static void * +invalid_legacy_expression_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; + { // NAME !'(' star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_legacy_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME !'(' star_expressions")); + expr_ty a; + expr_ty b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 7) // token='(' + && + (b = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ invalid_legacy_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME !'(' star_expressions")); + _res = _PyPegen_check_legacy_stmt ( p , a ) ? RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Missing parentheses in call to '%U'. Did you mean %U(...)?" , a -> v . Name . id , a -> v . Name . id ) : NULL; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_legacy_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME !'(' star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_expression: +// | !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid +// | disjunction 'if' disjunction !('else' | ':') +static void * +invalid_expression_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; + { // !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid")); + expr_ty a; + expr_ty b; + if ( + _PyPegen_lookahead(0, _tmp_144_rule, p) + && + (a = disjunction_rule(p)) // disjunction + && + (b = expression_without_invalid_rule(p)) // expression_without_invalid + ) + { + D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid")); + _res = _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?" ); + 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, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid")); + } + { // disjunction 'if' disjunction !('else' | ':') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); + Token * _keyword; + expr_ty a; + expr_ty b; + if ( + (a = disjunction_rule(p)) // disjunction + && + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (b = disjunction_rule(p)) // disjunction + && + _PyPegen_lookahead(0, _tmp_145_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expected 'else' after 'if' 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_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_named_expression: +// | expression ':=' expression +// | NAME '=' bitwise_or !('=' | ':=') +// | !(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=') +static void * +invalid_named_expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + if (_PyPegen_is_memoized(p, invalid_named_expression_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + { // expression ':=' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':=' expression")); + Token * _literal; + expr_ty a; + expr_ty expression_var; + if ( + (a = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + && + (expression_var = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':=' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use assignment expressions with %s" , _PyPegen_get_expr_name ( a ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':=' expression")); + } + { // NAME '=' bitwise_or !('=' | ':=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); + Token * _literal; + expr_ty a; + expr_ty b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = bitwise_or_rule(p)) // bitwise_or + && + _PyPegen_lookahead(0, _tmp_146_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); + } + { // !(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); + expr_ty a; + Token * b; + expr_ty bitwise_or_var; + if ( + _PyPegen_lookahead(0, _tmp_147_rule, p) + && + (a = bitwise_or_rule(p)) // bitwise_or + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + && + (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or + && + _PyPegen_lookahead(0, _tmp_148_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 !('=' | ':=')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot assign to %s here. Maybe you meant '==' instead of '='?" , _PyPegen_get_expr_name ( a ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_named_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, invalid_named_expression_type, _res); + p->level--; + return _res; +} + +// invalid_assignment: +// | invalid_ann_assign_target ':' expression +// | star_named_expression ',' star_named_expressions* ':' expression +// | expression ':' expression +// | ((star_targets '='))* star_expressions '=' +// | ((star_targets '='))* yield_expr '=' +// | star_expressions augassign (yield_expr | star_expressions) +static void * +invalid_assignment_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; + { // invalid_ann_assign_target ':' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_ann_assign_target ':' expression")); + Token * _literal; + expr_ty a; + expr_ty expression_var; + if ( + (a = invalid_ann_assign_target_rule(p)) // invalid_ann_assign_target + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (expression_var = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_ann_assign_target ':' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not %s) can be annotated" , _PyPegen_get_expr_name ( a ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_ann_assign_target ':' expression")); + } + { // star_named_expression ',' star_named_expressions* ':' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_149_var; + expr_ty a; + expr_ty expression_var; + if ( + (a = star_named_expression_rule(p)) // star_named_expression + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_loop0_149_var = _loop0_149_rule(p)) // star_named_expressions* + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + && + (expression_var = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not tuple) can be annotated" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); + } + { // expression ':' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); + Token * _literal; + expr_ty a; + expr_ty expression_var; + if ( + (a = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (expression_var = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "illegal target for annotation" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' expression")); + } + { // ((star_targets '='))* star_expressions '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); + Token * _literal; + asdl_seq * _loop0_150_var; + expr_ty a; + if ( + (_loop0_150_var = _loop0_150_rule(p)) // ((star_targets '='))* + && + (a = star_expressions_rule(p)) // star_expressions + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); + _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))* star_expressions '='")); + } + { // ((star_targets '='))* yield_expr '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); + Token * _literal; + asdl_seq * _loop0_151_var; + expr_ty a; + if ( + (_loop0_151_var = _loop0_151_rule(p)) // ((star_targets '='))* + && + (a = yield_expr_rule(p)) // yield_expr + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "assignment to yield expression not possible" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))* yield_expr '='")); + } + { // star_expressions augassign (yield_expr | star_expressions) + if (p->error_indicator) { + p->level--; + 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_152_var; + expr_ty a; + AugOperator* augassign_var; + if ( + (a = star_expressions_rule(p)) // star_expressions + && + (augassign_var = augassign_rule(p)) // augassign + && + (_tmp_152_var = _tmp_152_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)")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "'%s' is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_ann_assign_target: list | tuple | '(' invalid_ann_assign_target ')' +static expr_ty +invalid_ann_assign_target_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // list + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_ann_assign_target[%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+ invalid_ann_assign_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + _res = list_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_ann_assign_target[%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> invalid_ann_assign_target[%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+ invalid_ann_assign_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + _res = tuple_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_ann_assign_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); + } + { // '(' invalid_ann_assign_target ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' invalid_ann_assign_target ')'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = invalid_ann_assign_target_rule(p)) // invalid_ann_assign_target + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ invalid_ann_assign_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' invalid_ann_assign_target ')'")); + _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 invalid_ann_assign_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' invalid_ann_assign_target ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_del_stmt: 'del' star_expressions +static void * +invalid_del_stmt_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; + { // 'del' star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' star_expressions")); + Token * _keyword; + expr_ty a; + if ( + (_keyword = _PyPegen_expect_token(p, 503)) // token='del' + && + (a = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ invalid_del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' star_expressions")); + _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( DEL_TARGETS , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_del_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'del' star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_block: NEWLINE !INDENT +static void * +invalid_block_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; + { // NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE !INDENT")); + Token * newline_var; + if ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_comprehension: +// | ('[' | '(' | '{') starred_expression for_if_clauses +// | ('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses +// | ('[' | '{') star_named_expression ',' for_if_clauses +static void * +invalid_comprehension_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; + { // ('[' | '(' | '{') starred_expression for_if_clauses + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); + void *_tmp_153_var; + expr_ty a; + asdl_comprehension_seq* for_if_clauses_var; + if ( + (_tmp_153_var = _tmp_153_rule(p)) // '[' | '(' | '{' + && + (a = starred_expression_rule(p)) // starred_expression + && + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "iterable unpacking cannot be used in comprehension" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_comprehension[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); + } + { // ('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_154_var; + expr_ty a; + asdl_expr_seq* b; + asdl_comprehension_seq* for_if_clauses_var; + if ( + (_tmp_154_var = _tmp_154_rule(p)) // '[' | '{' + && + (a = star_named_expression_rule(p)) // star_named_expression + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (b = star_named_expressions_rule(p)) // star_named_expressions + && + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , PyPegen_last_item ( b , expr_ty ) , "did you forget parentheses around the comprehension target?" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_comprehension[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); + } + { // ('[' | '{') star_named_expression ',' for_if_clauses + if (p->error_indicator) { + p->level--; + 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_155_var; + expr_ty a; + Token * b; + asdl_comprehension_seq* for_if_clauses_var; + if ( + (_tmp_155_var = _tmp_155_rule(p)) // '[' | '{' + && + (a = star_named_expression_rule(p)) // star_named_expression + && + (b = _PyPegen_expect_token(p, 12)) // token=',' + && + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "did you forget parentheses around the comprehension target?" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_comprehension[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_dict_comprehension: '{' '**' bitwise_or for_if_clauses '}' +static void * +invalid_dict_comprehension_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; + { // '{' '**' bitwise_or for_if_clauses '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_dict_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'")); + Token * _literal; + Token * _literal_1; + Token * a; + expr_ty bitwise_or_var; + asdl_comprehension_seq* for_if_clauses_var; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = _PyPegen_expect_token(p, 35)) // token='**' + && + (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or + && + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + && + (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ invalid_dict_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "dict unpacking cannot be used in dict comprehension" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_dict_comprehension[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_parameters: param_no_default* invalid_parameters_helper param_no_default +static void * +invalid_parameters_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; + { // 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_156_var; + arg_ty a; + void *invalid_parameters_helper_var; + if ( + (_loop0_156_var = _loop0_156_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, "param_no_default* invalid_parameters_helper param_no_default")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "non-default argument follows default argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + 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")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_parameters_helper: slash_with_default | param_with_default+ +static void * +invalid_parameters_helper_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; + { // slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* a; + if ( + (a = slash_with_default_rule(p)) // slash_with_default + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + } + { // param_with_default+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); + asdl_seq * _loop1_157_var; + if ( + (_loop1_157_var = _loop1_157_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_157_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_lambda_parameters: +// | lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default +static void * +invalid_lambda_parameters_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_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_158_var; + arg_ty a; + void *invalid_lambda_parameters_helper_var; + if ( + (_loop0_158_var = _loop0_158_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, "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" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + 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")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_lambda_parameters_helper: +// | lambda_slash_with_default +// | lambda_param_with_default+ +static void * +invalid_lambda_parameters_helper_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_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* a; + if ( + (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + { // lambda_param_with_default+ + if (p->error_indicator) { + p->level--; + 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_159_var; + if ( + (_loop1_159_var = _loop1_159_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_159_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_star_etc: '*' (')' | ',' (')' | '**')) | '*' ',' TYPE_COMMENT +static void * +invalid_star_etc_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; + { // '*' (')' | ',' (')' | '**')) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); + void *_tmp_160_var; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_160_var = _tmp_160_rule(p)) // ')' | ',' (')' | '**') + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "named arguments must follow bare *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); + } + { // '*' ',' TYPE_COMMENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); + Token * _literal; + Token * _literal_1; + Token * type_comment_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); + _res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' TYPE_COMMENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_lambda_star_etc: '*' (':' | ',' (':' | '**')) +static void * +invalid_lambda_star_etc_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; + { // '*' (':' | ',' (':' | '**')) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + Token * _literal; + void *_tmp_161_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_161_var = _tmp_161_rule(p)) // ':' | ',' (':' | '**') + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_double_type_comments: TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT +static void * +invalid_double_type_comments_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; + { // TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_double_type_comments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); + Token * indent_var; + Token * newline_var; + Token * newline_var_1; + Token * type_comment_var; + Token * type_comment_var_1; + if ( + (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + (type_comment_var_1 = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' + && + (newline_var_1 = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' + ) + { + D(fprintf(stderr, "%*c+ invalid_double_type_comments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); + _res = RAISE_SYNTAX_ERROR ( "Cannot have two type comments on def" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_double_type_comments[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_with_item: expression 'as' expression &(',' | ')' | ':') +static void * +invalid_with_item_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; + { // expression 'as' expression &(',' | ')' | ':') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); + Token * _keyword; + expr_ty a; + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (a = expression_rule(p)) // expression + && + _PyPegen_lookahead(1, _tmp_162_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); + _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_with_item[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_for_target: ASYNC? 'for' star_expressions +static void * +invalid_for_target_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; + { // ASYNC? 'for' star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_for_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions")); + Token * _keyword; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (_keyword = _PyPegen_expect_token(p, 517)) // token='for' + && + (a = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ invalid_for_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions")); + _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( FOR_TARGETS , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_for_target[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'for' star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_group: '(' starred_expression ')' | '(' '**' expression ')' +static void * +invalid_group_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; + { // '(' starred_expression ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' starred_expression ')'")); + Token * _literal; + Token * _literal_1; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = starred_expression_rule(p)) // starred_expression + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ invalid_group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' starred_expression ')'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use starred expression here" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_group[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' starred_expression ')'")); + } + { // '(' '**' expression ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'")); + Token * _literal; + Token * _literal_1; + Token * a; + expr_ty expression_var; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = _PyPegen_expect_token(p, 35)) // token='**' + && + (expression_var = expression_rule(p)) // expression + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ invalid_group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use double starred expression here" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_group[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' '**' expression ')'")); + } + _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(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // import_from_as_names ',' NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names ',' NEWLINE")); + Token * _literal; + asdl_alias_seq* import_from_as_names_var; + Token * newline_var; + if ( + (import_from_as_names_var = import_from_as_names_rule(p)) // import_from_as_names + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_names ',' NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "trailing comma not allowed without surrounding 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_import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_names ',' NEWLINE")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_with_stmt: +// | ASYNC? 'with' ','.(expression ['as' star_target])+ &&':' +// | ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':' +static void * +invalid_with_stmt_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; + { // ASYNC? 'with' ','.(expression ['as' star_target])+ &&':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); + asdl_seq * _gather_163_var; + Token * _keyword; + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (_keyword = _PyPegen_expect_token(p, 519)) // token='with' + && + (_gather_163_var = _gather_163_rule(p)) // ','.(expression ['as' star_target])+ + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); + _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _gather_163_var, _literal); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); + } + { // ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); + asdl_seq * _gather_165_var; + Token * _keyword; + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (_keyword = _PyPegen_expect_token(p, 519)) // token='with' + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (_gather_165_var = _gather_165_rule(p)) // ','.(expressions ['as' star_target])+ + && + (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); + _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _literal, _gather_165_var, _opt_var_1, _literal_1, _literal_2); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_with_stmt_indent: +// | ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT +// | ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT +static void * +invalid_with_stmt_indent_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; + { // ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + 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_167_var; + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + Token * newline_var; + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (a = _PyPegen_expect_token(p, 519)) // token='with' + && + (_gather_167_var = _gather_167_rule(p)) // ','.(expression ['as' star_target])+ + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_with_stmt_indent[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); + } + { // ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + 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_169_var; + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings + Token * a; + Token * newline_var; + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (a = _PyPegen_expect_token(p, 519)) // token='with' + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (_gather_169_var = _gather_169_rule(p)) // ','.(expressions ['as' star_target])+ + && + (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_with_stmt_indent[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_try_stmt: 'try' ':' NEWLINE !INDENT | 'try' ':' block !('except' | 'finally') +static void * +invalid_try_stmt_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; + { // 'try' ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' NEWLINE !INDENT")); + Token * _literal; + Token * a; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 511)) // token='try' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'try' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' ':' NEWLINE !INDENT")); + } + { // 'try' ':' block !('except' | 'finally') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* block_var; + if ( + (_keyword = _PyPegen_expect_token(p, 511)) // token='try' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (block_var = block_rule(p)) // block + && + _PyPegen_lookahead(0, _tmp_171_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); + _res = RAISE_SYNTAX_ERROR ( "expected 'except' or 'finally' block" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' ':' block !('except' | 'finally')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_except_stmt: +// | 'except' expression ',' expressions ['as' NAME] ':' +// | 'except' expression ['as' NAME] NEWLINE +// | 'except' NEWLINE +static void * +invalid_except_stmt_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; + { // 'except' expression ',' expressions ['as' NAME] ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ',' expressions ['as' NAME] ':'")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + expr_ty expressions_var; + if ( + (_keyword = _PyPegen_expect_token(p, 521)) // token='except' + && + (a = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (expressions_var = expressions_rule(p)) // expressions + && + (_opt_var = _tmp_172_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ',' expressions ['as' NAME] ':'")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "multiple exception types must be parenthesized" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_except_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' expression ',' expressions ['as' NAME] ':'")); + } + { // 'except' expression ['as' NAME] NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] NEWLINE")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + expr_ty expression_var; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 521)) // token='except' + && + (expression_var = expression_rule(p)) // expression + && + (_opt_var = _tmp_173_rule(p), !p->error_indicator) // ['as' NAME] + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_except_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' expression ['as' NAME] NEWLINE")); + } + { // 'except' NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' NEWLINE")); + Token * a; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 521)) // token='except' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_except_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' NEWLINE")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_finally_stmt: 'finally' ':' NEWLINE !INDENT +static void * +invalid_finally_stmt_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; + { // 'finally' ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_finally_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally' ':' NEWLINE !INDENT")); + Token * _literal; + Token * a; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 522)) // token='finally' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_finally_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally' ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'finally' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_finally_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally' ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_except_stmt_indent: +// | 'except' expression ['as' NAME] ':' NEWLINE !INDENT +// | 'except' ':' NEWLINE !INDENT +static void * +invalid_except_stmt_indent_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; + { // 'except' expression ['as' NAME] ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_except_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' NEWLINE !INDENT")); + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + expr_ty expression_var; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 521)) // token='except' + && + (expression_var = expression_rule(p)) // expression + && + (_opt_var = _tmp_174_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_except_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_except_stmt_indent[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' expression ['as' NAME] ':' NEWLINE !INDENT")); + } + { // 'except' ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_except_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' ':' NEWLINE !INDENT")); + Token * _literal; + Token * a; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 521)) // token='except' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_except_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' NEWLINE !INDENT")); + _res = RAISE_SYNTAX_ERROR ( "expected an indented block after except statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_except_stmt_indent[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_match_stmt: +// | "match" subject_expr !':' +// | "match" subject_expr ':' NEWLINE !INDENT +static void * +invalid_match_stmt_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; + { // "match" subject_expr !':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr !':'")); + expr_ty _keyword; + expr_ty subject_expr_var; + if ( + (_keyword = _PyPegen_expect_soft_keyword(p, "match")) // soft_keyword='"match"' + && + (subject_expr_var = subject_expr_rule(p)) // subject_expr + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 11) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr !':'")); + _res = CHECK_VERSION ( void * , 10 , "Pattern matching is" , RAISE_SYNTAX_ERROR ( "expected ':'" ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_match_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"match\" subject_expr !':'")); + } + { // "match" subject_expr ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE !INDENT")); + Token * _literal; + expr_ty a; + Token * newline_var; + expr_ty subject; + if ( + (a = _PyPegen_expect_soft_keyword(p, "match")) // soft_keyword='"match"' + && + (subject = subject_expr_rule(p)) // subject_expr + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'match' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_match_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"match\" subject_expr ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_case_block: +// | "case" patterns guard? !':' +// | "case" patterns guard? ':' NEWLINE !INDENT +static void * +invalid_case_block_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; + { // "case" patterns guard? !':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? !':'")); + expr_ty _keyword; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + pattern_ty patterns_var; + if ( + (_keyword = _PyPegen_expect_soft_keyword(p, "case")) // soft_keyword='"case"' + && + (patterns_var = patterns_rule(p)) // patterns + && + (_opt_var = guard_rule(p), !p->error_indicator) // guard? + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 11) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? !':'")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_case_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"case\" patterns guard? !':'")); + } + { // "case" patterns guard? ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' NEWLINE !INDENT")); + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + Token * newline_var; + pattern_ty patterns_var; + if ( + (a = _PyPegen_expect_soft_keyword(p, "case")) // soft_keyword='"case"' + && + (patterns_var = patterns_rule(p)) // patterns + && + (_opt_var = guard_rule(p), !p->error_indicator) // guard? + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'case' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_case_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"case\" patterns guard? ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_as_pattern: or_pattern 'as' "_" | or_pattern 'as' !NAME expression +static void * +invalid_as_pattern_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; + { // or_pattern 'as' "_" + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' \"_\"")); + Token * _keyword; + expr_ty a; + pattern_ty or_pattern_var; + if ( + (or_pattern_var = or_pattern_rule(p)) // or_pattern + && + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (a = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' + ) + { + D(fprintf(stderr, "%*c+ invalid_as_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' \"_\"")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use '_' as a target" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_as_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "or_pattern 'as' \"_\"")); + } + { // or_pattern 'as' !NAME expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' !NAME expression")); + Token * _keyword; + expr_ty a; + pattern_ty or_pattern_var; + if ( + (or_pattern_var = or_pattern_rule(p)) // or_pattern + && + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p) + && + (a = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_as_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' !NAME expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "invalid pattern target" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_as_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "or_pattern 'as' !NAME expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_class_pattern: name_or_attr '(' invalid_class_argument_pattern +static void * +invalid_class_pattern_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; + { // name_or_attr '(' invalid_class_argument_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' invalid_class_argument_pattern")); + Token * _literal; + asdl_pattern_seq* a; + expr_ty name_or_attr_var; + if ( + (name_or_attr_var = name_or_attr_rule(p)) // name_or_attr + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = invalid_class_argument_pattern_rule(p)) // invalid_class_argument_pattern + ) + { + D(fprintf(stderr, "%*c+ invalid_class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' invalid_class_argument_pattern")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( PyPegen_first_item ( a , pattern_ty ) , PyPegen_last_item ( a , pattern_ty ) , "positional patterns follow keyword patterns" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_class_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "name_or_attr '(' invalid_class_argument_pattern")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_class_argument_pattern: +// | [positional_patterns ','] keyword_patterns ',' positional_patterns +static asdl_pattern_seq* +invalid_class_argument_pattern_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_pattern_seq* _res = NULL; + int _mark = p->mark; + { // [positional_patterns ','] keyword_patterns ',' positional_patterns + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_class_argument_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[positional_patterns ','] keyword_patterns ',' positional_patterns")); + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_pattern_seq* a; + asdl_seq* keyword_patterns_var; + if ( + (_opt_var = _tmp_175_rule(p), !p->error_indicator) // [positional_patterns ','] + && + (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = positional_patterns_rule(p)) // positional_patterns + ) + { + D(fprintf(stderr, "%*c+ invalid_class_argument_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[positional_patterns ','] keyword_patterns ',' positional_patterns")); + _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 invalid_class_argument_pattern[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "[positional_patterns ','] keyword_patterns ',' positional_patterns")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_if_stmt: +// | 'if' named_expression NEWLINE +// | 'if' named_expression ':' NEWLINE !INDENT +static void * +invalid_if_stmt_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; + { // 'if' named_expression NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression NEWLINE")); + Token * _keyword; + expr_ty named_expression_var; + Token * newline_var; + if ( + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (named_expression_var = named_expression_rule(p)) // named_expression + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_if_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' named_expression NEWLINE")); + } + { // 'if' named_expression ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' NEWLINE !INDENT")); + Token * _literal; + Token * a; + expr_ty a_1; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 510)) // token='if' + && + (a_1 = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'if' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_if_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' named_expression ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_elif_stmt: +// | 'elif' named_expression NEWLINE +// | 'elif' named_expression ':' NEWLINE !INDENT +static void * +invalid_elif_stmt_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; + { // 'elif' named_expression NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression NEWLINE")); + Token * _keyword; + expr_ty named_expression_var; + Token * newline_var; + if ( + (_keyword = _PyPegen_expect_token(p, 515)) // token='elif' + && + (named_expression_var = named_expression_rule(p)) // named_expression + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_elif_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'elif' named_expression NEWLINE")); + } + { // 'elif' named_expression ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' NEWLINE !INDENT")); + Token * _literal; + Token * a; + expr_ty named_expression_var; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 515)) // token='elif' + && + (named_expression_var = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'elif' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_elif_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'elif' named_expression ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_else_stmt: 'else' ':' NEWLINE !INDENT +static void * +invalid_else_stmt_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; + { // 'else' ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_else_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' ':' NEWLINE !INDENT")); + Token * _literal; + Token * a; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 516)) // token='else' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_else_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'else' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_else_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else' ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_while_stmt: +// | 'while' named_expression NEWLINE +// | 'while' named_expression ':' NEWLINE !INDENT +static void * +invalid_while_stmt_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; + { // 'while' named_expression NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression NEWLINE")); + Token * _keyword; + expr_ty named_expression_var; + Token * newline_var; + if ( + (_keyword = _PyPegen_expect_token(p, 512)) // token='while' + && + (named_expression_var = named_expression_rule(p)) // named_expression + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_while_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'while' named_expression NEWLINE")); + } + { // 'while' named_expression ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' NEWLINE !INDENT")); + Token * _literal; + Token * a; + expr_ty named_expression_var; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 512)) // token='while' + && + (named_expression_var = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'while' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_while_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'while' named_expression ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_for_stmt: ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT +static void * +invalid_for_stmt_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; + { // ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); + Token * _keyword; + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + Token * newline_var; + expr_ty star_expressions_var; + expr_ty star_targets_var; + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (a = _PyPegen_expect_token(p, 517)) // token='for' + && + (star_targets_var = star_targets_rule(p)) // star_targets + && + (_keyword = _PyPegen_expect_token(p, 518)) // token='in' + && + (star_expressions_var = star_expressions_rule(p)) // star_expressions + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'for' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_for_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_def_raw: +// | ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT +static void * +invalid_def_raw_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; + { // ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); + Token * _literal; + Token * _literal_1; + Token * _literal_2; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings + void *_opt_var_2; + UNUSED(_opt_var_2); // Silence compiler warnings + Token * a; + expr_ty name_var; + Token * newline_var; + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (a = _PyPegen_expect_token(p, 526)) // token='def' + && + (name_var = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (_opt_var_1 = params_rule(p), !p->error_indicator) // params? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && + (_opt_var_2 = _tmp_176_rule(p), !p->error_indicator) // ['->' expression] + && + (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after function definition on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_def_raw[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_class_def_raw: 'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT +static void * +invalid_class_def_raw_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; + { // 'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT")); + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + expr_ty name_var; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 527)) // token='class' + && + (name_var = _PyPegen_name_token(p)) // NAME + && + (_opt_var = _tmp_177_rule(p), !p->error_indicator) // ['(' arguments? ')'] + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after class definition on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_double_starred_kvpairs: +// | ','.double_starred_kvpair+ ',' invalid_kvpair +// | expression ':' '*' bitwise_or +// | expression ':' &('}' | ',') +static void * +invalid_double_starred_kvpairs_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; + { // ','.double_starred_kvpair+ ',' invalid_kvpair + if (p->error_indicator) { + p->level--; + 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_178_var; + Token * _literal; + void *invalid_kvpair_var; + if ( + (_gather_178_var = _gather_178_rule(p)) // ','.double_starred_kvpair+ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (invalid_kvpair_var = invalid_kvpair_rule(p)) // invalid_kvpair + ) + { + 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_178_var, _literal, invalid_kvpair_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_double_starred_kvpairs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); + } + { // expression ':' '*' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); + Token * _literal; + Token * a; + expr_ty bitwise_or_var; + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "cannot use a starred expression in a dictionary value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_double_starred_kvpairs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' '*' bitwise_or")); + } + { // expression ':' &('}' | ',') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); + Token * a; + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + (a = _PyPegen_expect_token(p, 11)) // token=':' + && + _PyPegen_lookahead(1, _tmp_180_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression expected after dictionary key and ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_double_starred_kvpairs[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' &('}' | ',')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_kvpair: expression !(':') | expression ':' '*' bitwise_or | expression ':' +static void * +invalid_kvpair_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; + { // expression !(':') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !(':')")); + expr_ty a; + if ( + (a = expression_rule(p)) // expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 11) // token=(':') + ) + { + D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !(':')")); + _res = RAISE_ERROR_KNOWN_LOCATION ( p , PyExc_SyntaxError , a -> lineno , a -> end_col_offset - 1 , a -> end_lineno , - 1 , "':' expected after dictionary key" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kvpair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !(':')")); + } + { // expression ':' '*' bitwise_or + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); + Token * _literal; + Token * a; + expr_ty bitwise_or_var; + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or + ) + { + D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "cannot use a starred expression in a dictionary value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kvpair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' '*' bitwise_or")); + } + { // expression ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':'")); + Token * a; + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + (a = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression expected after dictionary key and ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kvpair[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_1: NEWLINE +static asdl_seq * +_loop0_1_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; + } + 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_1[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + Token * newline_var; + while ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + _res = newline_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_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; + } + 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); + p->level--; + return _seq; +} + +// _loop0_2: NEWLINE +static asdl_seq * +_loop0_2_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; + } + 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' + ) + { + _res = newline_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_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; +} + +// _loop0_4: ',' expression +static asdl_seq * +_loop0_4_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = expression_rule(p)) // expression + ) + { + _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) { + 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_4[%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); + 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_4_type, _seq); + p->level--; + return _seq; +} + +// _gather_3: expression _loop0_4 +static asdl_seq * +_gather_3_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // expression _loop0_4 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_4")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = expression_rule(p)) // expression + && + (seq = _loop0_4_rule(p)) // _loop0_4 + ) + { + D(fprintf(stderr, "%*c+ _gather_3[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_4")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_3[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_4")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_6: ',' expression +static asdl_seq * +_loop0_6_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = expression_rule(p)) // expression + ) + { + _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) { + 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_6[%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); + 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_6_type, _seq); + p->level--; + return _seq; +} + +// _gather_5: expression _loop0_6 +static asdl_seq * +_gather_5_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // expression _loop0_6 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_6")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = expression_rule(p)) // expression + && + (seq = _loop0_6_rule(p)) // _loop0_6 + ) + { + D(fprintf(stderr, "%*c+ _gather_5[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_6")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_5[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_6")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_8: ',' expression +static asdl_seq * +_loop0_8_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = expression_rule(p)) // expression + ) + { + _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) { + 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_8[%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); + 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_8_type, _seq); + p->level--; + return _seq; +} + +// _gather_7: expression _loop0_8 +static asdl_seq * +_gather_7_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // expression _loop0_8 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_8")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = expression_rule(p)) // expression + && + (seq = _loop0_8_rule(p)) // _loop0_8 + ) + { + D(fprintf(stderr, "%*c+ _gather_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_8")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_7[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_8")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_10: ',' expression +static asdl_seq * +_loop0_10_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = expression_rule(p)) // expression + ) + { + _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) { + 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_10[%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); + 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_10_type, _seq); + p->level--; + return _seq; +} + +// _gather_9: expression _loop0_10 +static asdl_seq * +_gather_9_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // expression _loop0_10 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_10")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = expression_rule(p)) // expression + && + (seq = _loop0_10_rule(p)) // _loop0_10 + ) + { + D(fprintf(stderr, "%*c+ _gather_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_10")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_9[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_10")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_11: statement +static asdl_seq * +_loop1_11_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; + } + 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_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); + asdl_stmt_seq* statement_var; + while ( + (statement_var = statement_rule(p)) // statement + ) + { + _res = statement_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_11[%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_11_type, _seq); + p->level--; + return _seq; +} + +// _loop0_13: ';' simple_stmt +static asdl_seq * +_loop0_13_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; + } + 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_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' simple_stmt")); + Token * _literal; + stmt_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 13)) // token=';' + && + (elem = simple_stmt_rule(p)) // simple_stmt + ) + { + _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) { + 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_13[%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_13_type, _seq); + p->level--; + return _seq; +} + +// _gather_12: simple_stmt _loop0_13 +static asdl_seq * +_gather_12_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // simple_stmt _loop0_13 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_13")); + stmt_ty elem; + asdl_seq * seq; + if ( + (elem = simple_stmt_rule(p)) // simple_stmt + && + (seq = _loop0_13_rule(p)) // _loop0_13 + ) + { + D(fprintf(stderr, "%*c+ _gather_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_13")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_12[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt _loop0_13")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_14: 'import' | 'from' +static void * +_tmp_14_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; + { // 'import' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 513)) // token='import' + ) + { + D(fprintf(stderr, "%*c+ _tmp_14[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_14[%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_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 514)) // token='from' + ) + { + D(fprintf(stderr, "%*c+ _tmp_14[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_14[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_15: 'def' | '@' | ASYNC +static void * +_tmp_15_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; + { // 'def' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 526)) // token='def' + ) + { + D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); + _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, "'def'")); + } + { // '@' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 49)) // token='@' + ) + { + D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); + _res = _literal; + 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, "'@'")); + } + { // ASYNC + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_15[%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_15[%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_15[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_16: 'class' | '@' +static void * +_tmp_16_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; + { // 'class' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 527)) // token='class' + ) + { + D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); + _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, "'class'")); + } + { // '@' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 49)) // token='@' + ) + { + D(fprintf(stderr, "%*c+ _tmp_16[%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, "'@'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_17: 'with' | ASYNC +static void * +_tmp_17_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; + { // 'with' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 519)) // token='with' + ) + { + D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); + _res = _keyword; + 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, "'with'")); + } + { // ASYNC + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_17[%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_17[%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_17[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_18: 'for' | ASYNC +static void * +_tmp_18_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; + { // 'for' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 517)) // token='for' + ) + { + D(fprintf(stderr, "%*c+ _tmp_18[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_18[%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_18[%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_18[%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_18[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_19: '=' annotated_rhs +static void * +_tmp_19_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; + { // '=' annotated_rhs + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_19[%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+ _tmp_19[%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 _tmp_19[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_20: '(' single_target ')' | single_subscript_attribute_target +static void * +_tmp_20_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; + { // '(' single_target ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_20[%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+ _tmp_20[%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; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_20[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' single_target ')'")); + } + { // single_subscript_attribute_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_20[%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_20[%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_20[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_subscript_attribute_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_21: '=' annotated_rhs +static void * +_tmp_21_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; + { // '=' annotated_rhs + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_21[%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+ _tmp_21[%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 _tmp_21[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_22: (star_targets '=') +static asdl_seq * +_loop1_22_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; + } + 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> _loop1_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_181_var; + while ( + (_tmp_181_var = _tmp_181_rule(p)) // star_targets '=' + ) + { + _res = _tmp_181_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_22[%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) { + 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_22_type, _seq); + p->level--; + return _seq; +} + +// _tmp_23: yield_expr | star_expressions +static void * +_tmp_23_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; + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_23[%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_23[%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_23[%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_23[%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_23[%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_23[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_24: yield_expr | star_expressions +static void * +_tmp_24_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; + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_24[%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_24[%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_24[%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_24[%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_24[%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_24[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_26: ',' NAME +static asdl_seq * +_loop0_26_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; + } + 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_26[%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) { + 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_26[%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) { + 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_26_type, _seq); + p->level--; + return _seq; +} + +// _gather_25: NAME _loop0_26 +static asdl_seq * +_gather_25_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // NAME _loop0_26 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_26")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = _PyPegen_name_token(p)) // NAME + && + (seq = _loop0_26_rule(p)) // _loop0_26 + ) + { + D(fprintf(stderr, "%*c+ _gather_25[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_26")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_25[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_26")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_28: ',' NAME +static asdl_seq * +_loop0_28_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; + } + 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_28[%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) { + 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_28[%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) { + 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_28_type, _seq); + p->level--; + return _seq; +} + +// _gather_27: NAME _loop0_28 +static asdl_seq * +_gather_27_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // NAME _loop0_28 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_28")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = _PyPegen_name_token(p)) // NAME + && + (seq = _loop0_28_rule(p)) // _loop0_28 + ) + { + D(fprintf(stderr, "%*c+ _gather_27[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_28")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_27[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_28")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_29: ',' expression +static void * +_tmp_29_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; + { // ',' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_29[%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_29[%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_29[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_30: ';' | NEWLINE +static void * +_tmp_30_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; + { // ';' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 13)) // token=';' + ) + { + D(fprintf(stderr, "%*c+ _tmp_30[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_30[%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_30[%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_30[%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_30[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_31: ('.' | '...') +static asdl_seq * +_loop0_31_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('.' | '...') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); + void *_tmp_182_var; + while ( + (_tmp_182_var = _tmp_182_rule(p)) // '.' | '...' + ) + { + _res = _tmp_182_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_31[%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; + } + 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_31_type, _seq); + p->level--; + return _seq; +} + +// _loop1_32: ('.' | '...') +static asdl_seq * +_loop1_32_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('.' | '...') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); + void *_tmp_183_var; + while ( + (_tmp_183_var = _tmp_183_rule(p)) // '.' | '...' + ) + { + _res = _tmp_183_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_32[%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); + _PyPegen_insert_memo(p, _start_mark, _loop1_32_type, _seq); + p->level--; + return _seq; +} + +// _loop0_34: ',' import_from_as_name +static asdl_seq * +_loop0_34_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' import_from_as_name + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name")); + Token * _literal; + alias_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = import_from_as_name_rule(p)) // import_from_as_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) { + 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_34[%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); + 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_34_type, _seq); + p->level--; + return _seq; +} + +// _gather_33: import_from_as_name _loop0_34 +static asdl_seq * +_gather_33_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // import_from_as_name _loop0_34 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_34")); + alias_ty elem; + asdl_seq * seq; + if ( + (elem = import_from_as_name_rule(p)) // import_from_as_name + && + (seq = _loop0_34_rule(p)) // _loop0_34 + ) + { + D(fprintf(stderr, "%*c+ _gather_33[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_34")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_33[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_name _loop0_34")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_35: 'as' NAME +static void * +_tmp_35_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; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (z = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_35[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _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_35[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_37: ',' dotted_as_name +static asdl_seq * +_loop0_37_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' dotted_as_name + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name")); + Token * _literal; + alias_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = dotted_as_name_rule(p)) // dotted_as_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) { + 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_37[%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); + 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_37_type, _seq); + p->level--; + return _seq; +} + +// _gather_36: dotted_as_name _loop0_37 +static asdl_seq * +_gather_36_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // dotted_as_name _loop0_37 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_37")); + alias_ty elem; + asdl_seq * seq; + if ( + (elem = dotted_as_name_rule(p)) // dotted_as_name + && + (seq = _loop0_37_rule(p)) // _loop0_37 + ) + { + D(fprintf(stderr, "%*c+ _gather_36[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_37")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_36[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_as_name _loop0_37")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_38: 'as' NAME +static void * +_tmp_38_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; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (z = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_38[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _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_38[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_40: ',' with_item +static asdl_seq * +_loop0_40_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' with_item + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + Token * _literal; + withitem_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = with_item_rule(p)) // with_item + ) + { + _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) { + 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_40[%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); + 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_40_type, _seq); + p->level--; + return _seq; +} + +// _gather_39: with_item _loop0_40 +static asdl_seq * +_gather_39_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // with_item _loop0_40 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_40")); + withitem_ty elem; + asdl_seq * seq; + if ( + (elem = with_item_rule(p)) // with_item + && + (seq = _loop0_40_rule(p)) // _loop0_40 + ) + { + D(fprintf(stderr, "%*c+ _gather_39[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_40")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_39[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_40")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_42: ',' with_item +static asdl_seq * +_loop0_42_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' with_item + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + Token * _literal; + withitem_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = with_item_rule(p)) // with_item + ) + { + _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) { + 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_42[%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); + 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_42_type, _seq); + p->level--; + return _seq; +} + +// _gather_41: with_item _loop0_42 +static asdl_seq * +_gather_41_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // with_item _loop0_42 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_42")); + withitem_ty elem; + asdl_seq * seq; + if ( + (elem = with_item_rule(p)) // with_item + && + (seq = _loop0_42_rule(p)) // _loop0_42 + ) + { + D(fprintf(stderr, "%*c+ _gather_41[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_42")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_41[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_42")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_44: ',' with_item +static asdl_seq * +_loop0_44_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' with_item + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + Token * _literal; + withitem_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = with_item_rule(p)) // with_item + ) + { + _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) { + 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_44[%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); + 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_44_type, _seq); + p->level--; + return _seq; +} + +// _gather_43: with_item _loop0_44 +static asdl_seq * +_gather_43_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // with_item _loop0_44 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_43[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_44")); + withitem_ty elem; + asdl_seq * seq; + if ( + (elem = with_item_rule(p)) // with_item + && + (seq = _loop0_44_rule(p)) // _loop0_44 + ) + { + D(fprintf(stderr, "%*c+ _gather_43[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_44")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_43[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_44")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_46: ',' with_item +static asdl_seq * +_loop0_46_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' with_item + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + Token * _literal; + withitem_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = with_item_rule(p)) // with_item + ) + { + _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) { + 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_46[%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); + 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_46_type, _seq); + p->level--; + return _seq; +} + +// _gather_45: with_item _loop0_46 +static asdl_seq * +_gather_45_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // with_item _loop0_46 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_46")); + withitem_ty elem; + asdl_seq * seq; + if ( + (elem = with_item_rule(p)) // with_item + && + (seq = _loop0_46_rule(p)) // _loop0_46 + ) + { + D(fprintf(stderr, "%*c+ _gather_45[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_46")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_45[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_46")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_47: ',' | ')' | ':' +static void * +_tmp_47_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; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_47[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_47[%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_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_47[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_47[%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_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_47[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_47[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_48: except_block +static asdl_seq * +_loop1_48_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; + } + 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_48[%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 + ) + { + _res = except_block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_48[%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; + } + 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_48_type, _seq); + p->level--; + return _seq; +} + +// _tmp_49: 'as' NAME +static void * +_tmp_49_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; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (z = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_49[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _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_49[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_50: case_block +static asdl_seq * +_loop1_50_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // case_block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_50[%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 + ) + { + _res = case_block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_50[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "case_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; + } + 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: '|' closed_pattern +static asdl_seq * +_loop0_52_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // '|' closed_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); + Token * _literal; + pattern_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 18)) // token='|' + && + (elem = closed_pattern_rule(p)) // closed_pattern + ) + { + _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) { + 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_52[%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); + 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_52_type, _seq); + p->level--; + return _seq; +} + +// _gather_51: closed_pattern _loop0_52 +static asdl_seq * +_gather_51_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // closed_pattern _loop0_52 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_52")); + pattern_ty elem; + asdl_seq * seq; + if ( + (elem = closed_pattern_rule(p)) // closed_pattern + && + (seq = _loop0_52_rule(p)) // _loop0_52 + ) + { + D(fprintf(stderr, "%*c+ _gather_51[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_52")); + _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, "closed_pattern _loop0_52")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_53: '+' | '-' +static void * +_tmp_53_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; + { // '+' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 14)) // token='+' + ) + { + D(fprintf(stderr, "%*c+ _tmp_53[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_53[%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_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + ) + { + D(fprintf(stderr, "%*c+ _tmp_53[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_53[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_54: '+' | '-' +static void * +_tmp_54_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; + { // '+' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 14)) // token='+' + ) + { + D(fprintf(stderr, "%*c+ _tmp_54[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_54[%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_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + ) + { + D(fprintf(stderr, "%*c+ _tmp_54[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_54[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_55: '.' | '(' | '=' +static void * +_tmp_55_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; + { // '.' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + ) + { + D(fprintf(stderr, "%*c+ _tmp_55[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_55[%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_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + ) + { + D(fprintf(stderr, "%*c+ _tmp_55[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_55[%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_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_55[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_55[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_56: '.' | '(' | '=' +static void * +_tmp_56_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; + { // '.' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + ) + { + D(fprintf(stderr, "%*c+ _tmp_56[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_56[%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_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + ) + { + D(fprintf(stderr, "%*c+ _tmp_56[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_56[%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_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_56[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_56[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_58: ',' maybe_star_pattern +static asdl_seq * +_loop0_58_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' maybe_star_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); + Token * _literal; + pattern_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = maybe_star_pattern_rule(p)) // maybe_star_pattern + ) + { + _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) { + 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_58[%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); + 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_58_type, _seq); + p->level--; + return _seq; +} + +// _gather_57: maybe_star_pattern _loop0_58 +static asdl_seq * +_gather_57_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // maybe_star_pattern _loop0_58 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_58")); + pattern_ty elem; + asdl_seq * seq; + if ( + (elem = maybe_star_pattern_rule(p)) // maybe_star_pattern + && + (seq = _loop0_58_rule(p)) // _loop0_58 + ) + { + D(fprintf(stderr, "%*c+ _gather_57[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_58")); + _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, "maybe_star_pattern _loop0_58")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_60: ',' key_value_pattern +static asdl_seq * +_loop0_60_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' key_value_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); + Token * _literal; + KeyPatternPair* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = key_value_pattern_rule(p)) // key_value_pattern + ) + { + _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) { + 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_60[%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); + 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_60_type, _seq); + p->level--; + return _seq; +} + +// _gather_59: key_value_pattern _loop0_60 +static asdl_seq * +_gather_59_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // key_value_pattern _loop0_60 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_60")); + KeyPatternPair* elem; + asdl_seq * seq; + if ( + (elem = key_value_pattern_rule(p)) // key_value_pattern + && + (seq = _loop0_60_rule(p)) // _loop0_60 + ) + { + D(fprintf(stderr, "%*c+ _gather_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_60")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_59[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_60")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_61: literal_expr | attr +static void * +_tmp_61_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; + { // literal_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_61[%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_61[%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_61[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "literal_expr")); + } + { // attr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_61[%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_61[%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_61[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_63: ',' pattern +static asdl_seq * +_loop0_63_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); + Token * _literal; + pattern_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = pattern_rule(p)) // pattern + ) + { + _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) { + 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_63[%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); + 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_63_type, _seq); + p->level--; + return _seq; +} + +// _gather_62: pattern _loop0_63 +static asdl_seq * +_gather_62_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // pattern _loop0_63 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_63")); + pattern_ty elem; + asdl_seq * seq; + if ( + (elem = pattern_rule(p)) // pattern + && + (seq = _loop0_63_rule(p)) // _loop0_63 + ) + { + D(fprintf(stderr, "%*c+ _gather_62[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_63")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_62[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_63")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_65: ',' keyword_pattern +static asdl_seq * +_loop0_65_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' keyword_pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); + Token * _literal; + KeyPatternPair* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = keyword_pattern_rule(p)) // keyword_pattern + ) + { + _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) { + 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_65[%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); + 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_65_type, _seq); + p->level--; + return _seq; +} + +// _gather_64: keyword_pattern _loop0_65 +static asdl_seq * +_gather_64_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // keyword_pattern _loop0_65 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_65")); + KeyPatternPair* elem; + asdl_seq * seq; + if ( + (elem = keyword_pattern_rule(p)) // keyword_pattern + && + (seq = _loop0_65_rule(p)) // _loop0_65 + ) + { + D(fprintf(stderr, "%*c+ _gather_64[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_65")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_64[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_65")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_66: 'from' expression +static void * +_tmp_66_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; + { // 'from' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 514)) // token='from' + && + (z = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' 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_66[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_67: '->' expression +static void * +_tmp_67_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; + { // '->' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + Token * _literal; + expr_ty z; + if ( + (_literal = _PyPegen_expect_token(p, 51)) // token='->' + && + (z = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_67[%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_67[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_68: '->' expression +static void * +_tmp_68_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; + { // '->' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + Token * _literal; + expr_ty z; + if ( + (_literal = _PyPegen_expect_token(p, 51)) // token='->' + && + (z = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_68[%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_68[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_69: NEWLINE INDENT +static void * +_tmp_69_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; + { // NEWLINE INDENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); + Token * indent_var; + Token * newline_var; + if ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' + ) + { + D(fprintf(stderr, "%*c+ _tmp_69[%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_69[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_70: param_no_default +static asdl_seq * +_loop0_70_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; + } + 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> _loop0_70[%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 + ) + { + _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) { + 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_70[%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); + 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_70_type, _seq); + p->level--; + return _seq; +} + +// _loop0_71: param_with_default +static asdl_seq * +_loop0_71_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; + } + 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> _loop0_71[%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 + ) + { + _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) { + 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_71[%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); + 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_71_type, _seq); + p->level--; + return _seq; +} + +// _loop0_72: param_with_default +static asdl_seq * +_loop0_72_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; + } + 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> _loop0_72[%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 + ) + { + _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) { + 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_72[%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); + 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_72_type, _seq); + p->level--; + return _seq; +} + +// _loop1_73: param_no_default +static asdl_seq * +_loop1_73_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; + } + 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> _loop1_73[%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 + ) + { + _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) { + 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_73[%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; + } + 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_73_type, _seq); + p->level--; + return _seq; +} + +// _loop0_74: param_with_default +static asdl_seq * +_loop0_74_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; + } + 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> _loop0_74[%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 + ) + { + _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) { + 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_74[%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); + 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_74_type, _seq); + p->level--; + return _seq; +} + +// _loop1_75: param_with_default +static asdl_seq * +_loop1_75_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; + } + 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_75[%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 + ) + { + _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) { + 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_75[%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) { + 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_75_type, _seq); + p->level--; + return _seq; +} + +// _loop1_76: param_no_default +static asdl_seq * +_loop1_76_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; + } + 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> _loop1_76[%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 + ) + { + _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) { + 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_76[%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; + } + 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_76_type, _seq); + p->level--; + return _seq; +} + +// _loop1_77: param_no_default +static asdl_seq * +_loop1_77_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; + } + 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> _loop1_77[%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 + ) + { + _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) { + 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_77[%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; + } + 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_77_type, _seq); + p->level--; + return _seq; +} + +// _loop0_78: param_no_default +static asdl_seq * +_loop0_78_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; + } + 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> _loop0_78[%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 + ) + { + _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) { + 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_78[%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); + 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_78_type, _seq); + p->level--; + return _seq; +} + +// _loop1_79: param_with_default +static asdl_seq * +_loop1_79_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; + } + 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_79[%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 + ) + { + _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) { + 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_79[%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) { + 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_79_type, _seq); + p->level--; + return _seq; +} + +// _loop0_80: param_no_default +static asdl_seq * +_loop0_80_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; + } + 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> _loop0_80[%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 + ) + { + _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) { + 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_80[%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); + 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_80_type, _seq); + p->level--; + return _seq; +} + +// _loop1_81: param_with_default +static asdl_seq * +_loop1_81_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; + } + 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_81[%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 + ) + { + _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) { + 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_81[%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) { + 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_81_type, _seq); + p->level--; + return _seq; +} + +// _loop0_82: param_maybe_default +static asdl_seq * +_loop0_82_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; + } + 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_82[%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) { + 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, "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); + _PyPegen_insert_memo(p, _start_mark, _loop0_82_type, _seq); + p->level--; + return _seq; +} + +// _loop1_83: param_maybe_default +static asdl_seq * +_loop1_83_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; + } + 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> _loop1_83[%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) { + 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_83[%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) { + 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_83_type, _seq); + p->level--; + return _seq; +} + +// _loop1_84: ('@' named_expression NEWLINE) +static asdl_seq * +_loop1_84_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('@' named_expression NEWLINE) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); + void *_tmp_184_var; + while ( + (_tmp_184_var = _tmp_184_rule(p)) // '@' named_expression NEWLINE + ) + { + _res = _tmp_184_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_84[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('@' named_expression NEWLINE)")); + } + 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_84_type, _seq); + p->level--; + return _seq; +} + +// _tmp_85: '(' arguments? ')' +static void * +_tmp_85_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; + { // '(' arguments? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + Token * _literal; + Token * _literal_1; + void *z; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (z = arguments_rule(p), !p->error_indicator) // arguments? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_85[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + _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_85[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_86: (',' star_expression) +static asdl_seq * +_loop1_86_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // (',' star_expression) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); + void *_tmp_185_var; + while ( + (_tmp_185_var = _tmp_185_rule(p)) // ',' star_expression + ) + { + _res = _tmp_185_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_86[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)")); + } + 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_86_type, _seq); + p->level--; + return _seq; +} + +// _loop0_88: ',' star_named_expression +static asdl_seq * +_loop0_88_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' star_named_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = star_named_expression_rule(p)) // star_named_expression + ) + { + _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) { + 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_88[%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); + 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_88_type, _seq); + p->level--; + return _seq; +} + +// _gather_87: star_named_expression _loop0_88 +static asdl_seq * +_gather_87_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // star_named_expression _loop0_88 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_88")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = star_named_expression_rule(p)) // star_named_expression + && + (seq = _loop0_88_rule(p)) // _loop0_88 + ) + { + D(fprintf(stderr, "%*c+ _gather_87[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_88")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_87[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_88")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_89: (',' expression) +static asdl_seq * +_loop1_89_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // (',' expression) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); + void *_tmp_186_var; + while ( + (_tmp_186_var = _tmp_186_rule(p)) // ',' expression + ) + { + _res = _tmp_186_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_89[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' expression)")); + } + 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_89_type, _seq); + p->level--; + return _seq; +} + +// _loop0_90: lambda_param_no_default +static asdl_seq * +_loop0_90_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; + } + 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_90[%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) { + 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_90[%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); + _PyPegen_insert_memo(p, _start_mark, _loop0_90_type, _seq); + p->level--; + return _seq; +} + +// _loop0_91: lambda_param_with_default +static asdl_seq * +_loop0_91_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; + } + 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> _loop0_91[%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) { + 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_91[%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); + 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_91_type, _seq); + p->level--; + return _seq; +} + +// _loop0_92: lambda_param_with_default +static asdl_seq * +_loop0_92_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; + } + 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> _loop0_92[%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) { + 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_92[%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); + 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_92_type, _seq); + p->level--; + return _seq; +} + +// _loop1_93: lambda_param_no_default +static asdl_seq * +_loop1_93_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; + } + 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> _loop1_93[%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) { + 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_93[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_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); + _PyPegen_insert_memo(p, _start_mark, _loop1_93_type, _seq); + p->level--; + return _seq; +} + +// _loop0_94: lambda_param_with_default +static asdl_seq * +_loop0_94_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; + } + 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> _loop0_94[%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) { + 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_94[%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); + 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_94_type, _seq); + p->level--; + return _seq; +} + +// _loop1_95: lambda_param_with_default +static asdl_seq * +_loop1_95_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; + } + 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_95[%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) { + 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_95[%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); + _PyPegen_insert_memo(p, _start_mark, _loop1_95_type, _seq); + p->level--; + return _seq; +} + +// _loop1_96: lambda_param_no_default +static asdl_seq * +_loop1_96_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; + } + 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> _loop1_96[%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) { + 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_96[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_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); + _PyPegen_insert_memo(p, _start_mark, _loop1_96_type, _seq); + p->level--; + return _seq; +} + +// _loop1_97: lambda_param_no_default +static asdl_seq * +_loop1_97_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; + } + 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> _loop1_97[%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) { + 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_97[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_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); + _PyPegen_insert_memo(p, _start_mark, _loop1_97_type, _seq); + p->level--; + return _seq; +} + +// _loop0_98: lambda_param_no_default +static asdl_seq * +_loop0_98_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; + } + 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_98[%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) { + 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_98[%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); + _PyPegen_insert_memo(p, _start_mark, _loop0_98_type, _seq); + p->level--; + return _seq; +} + +// _loop1_99: lambda_param_with_default +static asdl_seq * +_loop1_99_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; + } + 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_99[%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) { + 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_99[%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); + _PyPegen_insert_memo(p, _start_mark, _loop1_99_type, _seq); + p->level--; + return _seq; +} + +// _loop0_100: lambda_param_no_default +static asdl_seq * +_loop0_100_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; + } + 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_100[%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) { + 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_100[%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); + _PyPegen_insert_memo(p, _start_mark, _loop0_100_type, _seq); + p->level--; + return _seq; +} + +// _loop1_101: lambda_param_with_default +static asdl_seq * +_loop1_101_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; + } + 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_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 + ) + { + _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) { + 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_101[%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); + _PyPegen_insert_memo(p, _start_mark, _loop1_101_type, _seq); + p->level--; + return _seq; +} + +// _loop0_102: lambda_param_maybe_default +static asdl_seq * +_loop0_102_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_102[%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 + ) + { + _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) { + 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_102[%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) { + 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_102_type, _seq); + p->level--; + return _seq; +} + +// _loop1_103: lambda_param_maybe_default +static asdl_seq * +_loop1_103_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_103[%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 + ) + { + _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) { + 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_103[%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; + } + 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_103_type, _seq); + p->level--; + return _seq; +} + +// _loop1_104: ('or' conjunction) +static asdl_seq * +_loop1_104_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('or' conjunction) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); + void *_tmp_187_var; + while ( + (_tmp_187_var = _tmp_187_rule(p)) // 'or' conjunction + ) + { + _res = _tmp_187_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_104[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)")); + } + 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_104_type, _seq); + p->level--; + return _seq; +} + +// _loop1_105: ('and' inversion) +static asdl_seq * +_loop1_105_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('and' inversion) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); + void *_tmp_188_var; + while ( + (_tmp_188_var = _tmp_188_rule(p)) // 'and' inversion + ) + { + _res = _tmp_188_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_105[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)")); + } + 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_105_type, _seq); + p->level--; + return _seq; +} + +// _loop1_106: compare_op_bitwise_or_pair +static asdl_seq * +_loop1_106_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // compare_op_bitwise_or_pair + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_106[%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 + ) + { + _res = compare_op_bitwise_or_pair_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_106[%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) { + 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_106_type, _seq); + p->level--; + return _seq; +} + +// _tmp_107: '!=' +static void * +_tmp_107_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; + { // '!=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); + Token * tok; + if ( + (tok = _PyPegen_expect_token(p, 28)) // token='!=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_107[%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; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_107[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_109: ',' slice +static asdl_seq * +_loop0_109_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' slice + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' slice")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = slice_rule(p)) // slice + ) + { + _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) { + 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_109[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' slice")); + } + 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_109_type, _seq); + p->level--; + return _seq; +} + +// _gather_108: slice _loop0_109 +static asdl_seq * +_gather_108_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // slice _loop0_109 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice _loop0_109")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = slice_rule(p)) // slice + && + (seq = _loop0_109_rule(p)) // _loop0_109 + ) + { + D(fprintf(stderr, "%*c+ _gather_108[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice _loop0_109")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_108[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice _loop0_109")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_110: ':' expression? +static void * +_tmp_110_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; + { // ':' expression? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); + Token * _literal; + void *d; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (d = expression_rule(p), !p->error_indicator) // expression? + ) + { + D(fprintf(stderr, "%*c+ _tmp_110[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); + _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 _tmp_110[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_111: tuple | group | genexp +static void * +_tmp_111_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; + { // tuple + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_111[%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_111[%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_111[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); + } + { // group + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_111[%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_111[%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_111[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group")); + } + { // genexp + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_111[%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_111[%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_111[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_112: list | listcomp +static void * +_tmp_112_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; + { // list + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_112[%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_112[%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_112[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); + } + { // listcomp + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_112[%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_112[%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_112[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "listcomp")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_113: dict | set | dictcomp | setcomp +static void * +_tmp_113_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; + { // dict + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_113[%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_113[%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_113[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dict")); + } + { // set + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_113[%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_113[%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_113[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "set")); + } + { // dictcomp + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_113[%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_113[%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_113[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dictcomp")); + } + { // setcomp + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_113[%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_113[%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_113[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "setcomp")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_114: STRING +static asdl_seq * +_loop1_114_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // STRING + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); + expr_ty string_var; + while ( + (string_var = _PyPegen_string_token(p)) // STRING + ) + { + _res = string_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_114[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); + } + 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_114_type, _seq); + p->level--; + return _seq; +} + +// _tmp_115: star_named_expression ',' star_named_expressions? +static void * +_tmp_115_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; + { // star_named_expression ',' star_named_expressions? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + Token * _literal; + expr_ty y; + void *z; + if ( + (y = star_named_expression_rule(p)) // star_named_expression + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (z = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? + ) + { + D(fprintf(stderr, "%*c+ _tmp_115[%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; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_115[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_116: yield_expr | named_expression +static void * +_tmp_116_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; + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_116[%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_116[%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_116[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // named_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_116[%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_116[%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_116[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_117: assignment_expression | expression !':=' +static void * +_tmp_117_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; + { // assignment_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_117[%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_117[%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_117[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); + } + { // expression !':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_117[%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_117[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_119: ',' double_starred_kvpair +static asdl_seq * +_loop0_119_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' double_starred_kvpair + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + Token * _literal; + KeyValuePair* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair + ) + { + _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) { + 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_119[%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) { + 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_119_type, _seq); + p->level--; + return _seq; +} + +// _gather_118: double_starred_kvpair _loop0_119 +static asdl_seq * +_gather_118_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // double_starred_kvpair _loop0_119 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_119")); + KeyValuePair* elem; + asdl_seq * seq; + if ( + (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair + && + (seq = _loop0_119_rule(p)) // _loop0_119 + ) + { + D(fprintf(stderr, "%*c+ _gather_118[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_119")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_118[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_119")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_120: for_if_clause +static asdl_seq * +_loop1_120_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // for_if_clause + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_120[%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 + ) + { + _res = for_if_clause_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_120[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause")); + } + 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_120_type, _seq); + p->level--; + return _seq; +} + +// _loop0_121: ('if' disjunction) +static asdl_seq * +_loop0_121_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('if' disjunction) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_189_var; + while ( + (_tmp_189_var = _tmp_189_rule(p)) // 'if' disjunction + ) + { + _res = _tmp_189_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_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); + 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_121_type, _seq); + p->level--; + return _seq; +} + +// _loop0_122: ('if' disjunction) +static asdl_seq * +_loop0_122_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('if' disjunction) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_190_var; + while ( + (_tmp_190_var = _tmp_190_rule(p)) // 'if' disjunction + ) + { + _res = _tmp_190_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_122[%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); + 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_122_type, _seq); + p->level--; + return _seq; +} + +// _loop0_124: ',' (starred_expression | (assignment_expression | expression !':=') !'=') +static asdl_seq * +_loop0_124_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' (starred_expression | (assignment_expression | expression !':=') !'=') + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_191_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + ) + { + _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) { + 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_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); + 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_124_type, _seq); + p->level--; + return _seq; +} + +// _gather_123: +// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124 +static asdl_seq * +_gather_123_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124 + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_191_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + && + (seq = _loop0_124_rule(p)) // _loop0_124 + ) + { + 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_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: + p->level--; + return _res; +} + +// _tmp_125: ',' kwargs +static void * +_tmp_125_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; + { // ',' kwargs + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); + Token * _literal; + asdl_seq* k; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (k = kwargs_rule(p)) // 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; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_125[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_127: ',' kwarg_or_starred +static asdl_seq * +_loop0_127_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' kwarg_or_starred + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + Token * _literal; + KeywordOrStarred* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred + ) + { + _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) { + 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_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); + 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_127_type, _seq); + p->level--; + return _seq; +} + +// _gather_126: kwarg_or_starred _loop0_127 +static asdl_seq * +_gather_126_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // kwarg_or_starred _loop0_127 + 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_starred _loop0_127")); + KeywordOrStarred* elem; + asdl_seq * seq; + if ( + (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred + && + (seq = _loop0_127_rule(p)) // _loop0_127 + ) + { + 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_126[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_127")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_129: ',' kwarg_or_double_starred +static asdl_seq * +_loop0_129_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' kwarg_or_double_starred + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + Token * _literal; + KeywordOrStarred* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred + ) + { + _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) { + 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_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); + 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_129_type, _seq); + p->level--; + return _seq; +} + +// _gather_128: kwarg_or_double_starred _loop0_129 +static asdl_seq * +_gather_128_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // kwarg_or_double_starred _loop0_129 + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_129_rule(p)) // _loop0_129 + ) + { + 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_128[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_129")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_131: ',' kwarg_or_starred +static asdl_seq * +_loop0_131_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' kwarg_or_starred + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + Token * _literal; + KeywordOrStarred* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred + ) + { + _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) { + 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_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); + 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_131_type, _seq); + p->level--; + return _seq; +} + +// _gather_130: kwarg_or_starred _loop0_131 +static asdl_seq * +_gather_130_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // kwarg_or_starred _loop0_131 + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_131_rule(p)) // _loop0_131 + ) + { + 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_130[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_131")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_133: ',' kwarg_or_double_starred +static asdl_seq * +_loop0_133_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' kwarg_or_double_starred + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + Token * _literal; + KeywordOrStarred* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred + ) + { + _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) { + 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_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); + 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_133_type, _seq); + p->level--; + return _seq; +} + +// _gather_132: kwarg_or_double_starred _loop0_133 +static asdl_seq * +_gather_132_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // kwarg_or_double_starred _loop0_133 + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_133_rule(p)) // _loop0_133 + ) + { + 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_132[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_133")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_134: (',' star_target) +static asdl_seq * +_loop0_134_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // (',' star_target) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_192_var; + while ( + (_tmp_192_var = _tmp_192_rule(p)) // ',' star_target + ) + { + _res = _tmp_192_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_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); + 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_134_type, _seq); + p->level--; + return _seq; +} + +// _loop0_136: ',' star_target +static asdl_seq * +_loop0_136_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = star_target_rule(p)) // 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) { + 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_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); + 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_136_type, _seq); + p->level--; + return _seq; +} + +// _gather_135: star_target _loop0_136 +static asdl_seq * +_gather_135_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // star_target _loop0_136 + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_136_rule(p)) // _loop0_136 + ) + { + 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_135[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_136")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_137: (',' star_target) +static asdl_seq * +_loop1_137_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // (',' star_target) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_193_var; + while ( + (_tmp_193_var = _tmp_193_rule(p)) // ',' star_target + ) + { + _res = _tmp_193_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_137[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); + } + 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_137_type, _seq); + p->level--; + return _seq; +} + +// _tmp_138: !'*' star_target +static void * +_tmp_138_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; + { // !'*' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + 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='*' + && + (star_target_var = star_target_rule(p)) // 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_138[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_140: ',' del_target +static asdl_seq * +_loop0_140_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' del_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = del_target_rule(p)) // del_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) { + 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_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); + 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_140_type, _seq); + p->level--; + return _seq; +} + +// _gather_139: del_target _loop0_140 +static asdl_seq * +_gather_139_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // del_target _loop0_140 + if (p->error_indicator) { + p->level--; + return NULL; + } + 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_140_rule(p)) // _loop0_140 + ) + { + 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_139[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_140")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_141: args | expression for_if_clauses +static void * +_tmp_141_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; + { // args + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_141[%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_141[%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_141[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); + } + { // expression for_if_clauses + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_141[%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 ( + (expression_var = expression_rule(p)) // expression + && + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + ) + { + D(fprintf(stderr, "%*c+ _tmp_141[%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_141[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_142: 'True' | 'False' | 'None' +static void * +_tmp_142_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; + { // 'True' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 524)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_142[%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_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 525)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_142[%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_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 523)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_143: NAME '=' +static void * +_tmp_143_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; + { // NAME '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_143[%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_143[%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_143[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_144: NAME STRING | SOFT_KEYWORD +static void * +_tmp_144_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; + { // NAME STRING + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_144[%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_144[%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_144[%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_144[%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_144[%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_144[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_145: 'else' | ':' +static void * +_tmp_145_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; + { // 'else' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 516)) // token='else' + ) + { + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); + _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, "'else'")); + } + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + 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, "':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_146: '=' | ':=' +static void * +_tmp_146_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; + { // '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_146[%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, "'='")); + } + { // ':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_146[%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, "':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_147: list | tuple | genexp | 'True' | 'None' | 'False' +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; + } + void * _res = NULL; + int _mark = p->mark; + { // list + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_147[%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_147[%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_147[%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_147[%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_147[%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_147[%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_147[%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_147[%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_147[%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_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 524)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + _res = _keyword; + 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, "'True'")); + } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 523)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + 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, "'None'")); + } + { // 'False' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 525)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + _res = _keyword; + 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, "'False'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_148: '=' | ':=' +static void * +_tmp_148_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; + { // '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_148[%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, "'='")); + } + { // ':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_148[%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, "':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_149: star_named_expressions +static asdl_seq * +_loop0_149_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; + } + 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_149[%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) { + 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_149[%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); + _PyPegen_insert_memo(p, _start_mark, _loop0_149_type, _seq); + p->level--; + return _seq; +} + +// _loop0_150: (star_targets '=') +static asdl_seq * +_loop0_150_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; + } + 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_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_194_var; + while ( + (_tmp_194_var = _tmp_194_rule(p)) // star_targets '=' + ) + { + _res = _tmp_194_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_150[%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); + _PyPegen_insert_memo(p, _start_mark, _loop0_150_type, _seq); + p->level--; + return _seq; +} + +// _loop0_151: (star_targets '=') +static asdl_seq * +_loop0_151_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; + } + 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_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_195_var; + while ( + (_tmp_195_var = _tmp_195_rule(p)) // star_targets '=' + ) + { + _res = _tmp_195_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_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_151[%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); + _PyPegen_insert_memo(p, _start_mark, _loop0_151_type, _seq); + p->level--; + return _seq; +} + +// _tmp_152: yield_expr | star_expressions +static void * +_tmp_152_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; + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%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_152[%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_152[%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_152[%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_152[%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_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_153: '[' | '(' | '{' +static void * +_tmp_153_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; + { // '[' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + 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, "'['")); + } + { // '(' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; + 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, "'('")); + } + { // '{' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; + 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, "'{'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_154: '[' | '{' +static void * +_tmp_154_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; + { // '[' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _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, "'['")); + } + { // '{' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _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, "'{'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_155: '[' | '{' +static void * +_tmp_155_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; + { // '[' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { + D(fprintf(stderr, "%*c+ _tmp_155[%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, "'['")); + } + { // '{' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { + D(fprintf(stderr, "%*c+ _tmp_155[%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, "'{'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_156: param_no_default +static asdl_seq * +_loop0_156_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; + } + 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> _loop0_156[%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 + ) + { + _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) { + 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_156[%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); + 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_156_type, _seq); + p->level--; + return _seq; +} + +// _loop1_157: param_with_default +static asdl_seq * +_loop1_157_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; + } + 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_157[%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 + ) + { + _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) { + 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_157[%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) { + 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_157_type, _seq); + p->level--; + return _seq; +} + +// _loop0_158: lambda_param_no_default +static asdl_seq * +_loop0_158_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; + } + 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_158[%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) { + 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_158[%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); + _PyPegen_insert_memo(p, _start_mark, _loop0_158_type, _seq); + p->level--; + return _seq; +} + +// _loop1_159: lambda_param_with_default +static asdl_seq * +_loop1_159_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; + } + 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_159[%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) { + 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_159[%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); + _PyPegen_insert_memo(p, _start_mark, _loop1_159_type, _seq); + p->level--; + return _seq; +} + +// _tmp_160: ')' | ',' (')' | '**') +static void * +_tmp_160_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; + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_160[%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_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + Token * _literal; + void *_tmp_196_var; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_tmp_196_var = _tmp_196_rule(p)) // ')' | '**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_196_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); + } + _res = NULL; + done: + p->level--; + return _res; +} -/* For a description, see the comments at end of this file */ +// _tmp_161: ':' | ',' (':' | '**') +static void * +_tmp_161_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; + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_161[%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_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + Token * _literal; + void *_tmp_197_var; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_tmp_197_var = _tmp_197_rule(p)) // ':' | '**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_197_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); + } + _res = NULL; + done: + p->level--; + return _res; +} -/* XXX To do: error recovery */ +// _tmp_162: ',' | ')' | ':' +static void * +_tmp_162_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; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + 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, "','")); + } + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + 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, "')'")); + } + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + 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, "':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} -#include "Python.h" -#include "token.h" -#include "grammar.h" -#include "node.h" -#include "parser.h" -#include "errcode.h" -#include "graminit.h" +// _loop0_164: ',' (expression ['as' star_target]) +static asdl_seq * +_loop0_164_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' (expression ['as' star_target]) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_164[%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=',' + && + (elem = _tmp_198_rule(p)) // expression ['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) { + 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_164[%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; + } + 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_164_type, _seq); + p->level--; + return _seq; +} +// _gather_163: (expression ['as' star_target]) _loop0_164 +static asdl_seq * +_gather_163_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (expression ['as' star_target]) _loop0_164 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_164")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_198_rule(p)) // expression ['as' star_target] + && + (seq = _loop0_164_rule(p)) // _loop0_164 + ) + { + D(fprintf(stderr, "%*c+ _gather_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_164")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_163[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_164")); + } + _res = NULL; + done: + p->level--; + return _res; +} -#ifdef Py_DEBUG -extern int Py_DebugFlag; -#define D(x) if (!Py_DebugFlag); else x -#else -#define D(x) -#endif +// _loop0_166: ',' (expressions ['as' star_target]) +static asdl_seq * +_loop0_166_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' (expressions ['as' star_target]) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _tmp_199_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) { + 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_166[%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; + } + 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_166_type, _seq); + p->level--; + return _seq; +} + +// _gather_165: (expressions ['as' star_target]) _loop0_166 +static asdl_seq * +_gather_165_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (expressions ['as' star_target]) _loop0_166 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_166")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_199_rule(p)) // expressions ['as' star_target] + && + (seq = _loop0_166_rule(p)) // _loop0_166 + ) + { + D(fprintf(stderr, "%*c+ _gather_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_166")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_165[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_166")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_168: ',' (expression ['as' star_target]) +static asdl_seq * +_loop0_168_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' (expression ['as' star_target]) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_168[%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=',' + && + (elem = _tmp_200_rule(p)) // expression ['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) { + 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_168[%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; + } + 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_168_type, _seq); + p->level--; + return _seq; +} + +// _gather_167: (expression ['as' star_target]) _loop0_168 +static asdl_seq * +_gather_167_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (expression ['as' star_target]) _loop0_168 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_168")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_200_rule(p)) // expression ['as' star_target] + && + (seq = _loop0_168_rule(p)) // _loop0_168 + ) + { + D(fprintf(stderr, "%*c+ _gather_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_168")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_167[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_168")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_170: ',' (expressions ['as' star_target]) +static asdl_seq * +_loop0_170_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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' (expressions ['as' star_target]) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _tmp_201_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) { + 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_170[%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; + } + 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_170_type, _seq); + p->level--; + return _seq; +} + +// _gather_169: (expressions ['as' star_target]) _loop0_170 +static asdl_seq * +_gather_169_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (expressions ['as' star_target]) _loop0_170 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_170")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_201_rule(p)) // expressions ['as' star_target] + && + (seq = _loop0_170_rule(p)) // _loop0_170 + ) + { + D(fprintf(stderr, "%*c+ _gather_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_170")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_169[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_170")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_171: 'except' | 'finally' +static void * +_tmp_171_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; + { // 'except' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 521)) // token='except' + ) + { + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + _res = _keyword; + 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, "'except'")); + } + { // 'finally' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 522)) // token='finally' + ) + { + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + _res = _keyword; + 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, "'finally'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_172: 'as' NAME +static void * +_tmp_172_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; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_172[%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_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_173: 'as' NAME +static void * +_tmp_173_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; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_173[%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_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_174: 'as' NAME +static void * +_tmp_174_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; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( + (_keyword = _PyPegen_expect_token(p, 520)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_174[%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_174[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} +// _tmp_175: positional_patterns ',' +static void * +_tmp_175_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; + { // positional_patterns ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + Token * _literal; + asdl_pattern_seq* positional_patterns_var; + if ( + (positional_patterns_var = positional_patterns_rule(p)) // positional_patterns + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_175[%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 _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); + } + _res = NULL; + done: + p->level--; + return _res; +} -/* STACK DATA TYPE */ +// _tmp_176: '->' expression +static void * +_tmp_176_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; + { // '->' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + Token * _literal; + expr_ty expression_var; + if ( + (_literal = _PyPegen_expect_token(p, 51)) // token='->' + && + (expression_var = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_176[%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 _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} -static void s_reset(stack *); +// _tmp_177: '(' arguments? ')' +static void * +_tmp_177_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; + { // '(' arguments? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_177[%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 ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (_opt_var = arguments_rule(p), !p->error_indicator) // arguments? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_177[%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 _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} -static void -s_reset(stack *s) +// _loop0_179: ',' double_starred_kvpair +static asdl_seq * +_loop0_179_rule(Parser *p) { - s->s_top = &s->s_base[MAXSTACK]; + 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; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' double_starred_kvpair + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + Token * _literal; + KeyValuePair* elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair + ) + { + _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) { + 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_179[%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) { + 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_179_type, _seq); + p->level--; + return _seq; } -#define s_empty(s) ((s)->s_top == &(s)->s_base[MAXSTACK]) - -static int -s_push(stack *s, const dfa *d, node *parent) +// _gather_178: double_starred_kvpair _loop0_179 +static asdl_seq * +_gather_178_rule(Parser *p) { - stackentry *top; - if (s->s_top == s->s_base) { - fprintf(stderr, "s_push: parser stack overflow\n"); - return E_NOMEM; + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // double_starred_kvpair _loop0_179 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_179")); + KeyValuePair* elem; + asdl_seq * seq; + if ( + (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair + && + (seq = _loop0_179_rule(p)) // _loop0_179 + ) + { + D(fprintf(stderr, "%*c+ _gather_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_179")); + _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, "double_starred_kvpair _loop0_179")); } - top = --s->s_top; - top->s_dfa = d; - top->s_parent = parent; - top->s_state = 0; - return 0; + _res = NULL; + done: + p->level--; + return _res; } -#ifdef Py_DEBUG - -static void -s_pop(stack *s) +// _tmp_180: '}' | ',' +static void * +_tmp_180_rule(Parser *p) { - if (s_empty(s)) { - Py_FatalError("parser stack underflow"); + 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; + { // '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; + 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, "'}'")); } - s->s_top++; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + 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, "','")); + } + _res = NULL; + done: + p->level--; + return _res; } -#else /* !Py_DEBUG */ - -#define s_pop(s) (s)->s_top++ - -#endif - - -/* PARSER CREATION */ - -parser_state * -PyParser_New(grammar *g, int start) +// _tmp_181: star_targets '=' +static void * +_tmp_181_rule(Parser *p) { - parser_state *ps; - - if (!g->g_accel) - PyGrammar_AddAccelerators(g); - ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state)); - if (ps == NULL) - return NULL; - ps->p_grammar = g; -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - ps->p_flags = 0; -#endif - ps->p_tree = PyNode_New(start); - if (ps->p_tree == NULL) { - PyMem_FREE(ps); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } - s_reset(&ps->p_stack); - (void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree); - return ps; + void * _res = NULL; + int _mark = p->mark; + { // star_targets '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty z; + if ( + (z = star_targets_rule(p)) // star_targets + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + _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_181[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + } + _res = NULL; + done: + p->level--; + return _res; } -void -PyParser_Delete(parser_state *ps) +// _tmp_182: '.' | '...' +static void * +_tmp_182_rule(Parser *p) { - /* NB If you want to save the parse tree, - you must set p_tree to NULL before calling delparser! */ - PyNode_Free(ps->p_tree); - PyMem_FREE(ps); + 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; + { // '.' + 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, 23)) // 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, "'.'")); + } + { // '...' + 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, 52)) // 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: + p->level--; + return _res; } - -/* PARSER STACK OPERATIONS */ - -static int -shift(stack *s, int type, char *str, int newstate, int lineno, int col_offset, - int end_lineno, int end_col_offset) +// _tmp_183: '.' | '...' +static void * +_tmp_183_rule(Parser *p) { - int err; - assert(!s_empty(s)); - err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno, col_offset, - end_lineno, end_col_offset); - if (err) - return err; - s->s_top->s_state = newstate; - return 0; + 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; + { // '.' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + ) + { + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_183[%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_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 52)) // token='...' + ) + { + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); + } + _res = NULL; + done: + p->level--; + return _res; } -static int -push(stack *s, int type, const dfa *d, int newstate, int lineno, int col_offset, - int end_lineno, int end_col_offset) +// _tmp_184: '@' named_expression NEWLINE +static void * +_tmp_184_rule(Parser *p) { - int err; - node *n; - n = s->s_top->s_parent; - assert(!s_empty(s)); - err = PyNode_AddChild(n, type, (char *)NULL, lineno, col_offset, - end_lineno, end_col_offset); - if (err) - return err; - s->s_top->s_state = newstate; - return s_push(s, d, CHILD(n, NCH(n)-1)); + 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; + { // '@' named_expression NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + Token * _literal; + expr_ty f; + Token * newline_var; + if ( + (_literal = _PyPegen_expect_token(p, 49)) // token='@' + && + (f = named_expression_rule(p)) // named_expression + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + _res = f; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "'@' named_expression NEWLINE")); + } + _res = NULL; + done: + p->level--; + return _res; } - -/* PARSER PROPER */ - -static int -classify(parser_state *ps, int type, const char *str) +// _tmp_185: ',' star_expression +static void * +_tmp_185_rule(Parser *p) { - grammar *g = ps->p_grammar; - int n = g->g_ll.ll_nlabels; - - if (type == NAME) { - const label *l = g->g_ll.ll_label; - int i; - for (i = n; i > 0; i--, l++) { - if (l->lb_type != NAME || l->lb_str == NULL || - l->lb_str[0] != str[0] || - strcmp(l->lb_str, str) != 0) - continue; -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD -#if 0 - /* Leaving this in as an example */ - if (!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) { - if (str[0] == 'w' && strcmp(str, "with") == 0) - break; /* not a keyword yet */ - else if (str[0] == 'a' && strcmp(str, "as") == 0) - break; /* not a keyword yet */ + 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; + { // ',' star_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + Token * _literal; + expr_ty c; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (c = star_expression_rule(p)) // star_expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } -#endif -#endif - D(printf("It's a keyword\n")); - return n - i; + goto done; } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } + _res = NULL; + done: + p->level--; + return _res; +} - { - const label *l = g->g_ll.ll_label; - int i; - for (i = n; i > 0; i--, l++) { - if (l->lb_type == type && l->lb_str == NULL) { - D(printf("It's a token we know\n")); - return n - i; +// _tmp_186: ',' expression +static void * +_tmp_186_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; + { // ',' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + Token * _literal; + expr_ty c; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (c = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } + goto done; } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } - - D(printf("Illegal token\n")); - return -1; + _res = NULL; + done: + p->level--; + return _res; } -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD -#if 0 -/* Leaving this in as an example */ -static void -future_hack(parser_state *ps) +// _tmp_187: 'or' conjunction +static void * +_tmp_187_rule(Parser *p) { - node *n = ps->p_stack.s_top->s_parent; - node *ch, *cch; - int i; - - /* from __future__ import ..., must have at least 4 children */ - n = CHILD(n, 0); - if (NCH(n) < 4) - return; - ch = CHILD(n, 0); - if (STR(ch) == NULL || strcmp(STR(ch), "from") != 0) - return; - ch = CHILD(n, 1); - if (NCH(ch) == 1 && STR(CHILD(ch, 0)) && - strcmp(STR(CHILD(ch, 0)), "__future__") != 0) - return; - ch = CHILD(n, 3); - /* ch can be a star, a parenthesis or import_as_names */ - if (TYPE(ch) == STAR) - return; - if (TYPE(ch) == LPAR) - ch = CHILD(n, 4); - - for (i = 0; i < NCH(ch); i += 2) { - cch = CHILD(ch, i); - if (NCH(cch) >= 1 && TYPE(CHILD(cch, 0)) == NAME) { - char *str_ch = STR(CHILD(cch, 0)); - if (strcmp(str_ch, FUTURE_WITH_STATEMENT) == 0) { - ps->p_flags |= CO_FUTURE_WITH_STATEMENT; - } else if (strcmp(str_ch, FUTURE_PRINT_FUNCTION) == 0) { - ps->p_flags |= CO_FUTURE_PRINT_FUNCTION; - } else if (strcmp(str_ch, FUTURE_UNICODE_LITERALS) == 0) { - ps->p_flags |= CO_FUTURE_UNICODE_LITERALS; + 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; + { // 'or' conjunction + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + Token * _keyword; + expr_ty c; + if ( + (_keyword = _PyPegen_expect_token(p, 531)) // token='or' + && + (c = conjunction_rule(p)) // conjunction + ) + { + D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } + goto done; } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } + _res = NULL; + done: + p->level--; + return _res; } -#endif -#endif /* future keyword */ - -int -PyParser_AddToken(parser_state *ps, int type, char *str, - int lineno, int col_offset, - int end_lineno, int end_col_offset, - int *expected_ret) -{ - int ilabel; - int err; - - D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str)); - - /* Find out which label this token is */ - ilabel = classify(ps, type, str); - if (ilabel < 0) - return E_SYNTAX; - - /* Loop until the token is shifted or an error occurred */ - for (;;) { - /* Fetch the current dfa and state */ - const dfa *d = ps->p_stack.s_top->s_dfa; - state *s = &d->d_state[ps->p_stack.s_top->s_state]; - - D(printf(" DFA '%s', state %d:", - d->d_name, ps->p_stack.s_top->s_state)); - - /* Check accelerator */ - if (s->s_lower <= ilabel && ilabel < s->s_upper) { - int x = s->s_accel[ilabel - s->s_lower]; - if (x != -1) { - if (x & (1<<7)) { - /* Push non-terminal */ - int nt = (x >> 8) + NT_OFFSET; - int arrow = x & ((1<<7)-1); - if (nt == func_body_suite && !(ps->p_flags & PyCF_TYPE_COMMENTS)) { - /* When parsing type comments is not requested, - we can provide better errors about bad indentation - by using 'suite' for the body of a funcdef */ - D(printf(" [switch func_body_suite to suite]")); - nt = suite; - } - const dfa *d1 = PyGrammar_FindDFA( - ps->p_grammar, nt); - if ((err = push(&ps->p_stack, nt, d1, - arrow, lineno, col_offset, - end_lineno, end_col_offset)) > 0) { - D(printf(" MemError: push\n")); - return err; - } - D(printf(" Push '%s'\n", d1->d_name)); - continue; - } - - /* Shift the token */ - if ((err = shift(&ps->p_stack, type, str, - x, lineno, col_offset, - end_lineno, end_col_offset)) > 0) { - D(printf(" MemError: shift.\n")); - return err; - } - D(printf(" Shift.\n")); - /* Pop while we are in an accept-only state */ - while (s = &d->d_state - [ps->p_stack.s_top->s_state], - s->s_accept && s->s_narcs == 1) { - D(printf(" DFA '%s', state %d: " - "Direct pop.\n", - d->d_name, - ps->p_stack.s_top->s_state)); -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD -#if 0 - if (d->d_name[0] == 'i' && - strcmp(d->d_name, - "import_stmt") == 0) - future_hack(ps); -#endif -#endif - s_pop(&ps->p_stack); - if (s_empty(&ps->p_stack)) { - D(printf(" ACCEPT.\n")); - return E_DONE; - } - d = ps->p_stack.s_top->s_dfa; - } - return E_OK; + +// _tmp_188: 'and' inversion +static void * +_tmp_188_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; + { // 'and' inversion + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + Token * _keyword; + expr_ty c; + if ( + (_keyword = _PyPegen_expect_token(p, 532)) // token='and' + && + (c = inversion_rule(p)) // inversion + ) + { + D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } + 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, "'and' inversion")); + } + _res = NULL; + done: + p->level--; + return _res; +} - if (s->s_accept) { -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD -#if 0 - if (d->d_name[0] == 'i' && - strcmp(d->d_name, "import_stmt") == 0) - future_hack(ps); -#endif -#endif - /* Pop this dfa and try again */ - s_pop(&ps->p_stack); - D(printf(" Pop ...\n")); - if (s_empty(&ps->p_stack)) { - D(printf(" Error: bottom of stack.\n")); - return E_SYNTAX; +// _tmp_189: 'if' disjunction +static void * +_tmp_189_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; + { // 'if' disjunction + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (z = disjunction_rule(p)) // disjunction + ) + { + D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } - continue; + 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, "'if' disjunction")); + } + _res = NULL; + done: + p->level--; + return _res; +} - /* Stuck, report syntax error */ - D(printf(" Error.\n")); - if (expected_ret) { - if (s->s_lower == s->s_upper - 1) { - /* Only one possible expected token */ - *expected_ret = ps->p_grammar-> - g_ll.ll_label[s->s_lower].lb_type; +// _tmp_190: 'if' disjunction +static void * +_tmp_190_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; + { // 'if' disjunction + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 510)) // token='if' + && + (z = disjunction_rule(p)) // disjunction + ) + { + D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } - else - *expected_ret = -1; + goto done; } - return E_SYNTAX; + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } + _res = NULL; + done: + p->level--; + return _res; } +// _tmp_191: starred_expression | (assignment_expression | expression !':=') !'=' +static void * +_tmp_191_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; + { // starred_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_191[%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_191[%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_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + { // (assignment_expression | expression !':=') !'=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_202_var; + if ( + (_tmp_202_var = _tmp_202_rule(p)) // assignment_expression | expression !':=' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_202_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, "(assignment_expression | expression !':=') !'='")); + } + _res = NULL; + done: + p->level--; + return _res; +} -#ifdef Py_DEBUG - -/* DEBUG OUTPUT */ - -void -dumptree(grammar *g, node *n) +// _tmp_192: ',' star_target +static void * +_tmp_192_rule(Parser *p) { - int i; + 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; + { // ',' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + Token * _literal; + expr_ty c; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (c = star_target_rule(p)) // star_target + ) + { + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + 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, "',' star_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} - if (n == NULL) - printf("NIL"); - else { - label l; - l.lb_type = TYPE(n); - l.lb_str = STR(n); - printf("%s", PyGrammar_LabelRepr(&l)); - if (ISNONTERMINAL(TYPE(n))) { - printf("("); - for (i = 0; i < NCH(n); i++) { - if (i > 0) - printf(","); - dumptree(g, CHILD(n, i)); +// _tmp_193: ',' star_target +static void * +_tmp_193_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; + { // ',' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + Token * _literal; + expr_ty c; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (c = star_target_rule(p)) // star_target + ) + { + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } - printf(")"); + 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, "',' star_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_194: star_targets '=' +static void * +_tmp_194_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; + { // star_targets '=' + if (p->error_indicator) { + p->level--; + return NULL; } + D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty star_targets_var; + if ( + (star_targets_var = star_targets_rule(p)) // star_targets + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_194[%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_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } + _res = NULL; + done: + p->level--; + return _res; } -void -showtree(grammar *g, node *n) +// _tmp_195: star_targets '=' +static void * +_tmp_195_rule(Parser *p) { - int i; + 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; + { // star_targets '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty star_targets_var; + if ( + (star_targets_var = star_targets_rule(p)) // star_targets + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_195[%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_195[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + } + _res = NULL; + done: + p->level--; + return _res; +} - if (n == NULL) - return; - if (ISNONTERMINAL(TYPE(n))) { - for (i = 0; i < NCH(n); i++) - showtree(g, CHILD(n, i)); +// _tmp_196: ')' | '**' +static void * +_tmp_196_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; + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + 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=')' + ) + { + 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_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } - else if (ISTERMINAL(TYPE(n))) { - printf("%s", _PyParser_TokenNames[TYPE(n)]); - if (TYPE(n) == NUMBER || TYPE(n) == NAME) - printf("(%s)", STR(n)); - printf(" "); + { // '**' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { + 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_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } - else - printf("? "); + _res = NULL; + done: + p->level--; + return _res; } -void -printtree(parser_state *ps) +// _tmp_197: ':' | '**' +static void * +_tmp_197_rule(Parser *p) { - if (Py_DebugFlag) { - printf("Parse tree:\n"); - dumptree(ps->p_grammar, ps->p_tree); - printf("\n"); - printf("Tokens:\n"); - showtree(ps->p_grammar, ps->p_tree); - printf("\n"); + 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; + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + 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_197[%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_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { + 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_197[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } - printf("Listing:\n"); - PyNode_ListTree(ps->p_tree); - printf("\n"); + _res = NULL; + done: + p->level--; + return _res; } -#endif /* Py_DEBUG */ +// _tmp_198: expression ['as' star_target] +static void * +_tmp_198_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; + { // expression ['as' star_target] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_198[%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_203_rule(p), !p->error_indicator) // ['as' star_target] + ) + { + D(fprintf(stderr, "%*c+ _tmp_198[%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_198[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); + } + _res = NULL; + done: + p->level--; + return _res; +} -/* +// _tmp_199: expressions ['as' star_target] +static void * +_tmp_199_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; + { // expressions ['as' star_target] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_199[%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_204_rule(p), !p->error_indicator) // ['as' star_target] + ) + { + D(fprintf(stderr, "%*c+ _tmp_199[%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_199[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); + } + _res = NULL; + done: + p->level--; + return _res; +} -Description ------------ +// _tmp_200: expression ['as' star_target] +static void * +_tmp_200_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; + { // expression ['as' star_target] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_200[%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_205_rule(p), !p->error_indicator) // ['as' star_target] + ) + { + D(fprintf(stderr, "%*c+ _tmp_200[%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_200[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); + } + _res = NULL; + done: + p->level--; + return _res; +} -The parser's interface is different than usual: the function addtoken() -must be called for each token in the input. This makes it possible to -turn it into an incremental parsing system later. The parsing system -constructs a parse tree as it goes. +// _tmp_201: expressions ['as' star_target] +static void * +_tmp_201_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; + { // expressions ['as' star_target] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_201[%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_206_rule(p), !p->error_indicator) // ['as' star_target] + ) + { + D(fprintf(stderr, "%*c+ _tmp_201[%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_201[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); + } + _res = NULL; + done: + p->level--; + return _res; +} -A parsing rule is represented as a Deterministic Finite-state Automaton -(DFA). A node in a DFA represents a state of the parser; an arc represents -a transition. Transitions are either labeled with terminal symbols or -with non-terminals. When the parser decides to follow an arc labeled -with a non-terminal, it is invoked recursively with the DFA representing -the parsing rule for that as its initial state; when that DFA accepts, -the parser that invoked it continues. The parse tree constructed by the -recursively called parser is inserted as a child in the current parse tree. +// _tmp_202: assignment_expression | expression !':=' +static void * +_tmp_202_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; + { // assignment_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_202[%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_202[%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_202[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); + } + { // expression !':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_202[%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_202[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} -The DFA's can be constructed automatically from a more conventional -language description. An extended LL(1) grammar (ELL(1)) is suitable. -Certain restrictions make the parser's life easier: rules that can produce -the empty string should be outlawed (there are other ways to put loops -or optional parts in the language). To avoid the need to construct -FIRST sets, we can require that all but the last alternative of a rule -(really: arc going out of a DFA's state) must begin with a terminal -symbol. +// _tmp_203: 'as' star_target +static void * +_tmp_203_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; + { // 'as' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_203[%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, 520)) // token='as' + && + (star_target_var = star_target_rule(p)) // star_target + ) + { + D(fprintf(stderr, "%*c+ _tmp_203[%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_203[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} -As an example, consider this grammar: +// _tmp_204: 'as' star_target +static void * +_tmp_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; + { // 'as' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_204[%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, 520)) // token='as' + && + (star_target_var = star_target_rule(p)) // star_target + ) + { + D(fprintf(stderr, "%*c+ _tmp_204[%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_204[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} -expr: term (OP term)* -term: CONSTANT | '(' expr ')' +// _tmp_205: 'as' star_target +static void * +_tmp_205_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; + { // 'as' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_205[%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, 520)) // token='as' + && + (star_target_var = star_target_rule(p)) // star_target + ) + { + D(fprintf(stderr, "%*c+ _tmp_205[%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_205[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} -The DFA corresponding to the rule for expr is: +// _tmp_206: 'as' star_target +static void * +_tmp_206_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; + { // 'as' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_206[%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, 520)) // token='as' + && + (star_target_var = star_target_rule(p)) // star_target + ) + { + D(fprintf(stderr, "%*c+ _tmp_206[%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_206[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; + done: + p->level--; + return _res; +} -------->.---term-->.-------> - ^ | - | | - \----OP----/ +void * +_PyPegen_parse(Parser *p) +{ + // Initialize keywords + p->keywords = reserved_keywords; + p->n_keyword_lists = n_keyword_lists; + p->soft_keywords = soft_keywords; -The parse tree generated for the input a+b is: + // Run parser + void *result = NULL; + if (p->start_rule == Py_file_input) { + result = file_rule(p); + } else if (p->start_rule == Py_single_input) { + result = interactive_rule(p); + } else if (p->start_rule == Py_eval_input) { + result = eval_rule(p); + } else if (p->start_rule == Py_func_type_input) { + result = func_type_rule(p); + } else if (p->start_rule == Py_fstring_input) { + result = fstring_rule(p); + } -(expr: (term: (NAME: a)), (OP: +), (term: (NAME: b))) + return result; +} -*/ +// The end diff --git a/contrib/tools/python3/src/Parser/parser.h b/contrib/tools/python3/src/Parser/parser.h deleted file mode 100644 index b16075e7f29..00000000000 --- a/contrib/tools/python3/src/Parser/parser.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef Py_PARSER_H -#define Py_PARSER_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Parser interface */ - -#define MAXSTACK 1700 - -typedef struct { - int s_state; /* State in current DFA */ - const dfa *s_dfa; /* Current DFA */ - struct _node *s_parent; /* Where to add next node */ -} stackentry; - -typedef struct { - stackentry *s_top; /* Top entry */ - stackentry s_base[MAXSTACK];/* Array of stack entries */ - /* NB The stack grows down */ -} stack; - -typedef struct { - stack p_stack; /* Stack of parser states */ - grammar *p_grammar; /* Grammar to use */ - node *p_tree; /* Top of parse tree */ -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - unsigned long p_flags; /* see co_flags in Include/code.h */ -#endif -} parser_state; - -parser_state *PyParser_New(grammar *g, int start); -void PyParser_Delete(parser_state *ps); -int PyParser_AddToken(parser_state *ps, int type, char *str, - int lineno, int col_offset, - int end_lineno, int end_col_offset, - int *expected_ret); -void PyGrammar_AddAccelerators(grammar *g); - - -#define showtree _Py_showtree -#define printtree _Py_printtree -#define dumptree _Py_dumptree - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PARSER_H */ diff --git a/contrib/tools/python3/src/Parser/parsetok.c b/contrib/tools/python3/src/Parser/parsetok.c deleted file mode 100644 index 1ecb2c4a16d..00000000000 --- a/contrib/tools/python3/src/Parser/parsetok.c +++ /dev/null @@ -1,486 +0,0 @@ - -/* Parser-tokenizer link implementation */ - -#include "Python.h" -#include "tokenizer.h" -#include "node.h" -#include "grammar.h" -#include "parser.h" -#include "parsetok.h" -#include "errcode.h" -#include "graminit.h" - - -/* Forward */ -static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *); -static int initerr(perrdetail *err_ret, PyObject * filename); - -typedef struct { - struct { - int lineno; - char *comment; - } *items; - size_t size; - size_t num_items; -} growable_comment_array; - -static int -growable_comment_array_init(growable_comment_array *arr, size_t initial_size) { - assert(initial_size > 0); - arr->items = malloc(initial_size * sizeof(*arr->items)); - arr->size = initial_size; - arr->num_items = 0; - - return arr->items != NULL; -} - -static int -growable_comment_array_add(growable_comment_array *arr, int lineno, char *comment) { - if (arr->num_items >= arr->size) { - size_t new_size = arr->size * 2; - void *new_items_array = realloc(arr->items, new_size * sizeof(*arr->items)); - if (!new_items_array) { - return 0; - } - arr->items = new_items_array; - arr->size = new_size; - } - - arr->items[arr->num_items].lineno = lineno; - arr->items[arr->num_items].comment = comment; - arr->num_items++; - return 1; -} - -static void -growable_comment_array_deallocate(growable_comment_array *arr) { - for (unsigned i = 0; i < arr->num_items; i++) { - PyObject_FREE(arr->items[i].comment); - } - free(arr->items); -} - -/* Parse input coming from a string. Return error code, print some errors. */ -node * -PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret) -{ - return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0); -} - -node * -PyParser_ParseStringFlags(const char *s, grammar *g, int start, - perrdetail *err_ret, int flags) -{ - return PyParser_ParseStringFlagsFilename(s, NULL, - g, start, err_ret, flags); -} - -node * -PyParser_ParseStringFlagsFilename(const char *s, const char *filename, - grammar *g, int start, - perrdetail *err_ret, int flags) -{ - int iflags = flags; - return PyParser_ParseStringFlagsFilenameEx(s, filename, g, start, - err_ret, &iflags); -} - -node * -PyParser_ParseStringObject(const char *s, PyObject *filename, - grammar *g, int start, - perrdetail *err_ret, int *flags) -{ - struct tok_state *tok; - int exec_input = start == file_input; - - if (initerr(err_ret, filename) < 0) - return NULL; - - if (PySys_Audit("compile", "yO", s, err_ret->filename) < 0) { - err_ret->error = E_ERROR; - return NULL; - } - - if (*flags & PyPARSE_IGNORE_COOKIE) - tok = PyTokenizer_FromUTF8(s, exec_input); - else - tok = PyTokenizer_FromString(s, exec_input); - if (tok == NULL) { - err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM; - return NULL; - } - if (*flags & PyPARSE_TYPE_COMMENTS) { - tok->type_comments = 1; - } - - Py_INCREF(err_ret->filename); - tok->filename = err_ret->filename; - if (*flags & PyPARSE_ASYNC_HACKS) - tok->async_hacks = 1; - return parsetok(tok, g, start, err_ret, flags); -} - -node * -PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str, - grammar *g, int start, - perrdetail *err_ret, int *flags) -{ - node *n; - PyObject *filename = NULL; - if (filename_str != NULL) { - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) { - err_ret->error = E_ERROR; - return NULL; - } - } - n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags); - Py_XDECREF(filename); - return n; -} - -/* Parse input coming from a file. Return error code, print some errors. */ - -node * -PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start, - const char *ps1, const char *ps2, - perrdetail *err_ret) -{ - return PyParser_ParseFileFlags(fp, filename, NULL, - g, start, ps1, ps2, err_ret, 0); -} - -node * -PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc, - grammar *g, int start, - const char *ps1, const char *ps2, - perrdetail *err_ret, int flags) -{ - int iflags = flags; - return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1, - ps2, err_ret, &iflags); -} - -node * -PyParser_ParseFileObject(FILE *fp, PyObject *filename, - const char *enc, grammar *g, int start, - const char *ps1, const char *ps2, - perrdetail *err_ret, int *flags) -{ - struct tok_state *tok; - - if (initerr(err_ret, filename) < 0) - return NULL; - - if (PySys_Audit("compile", "OO", Py_None, err_ret->filename) < 0) { - return NULL; - } - - if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) { - err_ret->error = E_NOMEM; - return NULL; - } - if (*flags & PyPARSE_TYPE_COMMENTS) { - tok->type_comments = 1; - } - Py_INCREF(err_ret->filename); - tok->filename = err_ret->filename; - return parsetok(tok, g, start, err_ret, flags); -} - -node * -PyParser_ParseFileFlagsEx(FILE *fp, const char *filename, - const char *enc, grammar *g, int start, - const char *ps1, const char *ps2, - perrdetail *err_ret, int *flags) -{ - node *n; - PyObject *fileobj = NULL; - if (filename != NULL) { - fileobj = PyUnicode_DecodeFSDefault(filename); - if (fileobj == NULL) { - err_ret->error = E_ERROR; - return NULL; - } - } - n = PyParser_ParseFileObject(fp, fileobj, enc, g, - start, ps1, ps2, err_ret, flags); - Py_XDECREF(fileobj); - return n; -} - -/* Parse input coming from the given tokenizer structure. - Return error code. */ - -static node * -parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, - int *flags) -{ - parser_state *ps; - node *n; - int started = 0; - int col_offset, end_col_offset; - growable_comment_array type_ignores; - - if (!growable_comment_array_init(&type_ignores, 10)) { - err_ret->error = E_NOMEM; - PyTokenizer_Free(tok); - return NULL; - } - - if ((ps = PyParser_New(g, start)) == NULL) { - err_ret->error = E_NOMEM; - growable_comment_array_deallocate(&type_ignores); - PyTokenizer_Free(tok); - return NULL; - } -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - if (*flags & PyPARSE_BARRY_AS_BDFL) - ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL; - if (*flags & PyPARSE_TYPE_COMMENTS) - ps->p_flags |= PyCF_TYPE_COMMENTS; -#endif - - for (;;) { - const char *a, *b; - int type; - size_t len; - char *str; - col_offset = -1; - int lineno; - const char *line_start; - - type = PyTokenizer_Get(tok, &a, &b); - - len = (a != NULL && b != NULL) ? b - a : 0; - str = (char *) PyObject_MALLOC(len + 1); - if (str == NULL) { - err_ret->error = E_NOMEM; - break; - } - if (len > 0) - strncpy(str, a, len); - str[len] = '\0'; - -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - if (type == NOTEQUAL) { - if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && - strcmp(str, "!=")) { - PyObject_FREE(str); - err_ret->error = E_SYNTAX; - break; - } - else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && - strcmp(str, "<>")) { - PyObject_FREE(str); - err_ret->expected = NOTEQUAL; - err_ret->error = E_SYNTAX; - break; - } - } -#endif - - /* 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) */ - lineno = type == STRING ? tok->first_lineno : tok->lineno; - line_start = type == STRING ? tok->multi_line_start : tok->line_start; - if (a != NULL && a >= line_start) { - col_offset = Py_SAFE_DOWNCAST(a - line_start, - intptr_t, int); - } - else { - col_offset = -1; - } - - if (b != NULL && b >= tok->line_start) { - end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start, - intptr_t, int); - } - else { - end_col_offset = -1; - } - - if (type == TYPE_IGNORE) { - if (!growable_comment_array_add(&type_ignores, tok->lineno, str)) { - err_ret->error = E_NOMEM; - break; - } - continue; - } - - if (type == ERRORTOKEN) { - err_ret->error = tok->done; - break; - } - if (type == ENDMARKER && started) { - type = NEWLINE; /* Add an extra newline */ - started = 0; - /* Add the right number of dedent tokens, - except if a certain flag is given -- - codeop.py uses this. */ - if (tok->indent && - !(*flags & PyPARSE_DONT_IMPLY_DEDENT)) - { - tok->pendin = -tok->indent; - tok->indent = 0; - } - } - else { - started = 1; - } - - if ((err_ret->error = - PyParser_AddToken(ps, (int)type, str, - lineno, col_offset, tok->lineno, end_col_offset, - &(err_ret->expected))) != E_OK) { - if (tok->done == E_EOF && !ISWHITESPACE(type)) { - tok->done = E_SYNTAX; - } - if (err_ret->error != E_DONE) { - PyObject_FREE(str); - err_ret->token = type; - } - break; - } - } - - if (err_ret->error == E_DONE) { - n = ps->p_tree; - ps->p_tree = NULL; - - if (n->n_type == file_input) { - /* Put type_ignore nodes in the ENDMARKER of file_input. */ - int num; - node *ch; - size_t i; - - num = NCH(n); - ch = CHILD(n, num - 1); - REQ(ch, ENDMARKER); - - for (i = 0; i < type_ignores.num_items; i++) { - int res = PyNode_AddChild(ch, TYPE_IGNORE, type_ignores.items[i].comment, - type_ignores.items[i].lineno, 0, - type_ignores.items[i].lineno, 0); - if (res != 0) { - err_ret->error = res; - PyNode_Free(n); - n = NULL; - break; - } - type_ignores.items[i].comment = NULL; - } - } - - /* Check that the source for a single input statement really - is a single statement by looking at what is left in the - buffer after parsing. Trailing whitespace and comments - are OK. */ - if (err_ret->error == E_DONE && start == single_input) { - const char *cur = tok->cur; - char c = *tok->cur; - - for (;;) { - while (c == ' ' || c == '\t' || c == '\n' || c == '\014') - c = *++cur; - - if (!c) - break; - - if (c != '#') { - err_ret->error = E_BADSINGLE; - PyNode_Free(n); - n = NULL; - break; - } - - /* Suck up comment. */ - while (c && c != '\n') - c = *++cur; - } - } - } - else - n = NULL; - - growable_comment_array_deallocate(&type_ignores); - -#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - *flags = ps->p_flags; -#endif - PyParser_Delete(ps); - - if (n == NULL) { - if (tok->done == E_EOF) - err_ret->error = E_EOF; - err_ret->lineno = tok->lineno; - if (tok->buf != NULL) { - size_t len; - assert(tok->cur - tok->buf < INT_MAX); - /* if we've managed to parse a token, point the offset to its start, - * else use the current reading position of the tokenizer - */ - err_ret->offset = col_offset != -1 ? col_offset + 1 : ((int)(tok->cur - tok->buf)); - len = tok->inp - tok->buf; - err_ret->text = (char *) PyObject_MALLOC(len + 1); - if (err_ret->text != NULL) { - if (len > 0) - strncpy(err_ret->text, tok->buf, len); - err_ret->text[len] = '\0'; - } - } - } else if (tok->encoding != NULL) { - /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was - * allocated using PyMem_ - */ - node* r = PyNode_New(encoding_decl); - if (r) - r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1); - if (!r || !r->n_str) { - err_ret->error = E_NOMEM; - if (r) - PyObject_FREE(r); - n = NULL; - goto done; - } - strcpy(r->n_str, tok->encoding); - PyMem_FREE(tok->encoding); - tok->encoding = NULL; - r->n_nchildren = 1; - r->n_child = n; - n = r; - } - -done: - PyTokenizer_Free(tok); - - if (n != NULL) { - _PyNode_FinalizeEndPos(n); - } - return n; -} - -static int -initerr(perrdetail *err_ret, PyObject *filename) -{ - err_ret->error = E_OK; - err_ret->lineno = 0; - err_ret->offset = 0; - err_ret->text = NULL; - err_ret->token = -1; - err_ret->expected = -1; - if (filename) { - Py_INCREF(filename); - err_ret->filename = filename; - } - else { - err_ret->filename = PyUnicode_FromString(""); - if (err_ret->filename == NULL) { - err_ret->error = E_ERROR; - return -1; - } - } - return 0; -} diff --git a/contrib/tools/python3/src/Parser/peg_api.c b/contrib/tools/python3/src/Parser/peg_api.c new file mode 100644 index 00000000000..1487ac4ff85 --- /dev/null +++ b/contrib/tools/python3/src/Parser/peg_api.c @@ -0,0 +1,28 @@ +#include "Python.h" + +#include "tokenizer.h" +#include "pegen.h" + +mod_ty +_PyParser_ASTFromString(const char *str, PyObject* filename, int mode, + PyCompilerFlags *flags, PyArena *arena) +{ + if (PySys_Audit("compile", "yO", str, filename) < 0) { + return NULL; + } + + mod_ty result = _PyPegen_run_parser_from_string(str, mode, filename, flags, arena); + return result; +} + +mod_ty +_PyParser_ASTFromFile(FILE *fp, PyObject *filename_ob, const char *enc, + int mode, const char *ps1, const char* ps2, + PyCompilerFlags *flags, int *errcode, PyArena *arena) +{ + if (PySys_Audit("compile", "OO", Py_None, filename_ob) < 0) { + return NULL; + } + return _PyPegen_run_parser_from_file_pointer(fp, mode, filename_ob, enc, ps1, ps2, + flags, errcode, arena); +} diff --git a/contrib/tools/python3/src/Parser/pegen.c b/contrib/tools/python3/src/Parser/pegen.c new file mode 100644 index 00000000000..df174760134 --- /dev/null +++ b/contrib/tools/python3/src/Parser/pegen.c @@ -0,0 +1,2630 @@ +#include +#include "pycore_ast.h" // _PyAST_Validate(), +#include +#include "tokenizer.h" + +#include "pegen.h" +#include "string_parser.h" + +PyObject * +_PyPegen_new_type_comment(Parser *p, const char *s) +{ + PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL); + if (res == NULL) { + return NULL; + } + if (_PyArena_AddPyObject(p->arena, res) < 0) { + Py_DECREF(res); + return NULL; + } + return res; +} + +arg_ty +_PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc) +{ + if (tc == NULL) { + return a; + } + const char *bytes = PyBytes_AsString(tc->bytes); + if (bytes == NULL) { + return NULL; + } + PyObject *tco = _PyPegen_new_type_comment(p, bytes); + if (tco == NULL) { + return NULL; + } + return _PyAST_arg(a->arg, a->annotation, tco, + a->lineno, a->col_offset, a->end_lineno, a->end_col_offset, + p->arena); +} + +static int +init_normalization(Parser *p) +{ + if (p->normalize) { + return 1; + } + PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); + if (!m) + { + return 0; + } + p->normalize = PyObject_GetAttrString(m, "normalize"); + Py_DECREF(m); + if (!p->normalize) + { + return 0; + } + return 1; +} + +/* Checks if the NOTEQUAL token is valid given the current parser flags +0 indicates success and nonzero indicates failure (an exception may be set) */ +int +_PyPegen_check_barry_as_flufl(Parser *p, Token* t) { + assert(t->bytes != NULL); + assert(t->type == NOTEQUAL); + + const char* tok_str = PyBytes_AS_STRING(t->bytes); + if (p->flags & PyPARSE_BARRY_AS_BDFL && strcmp(tok_str, "<>") != 0) { + RAISE_SYNTAX_ERROR("with Barry as BDFL, use '<>' instead of '!='"); + return -1; + } + if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) { + return strcmp(tok_str, "!="); + } + return 0; +} + +int +_PyPegen_check_legacy_stmt(Parser *p, expr_ty name) { + if (name->kind != Name_kind) { + return 0; + } + const char* candidates[2] = {"print", "exec"}; + for (int i=0; i<2; i++) { + if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) { + return 1; + } + } + return 0; +} + +PyObject * +_PyPegen_new_identifier(Parser *p, const char *n) +{ + PyObject *id = PyUnicode_DecodeUTF8(n, strlen(n), NULL); + if (!id) { + goto error; + } + /* PyUnicode_DecodeUTF8 should always return a ready string. */ + assert(PyUnicode_IS_READY(id)); + /* Check whether there are non-ASCII characters in the + identifier; if so, normalize to NFKC. */ + if (!PyUnicode_IS_ASCII(id)) + { + PyObject *id2; + if (!init_normalization(p)) + { + Py_DECREF(id); + goto error; + } + PyObject *form = PyUnicode_InternFromString("NFKC"); + if (form == NULL) + { + Py_DECREF(id); + goto error; + } + PyObject *args[2] = {form, id}; + id2 = _PyObject_FastCall(p->normalize, args, 2); + Py_DECREF(id); + Py_DECREF(form); + if (!id2) { + goto error; + } + if (!PyUnicode_Check(id2)) + { + PyErr_Format(PyExc_TypeError, + "unicodedata.normalize() must return a string, not " + "%.200s", + _PyType_Name(Py_TYPE(id2))); + Py_DECREF(id2); + goto error; + } + id = id2; + } + PyUnicode_InternInPlace(&id); + if (_PyArena_AddPyObject(p->arena, id) < 0) + { + Py_DECREF(id); + goto error; + } + return id; + +error: + p->error_indicator = 1; + return NULL; +} + +static PyObject * +_create_dummy_identifier(Parser *p) +{ + return _PyPegen_new_identifier(p, ""); +} + +static inline Py_ssize_t +byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) +{ + const char *str = PyUnicode_AsUTF8(line); + if (!str) { + return 0; + } + Py_ssize_t len = strlen(str); + if (col_offset > len + 1) { + col_offset = len + 1; + } + assert(col_offset >= 0); + PyObject *text = PyUnicode_DecodeUTF8(str, col_offset, "replace"); + if (!text) { + return 0; + } + Py_ssize_t size = PyUnicode_GET_LENGTH(text); + Py_DECREF(text); + return size; +} + +const char * +_PyPegen_get_expr_name(expr_ty e) +{ + assert(e != NULL); + switch (e->kind) { + case Attribute_kind: + return "attribute"; + case Subscript_kind: + return "subscript"; + case Starred_kind: + return "starred"; + case Name_kind: + return "name"; + case List_kind: + return "list"; + case Tuple_kind: + return "tuple"; + case Lambda_kind: + return "lambda"; + case Call_kind: + return "function call"; + case BoolOp_kind: + case BinOp_kind: + case UnaryOp_kind: + return "expression"; + case GeneratorExp_kind: + return "generator expression"; + case Yield_kind: + case YieldFrom_kind: + return "yield expression"; + case Await_kind: + return "await expression"; + case ListComp_kind: + return "list comprehension"; + case SetComp_kind: + return "set comprehension"; + case DictComp_kind: + return "dict comprehension"; + case Dict_kind: + return "dict literal"; + case Set_kind: + return "set display"; + case JoinedStr_kind: + case FormattedValue_kind: + return "f-string expression"; + case Constant_kind: { + PyObject *value = e->v.Constant.value; + if (value == Py_None) { + return "None"; + } + if (value == Py_False) { + return "False"; + } + if (value == Py_True) { + return "True"; + } + if (value == Py_Ellipsis) { + return "ellipsis"; + } + return "literal"; + } + case Compare_kind: + return "comparison"; + case IfExp_kind: + return "conditional expression"; + case NamedExpr_kind: + return "named expression"; + default: + PyErr_Format(PyExc_SystemError, + "unexpected expression in assignment %d (line %d)", + e->kind, e->lineno); + return NULL; + } +} + +static int +raise_decode_error(Parser *p) +{ + assert(PyErr_Occurred()); + const char *errtype = NULL; + if (PyErr_ExceptionMatches(PyExc_UnicodeError)) { + errtype = "unicode error"; + } + else if (PyErr_ExceptionMatches(PyExc_ValueError)) { + errtype = "value error"; + } + if (errtype) { + PyObject *type; + PyObject *value; + PyObject *tback; + PyObject *errstr; + PyErr_Fetch(&type, &value, &tback); + errstr = PyObject_Str(value); + if (errstr) { + RAISE_SYNTAX_ERROR("(%s) %U", errtype, errstr); + Py_DECREF(errstr); + } + else { + PyErr_Clear(); + RAISE_SYNTAX_ERROR("(%s) unknown error", errtype); + } + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(tback); + } + + return -1; +} + +static inline void +raise_unclosed_parentheses_error(Parser *p) { + int error_lineno = p->tok->parenlinenostack[p->tok->level-1]; + int error_col = p->tok->parencolstack[p->tok->level-1]; + RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, + error_lineno, error_col, error_lineno, -1, + "'%c' was never closed", + p->tok->parenstack[p->tok->level-1]); +} + +static void +raise_tokenizer_init_error(PyObject *filename) +{ + if (!(PyErr_ExceptionMatches(PyExc_LookupError) + || PyErr_ExceptionMatches(PyExc_SyntaxError) + || PyErr_ExceptionMatches(PyExc_ValueError) + || PyErr_ExceptionMatches(PyExc_UnicodeDecodeError))) { + return; + } + PyObject *errstr = NULL; + PyObject *tuple = NULL; + PyObject *type; + PyObject *value; + PyObject *tback; + PyErr_Fetch(&type, &value, &tback); + errstr = PyObject_Str(value); + if (!errstr) { + goto error; + } + + PyObject *tmp = Py_BuildValue("(OiiO)", filename, 0, -1, Py_None); + if (!tmp) { + goto error; + } + + tuple = PyTuple_Pack(2, errstr, tmp); + Py_DECREF(tmp); + if (!value) { + goto error; + } + PyErr_SetObject(PyExc_SyntaxError, tuple); + +error: + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(tback); + Py_XDECREF(errstr); + Py_XDECREF(tuple); +} + +static int +tokenizer_error(Parser *p) +{ + if (PyErr_Occurred()) { + return -1; + } + + const char *msg = NULL; + PyObject* errtype = PyExc_SyntaxError; + Py_ssize_t col_offset = -1; + switch (p->tok->done) { + case E_TOKEN: + msg = "invalid token"; + break; + case E_EOF: + if (p->tok->level) { + raise_unclosed_parentheses_error(p); + } else { + RAISE_SYNTAX_ERROR("unexpected EOF while parsing"); + } + return -1; + case E_DEDENT: + RAISE_INDENTATION_ERROR("unindent does not match any outer indentation level"); + return -1; + 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: { + col_offset = p->tok->cur - p->tok->buf - 1; + msg = "unexpected character after line continuation character"; + break; + } + default: + msg = "unknown parsing error"; + } + + RAISE_ERROR_KNOWN_LOCATION(p, errtype, p->tok->lineno, + col_offset >= 0 ? col_offset : 0, + p->tok->lineno, -1, msg); + return -1; +} + +void * +_PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...) +{ + if (p->fill == 0) { + va_list va; + va_start(va, errmsg); + _PyPegen_raise_error_known_location(p, errtype, 0, 0, 0, -1, errmsg, va); + va_end(va); + return NULL; + } + + Token *t = p->known_err_token != NULL ? p->known_err_token : p->tokens[p->fill - 1]; + Py_ssize_t col_offset; + Py_ssize_t end_col_offset = -1; + if (t->col_offset == -1) { + if (p->tok->cur == p->tok->buf) { + col_offset = 0; + } else { + const char* start = p->tok->buf ? p->tok->line_start : p->tok->buf; + col_offset = Py_SAFE_DOWNCAST(p->tok->cur - start, intptr_t, int); + } + } else { + col_offset = t->col_offset + 1; + } + + if (t->end_col_offset != -1) { + end_col_offset = t->end_col_offset + 1; + } + + va_list va; + va_start(va, errmsg); + _PyPegen_raise_error_known_location(p, errtype, t->lineno, col_offset, t->end_lineno, end_col_offset, errmsg, va); + va_end(va); + + return NULL; +} + +static PyObject * +get_error_line(Parser *p, Py_ssize_t lineno) +{ + /* If the file descriptor is interactive, the source lines of the current + * (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); + + char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; + assert(cur_line != NULL); + const char* buf_end = p->tok->fp_interactive ? p->tok->interactive_src_end : p->tok->inp; + + Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno; + + for (int i = 0; i < relative_lineno - 1; i++) { + char *new_line = strchr(cur_line, '\n') + 1; + assert(new_line != NULL && new_line <= buf_end); + if (new_line == NULL || new_line > buf_end) { + break; + } + cur_line = new_line; + } + + char *next_newline; + if ((next_newline = strchr(cur_line, '\n')) == NULL) { // This is the last line + next_newline = cur_line + strlen(cur_line); + } + return PyUnicode_DecodeUTF8(cur_line, next_newline - cur_line, "replace"); +} + +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) +{ + PyObject *value = NULL; + PyObject *errstr = NULL; + PyObject *error_line = NULL; + PyObject *tmp = NULL; + p->error_indicator = 1; + + if (end_lineno == CURRENT_POS) { + end_lineno = p->tok->lineno; + } + if (end_col_offset == CURRENT_POS) { + end_col_offset = p->tok->cur - p->tok->line_start; + } + + if (p->start_rule == Py_fstring_input) { + const char *fstring_msg = "f-string: "; + Py_ssize_t len = strlen(fstring_msg) + strlen(errmsg); + + char *new_errmsg = PyMem_Malloc(len + 1); // Lengths of both strings plus NULL character + if (!new_errmsg) { + return (void *) PyErr_NoMemory(); + } + + // Copy both strings into new buffer + memcpy(new_errmsg, fstring_msg, strlen(fstring_msg)); + memcpy(new_errmsg + strlen(fstring_msg), errmsg, strlen(errmsg)); + new_errmsg[len] = 0; + errmsg = new_errmsg; + } + errstr = PyUnicode_FromFormatV(errmsg, va); + if (!errstr) { + goto error; + } + + if (p->tok->fp_interactive) { + error_line = get_error_line(p, lineno); + } + else if (p->start_rule == Py_file_input) { + error_line = _PyErr_ProgramDecodedTextObject(p->tok->filename, + (int) lineno, p->tok->encoding); + } + + if (!error_line) { + /* PyErr_ProgramTextObject was not called or returned NULL. If it was not called, + then we need to find the error line from some other source, because + p->start_rule != Py_file_input. If it returned NULL, then it either unexpectedly + failed or we're parsing from a string or the REPL. There's a third edge case where + we're actually parsing from a file, which has an E_EOF SyntaxError and in that case + `PyErr_ProgramTextObject` fails because lineno points to last_file_line + 1, which + does not physically exist */ + assert(p->tok->fp == NULL || p->tok->fp == stdin || p->tok->done == E_EOF); + + if (p->tok->lineno <= lineno && p->tok->inp > p->tok->buf) { + Py_ssize_t size = p->tok->inp - p->tok->buf; + error_line = PyUnicode_DecodeUTF8(p->tok->buf, size, "replace"); + } + else if (p->tok->fp == NULL || p->tok->fp == stdin) { + error_line = get_error_line(p, lineno); + } + else { + error_line = PyUnicode_FromStringAndSize("", 0); + } + if (!error_line) { + goto error; + } + } + + if (p->start_rule == Py_fstring_input) { + col_offset -= p->starting_col_offset; + end_col_offset -= p->starting_col_offset; + } + + Py_ssize_t col_number = col_offset; + Py_ssize_t end_col_number = end_col_offset; + + if (p->tok->encoding != NULL) { + col_number = byte_offset_to_character_offset(error_line, col_offset); + end_col_number = end_col_number > 0 ? + byte_offset_to_character_offset(error_line, end_col_offset) : + end_col_number; + } + tmp = Py_BuildValue("(OiiNii)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); + if (!tmp) { + goto error; + } + value = PyTuple_Pack(2, errstr, tmp); + Py_DECREF(tmp); + if (!value) { + goto error; + } + PyErr_SetObject(errtype, value); + + Py_DECREF(errstr); + Py_DECREF(value); + if (p->start_rule == Py_fstring_input) { + PyMem_Free((void *)errmsg); + } + return NULL; + +error: + Py_XDECREF(errstr); + Py_XDECREF(error_line); + if (p->start_rule == Py_fstring_input) { + PyMem_Free((void *)errmsg); + } + return NULL; +} + +#if 0 +static const char * +token_name(int type) +{ + if (0 <= type && type <= N_TOKENS) { + return _PyParser_TokenNames[type]; + } + return ""; +} +#endif + +// Here, mark is the start of the node, while p->mark is the end. +// If node==NULL, they should be the same. +int +_PyPegen_insert_memo(Parser *p, int mark, int type, void *node) +{ + // Insert in front + Memo *m = _PyArena_Malloc(p->arena, sizeof(Memo)); + if (m == NULL) { + return -1; + } + m->type = type; + m->node = node; + m->mark = p->mark; + m->next = p->tokens[mark]->memo; + p->tokens[mark]->memo = m; + return 0; +} + +// Like _PyPegen_insert_memo(), but updates an existing node if found. +int +_PyPegen_update_memo(Parser *p, int mark, int type, void *node) +{ + for (Memo *m = p->tokens[mark]->memo; m != NULL; m = m->next) { + if (m->type == type) { + // Update existing node. + m->node = node; + m->mark = p->mark; + return 0; + } + } + // Insert new node. + return _PyPegen_insert_memo(p, mark, type, node); +} + +// Return dummy NAME. +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; +} + +static int +_get_keyword_or_name_type(Parser *p, const char *name, int name_len) +{ + 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) { + return k->type; + } + } + return NAME; +} + +static int +growable_comment_array_init(growable_comment_array *arr, size_t initial_size) { + assert(initial_size > 0); + arr->items = PyMem_Malloc(initial_size * sizeof(*arr->items)); + arr->size = initial_size; + arr->num_items = 0; + + return arr->items != NULL; +} + +static int +growable_comment_array_add(growable_comment_array *arr, int lineno, char *comment) { + if (arr->num_items >= arr->size) { + size_t new_size = arr->size * 2; + void *new_items_array = PyMem_Realloc(arr->items, new_size * sizeof(*arr->items)); + if (!new_items_array) { + return 0; + } + arr->items = new_items_array; + arr->size = new_size; + } + + arr->items[arr->num_items].lineno = lineno; + arr->items[arr->num_items].comment = comment; // Take ownership + arr->num_items++; + return 1; +} + +static void +growable_comment_array_deallocate(growable_comment_array *arr) { + for (unsigned i = 0; i < arr->num_items; i++) { + PyMem_Free(arr->items[i].comment); + } + PyMem_Free(arr->items); +} + +static int +initialize_token(Parser *p, Token *token, const char *start, const char *end, int token_type) { + assert(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) { + return -1; + } + + if (_PyArena_AddPyObject(p->arena, token->bytes) < 0) { + Py_DECREF(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; + + 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; + + p->fill += 1; + + if (token_type == ERRORTOKEN && p->tok->done == E_DECODE) { + return raise_decode_error(p); + } + + return (token_type == ERRORTOKEN ? tokenizer_error(p) : 0); +} + +static int +_resize_tokens_array(Parser *p) { + int newsize = p->size * 2; + Token **new_tokens = PyMem_Realloc(p->tokens, newsize * sizeof(Token *)); + if (new_tokens == NULL) { + PyErr_NoMemory(); + return -1; + } + p->tokens = new_tokens; + + for (int i = p->size; i < newsize; i++) { + p->tokens[i] = PyMem_Calloc(1, sizeof(Token)); + if (p->tokens[i] == NULL) { + p->size = i; // Needed, in order to cleanup correctly after parser fails + PyErr_NoMemory(); + return -1; + } + } + p->size = newsize; + return 0; +} + +int +_PyPegen_fill_token(Parser *p) +{ + const char *start; + const char *end; + int type = PyTokenizer_Get(p->tok, &start, &end); + + // Record and skip '# type: ignore' comments + while (type == TYPE_IGNORE) { + Py_ssize_t len = end - start; + char *tag = PyMem_Malloc(len + 1); + if (tag == NULL) { + PyErr_NoMemory(); + return -1; + } + strncpy(tag, 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; + } + type = PyTokenizer_Get(p->tok, &start, &end); + } + + // If we have reached the end and we are in single input mode we need to insert a newline and reset the parsing + if (p->start_rule == Py_single_input && type == ENDMARKER && p->parsing_started) { + type = NEWLINE; /* Add an extra newline */ + p->parsing_started = 0; + + if (p->tok->indent && !(p->flags & PyPARSE_DONT_IMPLY_DEDENT)) { + p->tok->pendin = -p->tok->indent; + p->tok->indent = 0; + } + } + else { + p->parsing_started = 1; + } + + // 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; + } + + Token *t = p->tokens[p->fill]; + return initialize_token(p, t, start, end, type); +} + + +#if defined(Py_DEBUG) +// Instrumentation to count the effectiveness of memoization. +// The array counts the number of tokens skipped by memoization, +// indexed by type. + +#define NSTATISTICS 2000 +static long memo_statistics[NSTATISTICS]; + +void +_PyPegen_clear_memo_statistics() +{ + for (int i = 0; i < NSTATISTICS; i++) { + memo_statistics[i] = 0; + } +} + +PyObject * +_PyPegen_get_memo_statistics() +{ + PyObject *ret = PyList_New(NSTATISTICS); + if (ret == NULL) { + return NULL; + } + for (int i = 0; i < NSTATISTICS; i++) { + PyObject *value = PyLong_FromLong(memo_statistics[i]); + if (value == NULL) { + Py_DECREF(ret); + return NULL; + } + // PyList_SetItem borrows a reference to value. + if (PyList_SetItem(ret, i, value) < 0) { + Py_DECREF(ret); + return NULL; + } + } + return ret; +} +#endif + +int // bool +_PyPegen_is_memoized(Parser *p, int type, void *pres) +{ + if (p->mark == p->fill) { + if (_PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + return -1; + } + } + + Token *t = p->tokens[p->mark]; + + for (Memo *m = t->memo; m != NULL; m = m->next) { + if (m->type == type) { +#if defined(PY_DEBUG) + if (0 <= type && type < NSTATISTICS) { + long count = m->mark - p->mark; + // A memoized negative result counts for one. + if (count <= 0) { + count = 1; + } + memo_statistics[type] += count; + } +#endif + p->mark = m->mark; + *(void **)(pres) = m->node; + return 1; + } + } + return 0; +} + +int +_PyPegen_lookahead_with_name(int positive, expr_ty (func)(Parser *), Parser *p) +{ + int mark = p->mark; + void *res = func(p); + p->mark = mark; + return (res != NULL) == positive; +} + +int +_PyPegen_lookahead_with_string(int positive, expr_ty (func)(Parser *, const char*), Parser *p, const char* arg) +{ + int mark = p->mark; + void *res = func(p, arg); + p->mark = mark; + return (res != NULL) == positive; +} + +int +_PyPegen_lookahead_with_int(int positive, Token *(func)(Parser *, int), Parser *p, int arg) +{ + int mark = p->mark; + void *res = func(p, arg); + p->mark = mark; + return (res != NULL) == positive; +} + +int +_PyPegen_lookahead(int positive, void *(func)(Parser *), Parser *p) +{ + int mark = p->mark; + void *res = (void*)func(p); + p->mark = mark; + return (res != NULL) == positive; +} + +Token * +_PyPegen_expect_token(Parser *p, int type) +{ + if (p->mark == p->fill) { + if (_PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + return NULL; + } + } + Token *t = p->tokens[p->mark]; + if (t->type != type) { + return NULL; + } + p->mark += 1; + return t; +} + +Token * +_PyPegen_expect_forced_token(Parser *p, int type, const char* expected) { + + if (p->error_indicator == 1) { + return NULL; + } + + if (p->mark == p->fill) { + if (_PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + return NULL; + } + } + Token *t = p->tokens[p->mark]; + if (t->type != type) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(t, "expected '%s'", expected); + return NULL; + } + p->mark += 1; + return t; +} + +expr_ty +_PyPegen_expect_soft_keyword(Parser *p, const char *keyword) +{ + if (p->mark == p->fill) { + if (_PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + return NULL; + } + } + Token *t = p->tokens[p->mark]; + if (t->type != NAME) { + return NULL; + } + const char *s = PyBytes_AsString(t->bytes); + if (!s) { + p->error_indicator = 1; + return NULL; + } + if (strcmp(s, keyword) != 0) { + return NULL; + } + return _PyPegen_name_token(p); +} + +Token * +_PyPegen_get_last_nonnwhitespace_token(Parser *p) +{ + assert(p->mark >= 0); + Token *token = NULL; + for (int m = p->mark - 1; m >= 0; m--) { + token = p->tokens[m]; + if (token->type != ENDMARKER && (token->type < NEWLINE || token->type > DEDENT)) { + break; + } + } + return token; +} + +static expr_ty +_PyPegen_name_from_token(Parser *p, Token* t) +{ + if (t == NULL) { + return NULL; + } + const char *s = PyBytes_AsString(t->bytes); + if (!s) { + p->error_indicator = 1; + return NULL; + } + PyObject *id = _PyPegen_new_identifier(p, s); + if (id == NULL) { + p->error_indicator = 1; + return NULL; + } + return _PyAST_Name(id, Load, t->lineno, t->col_offset, t->end_lineno, + t->end_col_offset, p->arena); +} + + +expr_ty +_PyPegen_name_token(Parser *p) +{ + Token *t = _PyPegen_expect_token(p, NAME); + return _PyPegen_name_from_token(p, t); +} + +void * +_PyPegen_string_token(Parser *p) +{ + return _PyPegen_expect_token(p, STRING); +} + + +expr_ty _PyPegen_soft_keyword_token(Parser *p) { + Token *t = _PyPegen_expect_token(p, NAME); + if (t == NULL) { + return NULL; + } + char *the_token; + Py_ssize_t size; + PyBytes_AsStringAndSize(t->bytes, &the_token, &size); + for (char **keyword = p->soft_keywords; *keyword != NULL; keyword++) { + if (strncmp(*keyword, the_token, size) == 0) { + return _PyPegen_name_from_token(p, t); + } + } + return NULL; +} + +static PyObject * +parsenumber_raw(const char *s) +{ + const char *end; + long x; + double dx; + Py_complex compl; + int imflag; + + assert(s != NULL); + errno = 0; + end = s + strlen(s) - 1; + imflag = *end == 'j' || *end == 'J'; + if (s[0] == '0') { + x = (long)PyOS_strtoul(s, (char **)&end, 0); + if (x < 0 && errno == 0) { + return PyLong_FromString(s, (char **)0, 0); + } + } + else { + x = PyOS_strtol(s, (char **)&end, 0); + } + if (*end == '\0') { + if (errno != 0) { + return PyLong_FromString(s, (char **)0, 0); + } + return PyLong_FromLong(x); + } + /* XXX Huge floats may silently fail */ + if (imflag) { + compl.real = 0.; + compl.imag = PyOS_string_to_double(s, (char **)&end, NULL); + if (compl.imag == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyComplex_FromCComplex(compl); + } + dx = PyOS_string_to_double(s, NULL, NULL); + if (dx == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(dx); +} + +static PyObject * +parsenumber(const char *s) +{ + char *dup; + char *end; + PyObject *res = NULL; + + assert(s != NULL); + + if (strchr(s, '_') == NULL) { + return parsenumber_raw(s); + } + /* Create a duplicate without underscores. */ + dup = PyMem_Malloc(strlen(s) + 1); + if (dup == NULL) { + return PyErr_NoMemory(); + } + end = dup; + for (; *s; s++) { + if (*s != '_') { + *end++ = *s; + } + } + *end = '\0'; + res = parsenumber_raw(dup); + PyMem_Free(dup); + return res; +} + +expr_ty +_PyPegen_number_token(Parser *p) +{ + Token *t = _PyPegen_expect_token(p, NUMBER); + if (t == NULL) { + return NULL; + } + + const char *num_raw = PyBytes_AsString(t->bytes); + if (num_raw == NULL) { + p->error_indicator = 1; + return NULL; + } + + if (p->feature_version < 6 && strchr(num_raw, '_') != NULL) { + p->error_indicator = 1; + return RAISE_SYNTAX_ERROR("Underscores in numeric literals are only supported " + "in Python 3.6 and greater"); + } + + PyObject *c = parsenumber(num_raw); + + if (c == NULL) { + p->error_indicator = 1; + return NULL; + } + + if (_PyArena_AddPyObject(p->arena, c) < 0) { + Py_DECREF(c); + p->error_indicator = 1; + return NULL; + } + + return _PyAST_Constant(c, NULL, t->lineno, t->col_offset, t->end_lineno, + t->end_col_offset, p->arena); +} + +/* Check that the source for a single input statement really is a single + statement by looking at what is left in the buffer after parsing. + Trailing whitespace and comments are OK. */ +static int // bool +bad_single_statement(Parser *p) +{ + char *cur = p->tok->cur; + char c = *cur; + + for (;;) { + while (c == ' ' || c == '\t' || c == '\n' || c == '\014') { + c = *++cur; + } + + if (!c) { + return 0; + } + + if (c != '#') { + return 1; + } + + /* Suck up comment. */ + while (c && c != '\n') { + c = *++cur; + } + } +} + +void +_PyPegen_Parser_Free(Parser *p) +{ + Py_XDECREF(p->normalize); + for (int i = 0; i < p->size; i++) { + PyMem_Free(p->tokens[i]); + } + PyMem_Free(p->tokens); + growable_comment_array_deallocate(&p->type_ignore_comments); + PyMem_Free(p); +} + +static int +compute_parser_flags(PyCompilerFlags *flags) +{ + int parser_flags = 0; + if (!flags) { + return 0; + } + if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT) { + parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; + } + if (flags->cf_flags & PyCF_IGNORE_COOKIE) { + parser_flags |= PyPARSE_IGNORE_COOKIE; + } + if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) { + parser_flags |= PyPARSE_BARRY_AS_BDFL; + } + if (flags->cf_flags & PyCF_TYPE_COMMENTS) { + parser_flags |= PyPARSE_TYPE_COMMENTS; + } + if ((flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7) { + parser_flags |= PyPARSE_ASYNC_HACKS; + } + if (flags->cf_flags & PyCF_ALLOW_INCOMPLETE_INPUT) { + parser_flags |= PyPARSE_ALLOW_INCOMPLETE_INPUT; + } + return parser_flags; +} + +Parser * +_PyPegen_Parser_New(struct tok_state *tok, int start_rule, int flags, + int feature_version, int *errcode, PyArena *arena) +{ + Parser *p = PyMem_Malloc(sizeof(Parser)); + if (p == NULL) { + return (Parser *) PyErr_NoMemory(); + } + assert(tok != NULL); + tok->type_comments = (flags & PyPARSE_TYPE_COMMENTS) > 0; + tok->async_hacks = (flags & PyPARSE_ASYNC_HACKS) > 0; + p->tok = tok; + p->keywords = NULL; + p->n_keyword_lists = -1; + p->soft_keywords = NULL; + p->tokens = PyMem_Malloc(sizeof(Token *)); + if (!p->tokens) { + PyMem_Free(p); + return (Parser *) PyErr_NoMemory(); + } + p->tokens[0] = PyMem_Calloc(1, sizeof(Token)); + if (!p->tokens) { + PyMem_Free(p->tokens); + PyMem_Free(p); + return (Parser *) PyErr_NoMemory(); + } + if (!growable_comment_array_init(&p->type_ignore_comments, 10)) { + PyMem_Free(p->tokens[0]); + PyMem_Free(p->tokens); + PyMem_Free(p); + return (Parser *) PyErr_NoMemory(); + } + + p->mark = 0; + p->fill = 0; + p->size = 1; + + p->errcode = errcode; + p->arena = arena; + p->start_rule = start_rule; + p->parsing_started = 0; + p->normalize = NULL; + p->error_indicator = 0; + + p->starting_lineno = 0; + p->starting_col_offset = 0; + p->flags = flags; + p->feature_version = feature_version; + p->known_err_token = NULL; + p->level = 0; + p->call_invalid_rules = 0; + return p; +} + +static void +reset_parser_state(Parser *p) +{ + for (int i = 0; i < p->fill; i++) { + p->tokens[i]->memo = NULL; + } + p->mark = 0; + p->call_invalid_rules = 1; + // Don't try to get extra tokens in interactive mode when trying to + // raise specialized errors in the second pass. + p->tok->interactive_underflow = IUNDERFLOW_STOP; +} + +static int +_PyPegen_check_tokenizer_errors(Parser *p) { + // Tokenize the whole input to see if there are any tokenization + // errors such as mistmatching parentheses. These will get priority + // over generic syntax errors only if the line number of the error is + // before the one that we had for the generic error. + + // We don't want to tokenize to the end for interactive input + if (p->tok->prompt != NULL) { + return 0; + } + + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + + Token *current_token = p->known_err_token != NULL ? p->known_err_token : p->tokens[p->fill - 1]; + Py_ssize_t current_err_line = current_token->lineno; + + int ret = 0; + + for (;;) { + const char *start; + const char *end; + switch (PyTokenizer_Get(p->tok, &start, &end)) { + case ERRORTOKEN: + if (p->tok->level != 0) { + int error_lineno = p->tok->parenlinenostack[p->tok->level-1]; + if (current_err_line > error_lineno) { + raise_unclosed_parentheses_error(p); + ret = -1; + goto exit; + } + } + break; + case ENDMARKER: + break; + default: + continue; + } + break; + } + + +exit: + if (PyErr_Occurred()) { + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(traceback); + } else { + PyErr_Restore(type, value, traceback); + } + return ret; +} + + +static inline int +_is_end_of_source(Parser *p) { + int err = p->tok->done; + return err == E_EOF || err == E_EOFS || err == E_EOLS; +} + +void * +_PyPegen_run_parser(Parser *p) +{ + void *res = _PyPegen_parse(p); + assert(p->level == 0); + if (res == NULL) { + if ((p->flags & PyPARSE_ALLOW_INCOMPLETE_INPUT) && _is_end_of_source(p)) { + PyErr_Clear(); + return RAISE_SYNTAX_ERROR("incomplete input"); + } + if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_SyntaxError)) { + return NULL; + } + // Make a second parser pass. In this pass we activate heavier and slower checks + // to produce better error messages and more complete diagnostics. Extra "invalid_*" + // rules will be active during parsing. + Token *last_token = p->tokens[p->fill - 1]; + reset_parser_state(p); + _PyPegen_parse(p); + if (PyErr_Occurred()) { + // Prioritize tokenizer errors to custom syntax errors raised + // on the second phase only if the errors come from the parser. + int is_tok_ok = (p->tok->done == E_DONE || p->tok->done == E_OK); + if (is_tok_ok && PyErr_ExceptionMatches(PyExc_SyntaxError)) { + _PyPegen_check_tokenizer_errors(p); + } + return NULL; + } + if (p->fill == 0) { + RAISE_SYNTAX_ERROR("error at start before reading any input"); + } + else if (last_token->type == ERRORTOKEN && p->tok->done == E_EOF) { + if (p->tok->level) { + raise_unclosed_parentheses_error(p); + } else { + RAISE_SYNTAX_ERROR("unexpected EOF while parsing"); + } + } + else { + if (p->tokens[p->fill-1]->type == INDENT) { + RAISE_INDENTATION_ERROR("unexpected indent"); + } + else if (p->tokens[p->fill-1]->type == DEDENT) { + RAISE_INDENTATION_ERROR("unexpected unindent"); + } + else { + // Use the last token we found on the first pass to avoid reporting + // incorrect locations for generic syntax errors just because we reached + // further away when trying to find specific syntax errors in the second + // pass. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(last_token, "invalid syntax"); + // _PyPegen_check_tokenizer_errors will override the existing + // generic SyntaxError we just raised if errors are found. + _PyPegen_check_tokenizer_errors(p); + } + } + return NULL; + } + + if (p->start_rule == Py_single_input && bad_single_statement(p)) { + p->tok->done = E_BADSINGLE; // This is not necessary for now, but might be in the future + return RAISE_SYNTAX_ERROR("multiple statements found while compiling a single statement"); + } + + // test_peg_generator defines _Py_TEST_PEGEN to not call PyAST_Validate() +#if defined(Py_DEBUG) && !defined(_Py_TEST_PEGEN) + if (p->start_rule == Py_single_input || + p->start_rule == Py_file_input || + p->start_rule == Py_eval_input) + { + if (!_PyAST_Validate(res)) { + return NULL; + } + } +#endif + return res; +} + +mod_ty +_PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filename_ob, + const char *enc, const char *ps1, const char *ps2, + PyCompilerFlags *flags, int *errcode, PyArena *arena) +{ + struct tok_state *tok = PyTokenizer_FromFile(fp, enc, ps1, ps2); + if (tok == NULL) { + if (PyErr_Occurred()) { + raise_tokenizer_init_error(filename_ob); + return NULL; + } + return NULL; + } + if (!tok->fp || ps1 != NULL || ps2 != NULL || + PyUnicode_CompareWithASCIIString(filename_ob, "") == 0) { + tok->fp_interactive = 1; + } + // This transfers the ownership to the tokenizer + tok->filename = filename_ob; + Py_INCREF(filename_ob); + + // From here on we need to clean up even if there's an error + mod_ty result = NULL; + + int parser_flags = compute_parser_flags(flags); + Parser *p = _PyPegen_Parser_New(tok, start_rule, parser_flags, PY_MINOR_VERSION, + errcode, arena); + if (p == NULL) { + goto error; + } + + result = _PyPegen_run_parser(p); + _PyPegen_Parser_Free(p); + +error: + PyTokenizer_Free(tok); + return result; +} + +mod_ty +_PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filename_ob, + PyCompilerFlags *flags, PyArena *arena) +{ + int exec_input = start_rule == Py_file_input; + + struct tok_state *tok; + if (flags != NULL && flags->cf_flags & PyCF_IGNORE_COOKIE) { + tok = PyTokenizer_FromUTF8(str, exec_input); + } else { + tok = PyTokenizer_FromString(str, exec_input); + } + if (tok == NULL) { + if (PyErr_Occurred()) { + raise_tokenizer_init_error(filename_ob); + } + return NULL; + } + // This transfers the ownership to the tokenizer + tok->filename = filename_ob; + Py_INCREF(filename_ob); + + // We need to clear up from here on + mod_ty result = NULL; + + int parser_flags = compute_parser_flags(flags); + int feature_version = flags && (flags->cf_flags & PyCF_ONLY_AST) ? + flags->cf_feature_version : PY_MINOR_VERSION; + Parser *p = _PyPegen_Parser_New(tok, start_rule, parser_flags, feature_version, + NULL, arena); + if (p == NULL) { + goto error; + } + + result = _PyPegen_run_parser(p); + _PyPegen_Parser_Free(p); + +error: + PyTokenizer_Free(tok); + return result; +} + +asdl_stmt_seq* +_PyPegen_interactive_exit(Parser *p) +{ + if (p->errcode) { + *(p->errcode) = E_EOF; + } + return NULL; +} + +/* Creates a single-element asdl_seq* that contains a */ +asdl_seq * +_PyPegen_singleton_seq(Parser *p, void *a) +{ + assert(a != NULL); + asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena); + if (!seq) { + return NULL; + } + asdl_seq_SET_UNTYPED(seq, 0, a); + return seq; +} + +/* Creates a copy of seq and prepends a to it */ +asdl_seq * +_PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq) +{ + assert(a != NULL); + if (!seq) { + return _PyPegen_singleton_seq(p, a); + } + + asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena); + if (!new_seq) { + return NULL; + } + + asdl_seq_SET_UNTYPED(new_seq, 0, a); + for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) { + asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1)); + } + return new_seq; +} + +/* Creates a copy of seq and appends a to it */ +asdl_seq * +_PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a) +{ + assert(a != NULL); + if (!seq) { + return _PyPegen_singleton_seq(p, a); + } + + asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena); + if (!new_seq) { + return NULL; + } + + for (Py_ssize_t i = 0, l = asdl_seq_LEN(new_seq); i + 1 < l; i++) { + asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i)); + } + asdl_seq_SET_UNTYPED(new_seq, asdl_seq_LEN(new_seq) - 1, a); + return new_seq; +} + +static Py_ssize_t +_get_flattened_seq_size(asdl_seq *seqs) +{ + Py_ssize_t size = 0; + for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) { + asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i); + size += asdl_seq_LEN(inner_seq); + } + return size; +} + +/* Flattens an asdl_seq* of asdl_seq*s */ +asdl_seq * +_PyPegen_seq_flatten(Parser *p, asdl_seq *seqs) +{ + Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs); + assert(flattened_seq_size > 0); + + asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena); + if (!flattened_seq) { + return NULL; + } + + int flattened_seq_idx = 0; + for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) { + asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i); + for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) { + asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j)); + } + } + assert(flattened_seq_idx == flattened_seq_size); + + return flattened_seq; +} + +void * +_PyPegen_seq_last_item(asdl_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + return asdl_seq_GET_UNTYPED(seq, len - 1); +} + +void * +_PyPegen_seq_first_item(asdl_seq *seq) +{ + return asdl_seq_GET_UNTYPED(seq, 0); +} + + +/* Creates a new name of the form . */ +expr_ty +_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name) +{ + assert(first_name != NULL && second_name != NULL); + PyObject *first_identifier = first_name->v.Name.id; + PyObject *second_identifier = second_name->v.Name.id; + + if (PyUnicode_READY(first_identifier) == -1) { + return NULL; + } + if (PyUnicode_READY(second_identifier) == -1) { + return NULL; + } + const char *first_str = PyUnicode_AsUTF8(first_identifier); + if (!first_str) { + return NULL; + } + const char *second_str = PyUnicode_AsUTF8(second_identifier); + if (!second_str) { + return NULL; + } + Py_ssize_t len = strlen(first_str) + strlen(second_str) + 1; // +1 for the dot + + PyObject *str = PyBytes_FromStringAndSize(NULL, len); + if (!str) { + return NULL; + } + + char *s = PyBytes_AS_STRING(str); + if (!s) { + return NULL; + } + + strcpy(s, first_str); + s += strlen(first_str); + *s++ = '.'; + strcpy(s, second_str); + s += strlen(second_str); + *s = '\0'; + + PyObject *uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), PyBytes_GET_SIZE(str), NULL); + Py_DECREF(str); + if (!uni) { + return NULL; + } + PyUnicode_InternInPlace(&uni); + if (_PyArena_AddPyObject(p->arena, uni) < 0) { + Py_DECREF(uni); + return NULL; + } + + return _PyAST_Name(uni, Load, EXTRA_EXPR(first_name, second_name)); +} + +/* Counts the total number of dots in seq's tokens */ +int +_PyPegen_seq_count_dots(asdl_seq *seq) +{ + int number_of_dots = 0; + for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) { + Token *current_expr = asdl_seq_GET_UNTYPED(seq, i); + switch (current_expr->type) { + case ELLIPSIS: + number_of_dots += 3; + break; + case DOT: + number_of_dots += 1; + break; + default: + Py_UNREACHABLE(); + } + } + + return number_of_dots; +} + +/* Creates an alias with '*' as the identifier name */ +alias_ty +_PyPegen_alias_for_star(Parser *p, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) { + PyObject *str = PyUnicode_InternFromString("*"); + if (!str) { + return NULL; + } + if (_PyArena_AddPyObject(p->arena, str) < 0) { + Py_DECREF(str); + return NULL; + } + return _PyAST_alias(str, NULL, lineno, col_offset, end_lineno, end_col_offset, arena); +} + +/* Creates a new asdl_seq* with the identifiers of all the names in seq */ +asdl_identifier_seq * +_PyPegen_map_names_to_ids(Parser *p, asdl_expr_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + assert(len > 0); + + asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + expr_ty e = asdl_seq_GET(seq, i); + asdl_seq_SET(new_seq, i, e->v.Name.id); + } + return new_seq; +} + +/* Constructs a CmpopExprPair */ +CmpopExprPair * +_PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr) +{ + assert(expr != NULL); + CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair)); + if (!a) { + return NULL; + } + a->cmpop = cmpop; + a->expr = expr; + return a; +} + +asdl_int_seq * +_PyPegen_get_cmpops(Parser *p, asdl_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + assert(len > 0); + + asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i); + asdl_seq_SET(new_seq, i, pair->cmpop); + } + return new_seq; +} + +asdl_expr_seq * +_PyPegen_get_exprs(Parser *p, asdl_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + assert(len > 0); + + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i); + asdl_seq_SET(new_seq, i, pair->expr); + } + return new_seq; +} + +/* Creates an asdl_seq* where all the elements have been changed to have ctx as context */ +static asdl_expr_seq * +_set_seq_context(Parser *p, asdl_expr_seq *seq, expr_context_ty ctx) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + if (len == 0) { + return NULL; + } + + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + expr_ty e = asdl_seq_GET(seq, i); + asdl_seq_SET(new_seq, i, _PyPegen_set_expr_context(p, e, ctx)); + } + return new_seq; +} + +static expr_ty +_set_name_context(Parser *p, expr_ty e, expr_context_ty ctx) +{ + return _PyAST_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e)); +} + +static expr_ty +_set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx) +{ + return _PyAST_Tuple( + _set_seq_context(p, e->v.Tuple.elts, ctx), + ctx, + EXTRA_EXPR(e, e)); +} + +static expr_ty +_set_list_context(Parser *p, expr_ty e, expr_context_ty ctx) +{ + return _PyAST_List( + _set_seq_context(p, e->v.List.elts, ctx), + ctx, + EXTRA_EXPR(e, e)); +} + +static expr_ty +_set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx) +{ + return _PyAST_Subscript(e->v.Subscript.value, e->v.Subscript.slice, + ctx, EXTRA_EXPR(e, e)); +} + +static expr_ty +_set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx) +{ + return _PyAST_Attribute(e->v.Attribute.value, e->v.Attribute.attr, + ctx, EXTRA_EXPR(e, e)); +} + +static expr_ty +_set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx) +{ + return _PyAST_Starred(_PyPegen_set_expr_context(p, e->v.Starred.value, ctx), + ctx, EXTRA_EXPR(e, e)); +} + +/* Creates an `expr_ty` equivalent to `expr` but with `ctx` as context */ +expr_ty +_PyPegen_set_expr_context(Parser *p, expr_ty expr, expr_context_ty ctx) +{ + assert(expr != NULL); + + expr_ty new = NULL; + switch (expr->kind) { + case Name_kind: + new = _set_name_context(p, expr, ctx); + break; + case Tuple_kind: + new = _set_tuple_context(p, expr, ctx); + break; + case List_kind: + new = _set_list_context(p, expr, ctx); + break; + case Subscript_kind: + new = _set_subscript_context(p, expr, ctx); + break; + case Attribute_kind: + new = _set_attribute_context(p, expr, ctx); + break; + case Starred_kind: + new = _set_starred_context(p, expr, ctx); + break; + default: + new = expr; + } + return new; +} + +/* Constructs a KeyValuePair that is used when parsing a dict's key value pairs */ +KeyValuePair * +_PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value) +{ + KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair)); + if (!a) { + return NULL; + } + a->key = key; + a->value = value; + return a; +} + +/* Extracts all keys from an asdl_seq* of KeyValuePair*'s */ +asdl_expr_seq * +_PyPegen_get_keys(Parser *p, asdl_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i); + asdl_seq_SET(new_seq, i, pair->key); + } + return new_seq; +} + +/* Extracts all values from an asdl_seq* of KeyValuePair*'s */ +asdl_expr_seq * +_PyPegen_get_values(Parser *p, asdl_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i); + asdl_seq_SET(new_seq, i, pair->value); + } + return new_seq; +} + +/* Constructs a KeyPatternPair that is used when parsing mapping & class patterns */ +KeyPatternPair * +_PyPegen_key_pattern_pair(Parser *p, expr_ty key, pattern_ty pattern) +{ + KeyPatternPair *a = _PyArena_Malloc(p->arena, sizeof(KeyPatternPair)); + if (!a) { + return NULL; + } + a->key = key; + a->pattern = pattern; + return a; +} + +/* Extracts all keys from an asdl_seq* of KeyPatternPair*'s */ +asdl_expr_seq * +_PyPegen_get_pattern_keys(Parser *p, asdl_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i); + asdl_seq_SET(new_seq, i, pair->key); + } + return new_seq; +} + +/* Extracts all patterns from an asdl_seq* of KeyPatternPair*'s */ +asdl_pattern_seq * +_PyPegen_get_patterns(Parser *p, asdl_seq *seq) +{ + Py_ssize_t len = asdl_seq_LEN(seq); + asdl_pattern_seq *new_seq = _Py_asdl_pattern_seq_new(len, p->arena); + if (!new_seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i); + asdl_seq_SET(new_seq, i, pair->pattern); + } + return new_seq; +} + +/* Constructs a NameDefaultPair */ +NameDefaultPair * +_PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc) +{ + NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair)); + if (!a) { + return NULL; + } + a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc); + a->value = value; + return a; +} + +/* Constructs a SlashWithDefault */ +SlashWithDefault * +_PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *names_with_defaults) +{ + SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault)); + if (!a) { + return NULL; + } + a->plain_names = plain_names; + a->names_with_defaults = names_with_defaults; + return a; +} + +/* Constructs a StarEtc */ +StarEtc * +_PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg) +{ + StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc)); + if (!a) { + return NULL; + } + a->vararg = vararg; + a->kwonlyargs = kwonlyargs; + a->kwarg = kwarg; + return a; +} + +asdl_seq * +_PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b) +{ + Py_ssize_t first_len = asdl_seq_LEN(a); + Py_ssize_t second_len = asdl_seq_LEN(b); + asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena); + if (!new_seq) { + return NULL; + } + + int k = 0; + for (Py_ssize_t i = 0; i < first_len; i++) { + asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i)); + } + for (Py_ssize_t i = 0; i < second_len; i++) { + asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i)); + } + + return new_seq; +} + +static asdl_arg_seq* +_get_names(Parser *p, asdl_seq *names_with_defaults) +{ + Py_ssize_t len = asdl_seq_LEN(names_with_defaults); + asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena); + if (!seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i); + asdl_seq_SET(seq, i, pair->arg); + } + return seq; +} + +static asdl_expr_seq * +_get_defaults(Parser *p, asdl_seq *names_with_defaults) +{ + Py_ssize_t len = asdl_seq_LEN(names_with_defaults); + asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena); + if (!seq) { + return NULL; + } + for (Py_ssize_t i = 0; i < len; i++) { + NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i); + asdl_seq_SET(seq, i, pair->value); + } + return seq; +} + +static int +_make_posonlyargs(Parser *p, + asdl_arg_seq *slash_without_default, + SlashWithDefault *slash_with_default, + asdl_arg_seq **posonlyargs) { + if (slash_without_default != NULL) { + *posonlyargs = slash_without_default; + } + else if (slash_with_default != NULL) { + asdl_arg_seq *slash_with_default_names = + _get_names(p, slash_with_default->names_with_defaults); + if (!slash_with_default_names) { + return -1; + } + *posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences( + p, + (asdl_seq*)slash_with_default->plain_names, + (asdl_seq*)slash_with_default_names); + } + else { + *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena); + } + return *posonlyargs == NULL ? -1 : 0; +} + +static int +_make_posargs(Parser *p, + asdl_arg_seq *plain_names, + asdl_seq *names_with_default, + asdl_arg_seq **posargs) { + if (plain_names != NULL && names_with_default != NULL) { + asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default); + if (!names_with_default_names) { + return -1; + } + *posargs = (asdl_arg_seq*)_PyPegen_join_sequences( + p,(asdl_seq*)plain_names, (asdl_seq*)names_with_default_names); + } + else if (plain_names == NULL && names_with_default != NULL) { + *posargs = _get_names(p, names_with_default); + } + else if (plain_names != NULL && names_with_default == NULL) { + *posargs = plain_names; + } + else { + *posargs = _Py_asdl_arg_seq_new(0, p->arena); + } + return *posargs == NULL ? -1 : 0; +} + +static int +_make_posdefaults(Parser *p, + SlashWithDefault *slash_with_default, + asdl_seq *names_with_default, + asdl_expr_seq **posdefaults) { + if (slash_with_default != NULL && names_with_default != NULL) { + asdl_expr_seq *slash_with_default_values = + _get_defaults(p, slash_with_default->names_with_defaults); + if (!slash_with_default_values) { + return -1; + } + asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default); + if (!names_with_default_values) { + return -1; + } + *posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences( + p, + (asdl_seq*)slash_with_default_values, + (asdl_seq*)names_with_default_values); + } + else if (slash_with_default == NULL && names_with_default != NULL) { + *posdefaults = _get_defaults(p, names_with_default); + } + else if (slash_with_default != NULL && names_with_default == NULL) { + *posdefaults = _get_defaults(p, slash_with_default->names_with_defaults); + } + else { + *posdefaults = _Py_asdl_expr_seq_new(0, p->arena); + } + return *posdefaults == NULL ? -1 : 0; +} + +static int +_make_kwargs(Parser *p, StarEtc *star_etc, + asdl_arg_seq **kwonlyargs, + asdl_expr_seq **kwdefaults) { + if (star_etc != NULL && star_etc->kwonlyargs != NULL) { + *kwonlyargs = _get_names(p, star_etc->kwonlyargs); + } + else { + *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena); + } + + if (*kwonlyargs == NULL) { + return -1; + } + + if (star_etc != NULL && star_etc->kwonlyargs != NULL) { + *kwdefaults = _get_defaults(p, star_etc->kwonlyargs); + } + else { + *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena); + } + + if (*kwdefaults == NULL) { + return -1; + } + + return 0; +} + +/* Constructs an arguments_ty object out of all the parsed constructs in the parameters rule */ +arguments_ty +_PyPegen_make_arguments(Parser *p, asdl_arg_seq *slash_without_default, + SlashWithDefault *slash_with_default, asdl_arg_seq *plain_names, + asdl_seq *names_with_default, StarEtc *star_etc) +{ + asdl_arg_seq *posonlyargs; + if (_make_posonlyargs(p, slash_without_default, slash_with_default, &posonlyargs) == -1) { + return NULL; + } + + asdl_arg_seq *posargs; + if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) { + return NULL; + } + + asdl_expr_seq *posdefaults; + if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) { + return NULL; + } + + arg_ty vararg = NULL; + if (star_etc != NULL && star_etc->vararg != NULL) { + vararg = star_etc->vararg; + } + + asdl_arg_seq *kwonlyargs; + asdl_expr_seq *kwdefaults; + if (_make_kwargs(p, star_etc, &kwonlyargs, &kwdefaults) == -1) { + return NULL; + } + + arg_ty kwarg = NULL; + if (star_etc != NULL && star_etc->kwarg != NULL) { + kwarg = star_etc->kwarg; + } + + return _PyAST_arguments(posonlyargs, posargs, vararg, kwonlyargs, + kwdefaults, kwarg, posdefaults, p->arena); +} + + +/* Constructs an empty arguments_ty object, that gets used when a function accepts no + * arguments. */ +arguments_ty +_PyPegen_empty_arguments(Parser *p) +{ + asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena); + if (!posonlyargs) { + return NULL; + } + asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena); + if (!posargs) { + return NULL; + } + asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena); + if (!posdefaults) { + return NULL; + } + asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena); + if (!kwonlyargs) { + return NULL; + } + asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena); + if (!kwdefaults) { + return NULL; + } + + return _PyAST_arguments(posonlyargs, posargs, NULL, kwonlyargs, + kwdefaults, NULL, posdefaults, p->arena); +} + +/* Encapsulates the value of an operator_ty into an AugOperator struct */ +AugOperator * +_PyPegen_augoperator(Parser *p, operator_ty kind) +{ + AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator)); + if (!a) { + return NULL; + } + a->kind = kind; + return a; +} + +/* Construct a FunctionDef equivalent to function_def, but with decorators */ +stmt_ty +_PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty function_def) +{ + 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); + } + + return _PyAST_FunctionDef( + 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); +} + +/* Construct a ClassDef equivalent to class_def, but with decorators */ +stmt_ty +_PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty class_def) +{ + 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->lineno, class_def->col_offset, class_def->end_lineno, + class_def->end_col_offset, p->arena); +} + +/* Construct a KeywordOrStarred */ +KeywordOrStarred * +_PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword) +{ + KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred)); + if (!a) { + return NULL; + } + a->element = element; + a->is_keyword = is_keyword; + return a; +} + +/* Get the number of starred expressions in an asdl_seq* of KeywordOrStarred*s */ +static int +_seq_number_of_starred_exprs(asdl_seq *seq) +{ + int n = 0; + for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) { + KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i); + if (!k->is_keyword) { + n++; + } + } + return n; +} + +/* Extract the starred expressions of an asdl_seq* of KeywordOrStarred*s */ +asdl_expr_seq * +_PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs) +{ + int new_len = _seq_number_of_starred_exprs(kwargs); + if (new_len == 0) { + return NULL; + } + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena); + if (!new_seq) { + return NULL; + } + + int idx = 0; + for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) { + KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i); + if (!k->is_keyword) { + asdl_seq_SET(new_seq, idx++, k->element); + } + } + return new_seq; +} + +/* Return a new asdl_seq* with only the keywords in kwargs */ +asdl_keyword_seq* +_PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs) +{ + Py_ssize_t len = asdl_seq_LEN(kwargs); + Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs); + if (new_len == 0) { + return NULL; + } + asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena); + if (!new_seq) { + return NULL; + } + + int idx = 0; + for (Py_ssize_t i = 0; i < len; i++) { + KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i); + if (k->is_keyword) { + asdl_seq_SET(new_seq, idx++, k->element); + } + } + 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()) { + raise_decode_error(p); + } + return NULL; +} + +expr_ty +_PyPegen_ensure_imaginary(Parser *p, expr_ty exp) +{ + if (exp->kind != Constant_kind || !PyComplex_CheckExact(exp->v.Constant.value)) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "imaginary number required in complex literal"); + return NULL; + } + return exp; +} + +expr_ty +_PyPegen_ensure_real(Parser *p, expr_ty exp) +{ + if (exp->kind != Constant_kind || PyComplex_CheckExact(exp->v.Constant.value)) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "real number required in complex literal"); + return NULL; + } + return exp; +} + +mod_ty +_PyPegen_make_module(Parser *p, asdl_stmt_seq *a) { + asdl_type_ignore_seq *type_ignores = NULL; + Py_ssize_t num = p->type_ignore_comments.num_items; + if (num > 0) { + // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena + type_ignores = _Py_asdl_type_ignore_seq_new(num, p->arena); + if (type_ignores == NULL) { + return NULL; + } + for (int i = 0; i < num; i++) { + PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment); + if (tag == NULL) { + return NULL; + } + type_ignore_ty ti = _PyAST_TypeIgnore(p->type_ignore_comments.items[i].lineno, + tag, p->arena); + if (ti == NULL) { + return NULL; + } + asdl_seq_SET(type_ignores, i, ti); + } + } + return _PyAST_Module(a, type_ignores, p->arena); +} + +// Error reporting helpers + +expr_ty +_PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type) +{ + if (e == NULL) { + return NULL; + } + +#define VISIT_CONTAINER(CONTAINER, TYPE) do { \ + Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\ + for (Py_ssize_t i = 0; i < len; i++) {\ + expr_ty other = asdl_seq_GET((CONTAINER)->v.TYPE.elts, i);\ + expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\ + if (child != NULL) {\ + return child;\ + }\ + }\ + } while (0) + + // We only need to visit List and Tuple nodes recursively as those + // are the only ones that can contain valid names in targets when + // they are parsed as expressions. Any other kind of expression + // that is a container (like Sets or Dicts) is directly invalid and + // we don't need to visit it recursively. + + switch (e->kind) { + case List_kind: + VISIT_CONTAINER(e, List); + return NULL; + case Tuple_kind: + VISIT_CONTAINER(e, Tuple); + return NULL; + case Starred_kind: + if (targets_type == DEL_TARGETS) { + return e; + } + return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type); + case Compare_kind: + // This is needed, because the `a in b` in `for a in b` gets parsed + // as a comparison, and so we need to search the left side of the comparison + // for invalid targets. + if (targets_type == FOR_TARGETS) { + cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0); + if (cmpop == In) { + return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type); + } + return NULL; + } + return e; + case Name_kind: + case Subscript_kind: + case Attribute_kind: + return NULL; + default: + return e; + } +} + +void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) { + int kwarg_unpacking = 0; + for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) { + keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i); + if (!keyword->arg) { + kwarg_unpacking = 1; + } + } + + const char *msg = NULL; + if (kwarg_unpacking) { + msg = "positional argument follows keyword argument unpacking"; + } else { + msg = "positional argument follows keyword argument"; + } + + return RAISE_SYNTAX_ERROR(msg); +} + + +static inline expr_ty +_PyPegen_get_last_comprehension_item(comprehension_ty comprehension) { + if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) { + return comprehension->iter; + } + return PyPegen_last_item(comprehension->ifs, expr_ty); +} + +void * +_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions) +{ + /* The rule that calls this function is 'args for_if_clauses'. + For the input f(L, x for x in y), L and x are in args and + the for is parsed as a for_if_clause. We have to check if + len <= 1, so that input like dict((a, b) for a, b in x) + gets successfully parsed and then we pass the last + argument (x in the above example) as the location of the + error */ + Py_ssize_t len = asdl_seq_LEN(args->v.Call.args); + if (len <= 1) { + return NULL; + } + + comprehension_ty last_comprehension = PyPegen_last_item(comprehensions, comprehension_ty); + + return RAISE_SYNTAX_ERROR_KNOWN_RANGE( + (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1), + _PyPegen_get_last_comprehension_item(last_comprehension), + "Generator expression must be parenthesized" + ); +} + + +expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_expr_seq *a, asdl_seq *b, + int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) { + Py_ssize_t args_len = asdl_seq_LEN(a); + Py_ssize_t total_len = args_len; + + if (b == NULL) { + return _PyAST_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset, + end_lineno, end_col_offset, arena); + + } + + asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b); + asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b); + + if (starreds) { + total_len += asdl_seq_LEN(starreds); + } + + asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena); + + Py_ssize_t i = 0; + for (i = 0; i < args_len; i++) { + asdl_seq_SET(args, i, asdl_seq_GET(a, i)); + } + for (; i < total_len; i++) { + asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len)); + } + + return _PyAST_Call(_PyPegen_dummy_name(p), args, keywords, lineno, + col_offset, end_lineno, end_col_offset, arena); +} diff --git a/contrib/tools/python3/src/Parser/pegen.h b/contrib/tools/python3/src/Parser/pegen.h new file mode 100644 index 00000000000..0e5a057c1f1 --- /dev/null +++ b/contrib/tools/python3/src/Parser/pegen.h @@ -0,0 +1,336 @@ +#ifndef PEGEN_H +#define PEGEN_H + +#define PY_SSIZE_T_CLEAN +#include +#include +#include + +#if 0 +#define PyPARSE_YIELD_IS_KEYWORD 0x0001 +#endif + +#define PyPARSE_DONT_IMPLY_DEDENT 0x0002 + +#if 0 +#define PyPARSE_WITH_IS_KEYWORD 0x0003 +#define PyPARSE_PRINT_IS_FUNCTION 0x0004 +#define PyPARSE_UNICODE_LITERALS 0x0008 +#endif + +#define PyPARSE_IGNORE_COOKIE 0x0010 +#define PyPARSE_BARRY_AS_BDFL 0x0020 +#define PyPARSE_TYPE_COMMENTS 0x0040 +#define PyPARSE_ASYNC_HACKS 0x0080 +#define PyPARSE_ALLOW_INCOMPLETE_INPUT 0x0100 + +typedef struct _memo { + int type; + void *node; + int mark; + struct _memo *next; +} Memo; + +typedef struct { + int type; + PyObject *bytes; + int level; + int lineno, col_offset, end_lineno, end_col_offset; + Memo *memo; +} Token; + +typedef struct { + char *str; + int type; +} KeywordToken; + + +typedef struct { + struct { + int lineno; + char *comment; // The " " in "# type: ignore " + } *items; + size_t size; + size_t num_items; +} growable_comment_array; + +typedef struct { + struct tok_state *tok; + Token **tokens; + int mark; + int fill, size; + PyArena *arena; + KeywordToken **keywords; + char **soft_keywords; + int n_keyword_lists; + int start_rule; + int *errcode; + int parsing_started; + PyObject* normalize; + int starting_lineno; + int starting_col_offset; + int error_indicator; + int flags; + int feature_version; + growable_comment_array type_ignore_comments; + Token *known_err_token; + int level; + int call_invalid_rules; +} Parser; + +typedef struct { + cmpop_ty cmpop; + expr_ty expr; +} CmpopExprPair; + +typedef struct { + expr_ty key; + expr_ty value; +} KeyValuePair; + +typedef struct { + expr_ty key; + pattern_ty pattern; +} KeyPatternPair; + +typedef struct { + arg_ty arg; + expr_ty value; +} NameDefaultPair; + +typedef struct { + asdl_arg_seq *plain_names; + asdl_seq *names_with_defaults; // asdl_seq* of NameDefaultsPair's +} SlashWithDefault; + +typedef struct { + arg_ty vararg; + asdl_seq *kwonlyargs; // asdl_seq* of NameDefaultsPair's + arg_ty kwarg; +} StarEtc; + +typedef struct { operator_ty kind; } AugOperator; +typedef struct { + void *element; + int is_keyword; +} KeywordOrStarred; + +#if defined(Py_DEBUG) +void _PyPegen_clear_memo_statistics(void); +PyObject *_PyPegen_get_memo_statistics(void); +#endif + +int _PyPegen_insert_memo(Parser *p, int mark, int type, void *node); +int _PyPegen_update_memo(Parser *p, int mark, int type, void *node); +int _PyPegen_is_memoized(Parser *p, int type, void *pres); + + +int _PyPegen_lookahead_with_name(int, expr_ty (func)(Parser *), Parser *); +int _PyPegen_lookahead_with_int(int, Token *(func)(Parser *, int), Parser *, int); +int _PyPegen_lookahead_with_string(int , expr_ty (func)(Parser *, const char*), Parser *, const char*); +int _PyPegen_lookahead(int, void *(func)(Parser *), Parser *); + +Token *_PyPegen_expect_token(Parser *p, int type); +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); +Token *_PyPegen_get_last_nonnwhitespace_token(Parser *); +int _PyPegen_fill_token(Parser *p); +expr_ty _PyPegen_name_token(Parser *p); +expr_ty _PyPegen_number_token(Parser *p); +void *_PyPegen_string_token(Parser *p); +const char *_PyPegen_get_expr_name(expr_ty); +void *_PyPegen_raise_error(Parser *p, PyObject *errtype, 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_dummy_name(Parser *p, ...); + +void * _PyPegen_seq_last_item(asdl_seq *seq); +#define PyPegen_last_item(seq, type) ((type)_PyPegen_seq_last_item((asdl_seq*)seq)) + +void * _PyPegen_seq_first_item(asdl_seq *seq); +#define PyPegen_first_item(seq, type) ((type)_PyPegen_seq_first_item((asdl_seq*)seq)) + +#define CURRENT_POS (-5) + +Py_LOCAL_INLINE(void *) +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; + va_start(va, errmsg); + Py_ssize_t _col_offset = (col_offset == CURRENT_POS ? CURRENT_POS : col_offset + 1); + Py_ssize_t _end_col_offset = (end_col_offset == CURRENT_POS ? CURRENT_POS : end_col_offset + 1); + _PyPegen_raise_error_known_location(p, errtype, lineno, _col_offset, end_lineno, _end_col_offset, errmsg, va); + va_end(va); + return NULL; +} + +#define UNUSED(expr) do { (void)(expr); } while (0) +#define EXTRA_EXPR(head, tail) head->lineno, (head)->col_offset, (tail)->end_lineno, (tail)->end_col_offset, p->arena +#define EXTRA _start_lineno, _start_col_offset, _end_lineno, _end_col_offset, p->arena +#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_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, ...) \ + RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, (a)->lineno, (a)->col_offset, (a)->end_lineno, (a)->end_col_offset, msg, ##__VA_ARGS__) +#define RAISE_SYNTAX_ERROR_STARTING_FROM(a, msg, ...) \ + RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, (a)->lineno, (a)->col_offset, CURRENT_POS, CURRENT_POS, msg, ##__VA_ARGS__) + +Py_LOCAL_INLINE(void *) +CHECK_CALL(Parser *p, void *result) +{ + if (result == NULL) { + assert(PyErr_Occurred()); + p->error_indicator = 1; + } + return result; +} + +/* This is needed for helper functions that are allowed to + return NULL without an error. Example: _PyPegen_seq_extract_starred_exprs */ +Py_LOCAL_INLINE(void *) +CHECK_CALL_NULL_ALLOWED(Parser *p, void *result) +{ + if (result == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + } + return result; +} + +#define CHECK(type, result) ((type) CHECK_CALL(p, result)) +#define CHECK_NULL_ALLOWED(type, result) ((type) CHECK_CALL_NULL_ALLOWED(p, result)) + +PyObject *_PyPegen_new_type_comment(Parser *, const char *); + +Py_LOCAL_INLINE(PyObject *) +NEW_TYPE_COMMENT(Parser *p, Token *tc) +{ + if (tc == NULL) { + return NULL; + } + const char *bytes = PyBytes_AsString(tc->bytes); + if (bytes == NULL) { + goto error; + } + PyObject *tco = _PyPegen_new_type_comment(p, bytes); + if (tco == NULL) { + goto error; + } + return tco; + error: + p->error_indicator = 1; // Inline CHECK_CALL + return NULL; +} + +Py_LOCAL_INLINE(void *) +INVALID_VERSION_CHECK(Parser *p, int version, char *msg, void *node) +{ + if (node == NULL) { + p->error_indicator = 1; // Inline CHECK_CALL + return NULL; + } + if (p->feature_version < version) { + p->error_indicator = 1; + return RAISE_SYNTAX_ERROR("%s only supported in Python 3.%i and greater", + msg, version); + } + return node; +} + +#define CHECK_VERSION(type, version, msg, node) ((type) INVALID_VERSION_CHECK(p, version, msg, node)) + +arg_ty _PyPegen_add_type_comment_to_arg(Parser *, arg_ty, Token *); +PyObject *_PyPegen_new_identifier(Parser *, const char *); +Parser *_PyPegen_Parser_New(struct tok_state *, int, int, int, int *, PyArena *); +void _PyPegen_Parser_Free(Parser *); +mod_ty _PyPegen_run_parser_from_file_pointer(FILE *, int, PyObject *, const char *, + const char *, const char *, PyCompilerFlags *, int *, PyArena *); +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 *); +asdl_seq *_PyPegen_singleton_seq(Parser *, void *); +asdl_seq *_PyPegen_seq_insert_in_front(Parser *, void *, asdl_seq *); +asdl_seq *_PyPegen_seq_append_to_end(Parser *, asdl_seq *, void *); +asdl_seq *_PyPegen_seq_flatten(Parser *, asdl_seq *); +expr_ty _PyPegen_join_names_with_dot(Parser *, expr_ty, expr_ty); +int _PyPegen_seq_count_dots(asdl_seq *); +alias_ty _PyPegen_alias_for_star(Parser *, int, int, int, int, PyArena *); +asdl_identifier_seq *_PyPegen_map_names_to_ids(Parser *, asdl_expr_seq *); +CmpopExprPair *_PyPegen_cmpop_expr_pair(Parser *, cmpop_ty, expr_ty); +asdl_int_seq *_PyPegen_get_cmpops(Parser *p, asdl_seq *); +asdl_expr_seq *_PyPegen_get_exprs(Parser *, asdl_seq *); +expr_ty _PyPegen_set_expr_context(Parser *, expr_ty, expr_context_ty); +KeyValuePair *_PyPegen_key_value_pair(Parser *, expr_ty, expr_ty); +asdl_expr_seq *_PyPegen_get_keys(Parser *, asdl_seq *); +asdl_expr_seq *_PyPegen_get_values(Parser *, asdl_seq *); +KeyPatternPair *_PyPegen_key_pattern_pair(Parser *, expr_ty, pattern_ty); +asdl_expr_seq *_PyPegen_get_pattern_keys(Parser *, asdl_seq *); +asdl_pattern_seq *_PyPegen_get_patterns(Parser *, asdl_seq *); +NameDefaultPair *_PyPegen_name_default_pair(Parser *, arg_ty, expr_ty, Token *); +SlashWithDefault *_PyPegen_slash_with_default(Parser *, asdl_arg_seq *, asdl_seq *); +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 *); +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); +KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int); +asdl_expr_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *); +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_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); +mod_ty _PyPegen_make_module(Parser *, asdl_stmt_seq *); + +// Error reporting helpers +typedef enum { + STAR_TARGETS, + DEL_TARGETS, + FOR_TARGETS +} TARGETS_TYPE; +expr_ty _PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type); +#define RAISE_SYNTAX_ERROR_INVALID_TARGET(type, e) _RAISE_SYNTAX_ERROR_INVALID_TARGET(p, type, e) + +Py_LOCAL_INLINE(void *) +_RAISE_SYNTAX_ERROR_INVALID_TARGET(Parser *p, TARGETS_TYPE type, void *e) +{ + expr_ty invalid_target = CHECK_NULL_ALLOWED(expr_ty, _PyPegen_get_invalid_target(e, type)); + if (invalid_target != NULL) { + const char *msg; + if (type == STAR_TARGETS || type == FOR_TARGETS) { + msg = "cannot assign to %s"; + } + else { + msg = "cannot delete %s"; + } + return RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + invalid_target, + msg, + _PyPegen_get_expr_name(invalid_target) + ); + return RAISE_SYNTAX_ERROR_KNOWN_LOCATION(invalid_target, "invalid syntax"); + } + return NULL; +} + +void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); +void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions); + + +// Generated function in parse.c - function definition in python.gram +void *_PyPegen_parse(Parser *); + +#endif diff --git a/contrib/tools/python3/src/Parser/pegen/parse.c b/contrib/tools/python3/src/Parser/pegen/parse.c deleted file mode 100644 index 105b0faa200..00000000000 --- a/contrib/tools/python3/src/Parser/pegen/parse.c +++ /dev/null @@ -1,25594 +0,0 @@ -// @generated by pegen.py from python.gram -#include "pegen.h" - -#if defined(Py_DEBUG) && defined(Py_BUILD_CORE) -extern int Py_DebugFlag; -#define D(x) if (Py_DebugFlag) x; -#else -#define D(x) -#endif - -# define MAXSTACK 6000 -static const int n_keyword_lists = 15; -static KeywordToken *reserved_keywords[] = { - (KeywordToken[]) {{NULL, -1}}, - (KeywordToken[]) {{NULL, -1}}, - (KeywordToken[]) { - {"if", 510}, - {"in", 518}, - {"as", 520}, - {"is", 527}, - {"or", 532}, - {NULL, -1}, - }, - (KeywordToken[]) { - {"del", 503}, - {"try", 511}, - {"for", 517}, - {"def", 523}, - {"not", 526}, - {"and", 533}, - {NULL, -1}, - }, - (KeywordToken[]) { - {"pass", 502}, - {"from", 514}, - {"elif", 515}, - {"else", 516}, - {"with", 519}, - {"True", 528}, - {"None", 530}, - {NULL, -1}, - }, - (KeywordToken[]) { - {"raise", 501}, - {"yield", 504}, - {"break", 506}, - {"while", 512}, - {"class", 524}, - {"False", 529}, - {NULL, -1}, - }, - (KeywordToken[]) { - {"return", 500}, - {"assert", 505}, - {"global", 508}, - {"import", 513}, - {"except", 521}, - {"lambda", 525}, - {NULL, -1}, - }, - (KeywordToken[]) { - {"finally", 522}, - {NULL, -1}, - }, - (KeywordToken[]) { - {"continue", 507}, - {"nonlocal", 509}, - {NULL, -1}, - }, - (KeywordToken[]) {{NULL, -1}}, - (KeywordToken[]) {{NULL, -1}}, - (KeywordToken[]) {{NULL, -1}}, - (KeywordToken[]) {{NULL, -1}}, - (KeywordToken[]) {{NULL, -1}}, - (KeywordToken[]) { - {"__peg_parser__", 531}, - {NULL, -1}, - }, -}; -#define file_type 1000 -#define interactive_type 1001 -#define eval_type 1002 -#define func_type_type 1003 -#define fstring_type 1004 -#define type_expressions_type 1005 -#define statements_type 1006 -#define statement_type 1007 -#define statement_newline_type 1008 -#define simple_stmt_type 1009 -#define small_stmt_type 1010 -#define compound_stmt_type 1011 -#define assignment_type 1012 -#define augassign_type 1013 -#define global_stmt_type 1014 -#define nonlocal_stmt_type 1015 -#define yield_stmt_type 1016 -#define assert_stmt_type 1017 -#define del_stmt_type 1018 -#define import_stmt_type 1019 -#define import_name_type 1020 -#define import_from_type 1021 -#define import_from_targets_type 1022 -#define import_from_as_names_type 1023 -#define import_from_as_name_type 1024 -#define dotted_as_names_type 1025 -#define dotted_as_name_type 1026 -#define dotted_name_type 1027 // Left-recursive -#define if_stmt_type 1028 -#define elif_stmt_type 1029 -#define else_block_type 1030 -#define while_stmt_type 1031 -#define for_stmt_type 1032 -#define with_stmt_type 1033 -#define with_item_type 1034 -#define try_stmt_type 1035 -#define except_block_type 1036 -#define finally_block_type 1037 -#define return_stmt_type 1038 -#define raise_stmt_type 1039 -#define function_def_type 1040 -#define function_def_raw_type 1041 -#define func_type_comment_type 1042 -#define params_type 1043 -#define parameters_type 1044 -#define slash_no_default_type 1045 -#define slash_with_default_type 1046 -#define star_etc_type 1047 -#define kwds_type 1048 -#define param_no_default_type 1049 -#define param_with_default_type 1050 -#define param_maybe_default_type 1051 -#define param_type 1052 -#define annotation_type 1053 -#define default_type 1054 -#define decorators_type 1055 -#define class_def_type 1056 -#define class_def_raw_type 1057 -#define block_type 1058 -#define star_expressions_type 1059 -#define star_expression_type 1060 -#define star_named_expressions_type 1061 -#define star_named_expression_type 1062 -#define named_expression_type 1063 -#define annotated_rhs_type 1064 -#define expressions_type 1065 -#define expression_type 1066 -#define lambdef_type 1067 -#define lambda_params_type 1068 -#define lambda_parameters_type 1069 -#define lambda_slash_no_default_type 1070 -#define lambda_slash_with_default_type 1071 -#define lambda_star_etc_type 1072 -#define lambda_kwds_type 1073 -#define lambda_param_no_default_type 1074 -#define lambda_param_with_default_type 1075 -#define lambda_param_maybe_default_type 1076 -#define lambda_param_type 1077 -#define disjunction_type 1078 -#define conjunction_type 1079 -#define inversion_type 1080 -#define comparison_type 1081 -#define compare_op_bitwise_or_pair_type 1082 -#define eq_bitwise_or_type 1083 -#define noteq_bitwise_or_type 1084 -#define lte_bitwise_or_type 1085 -#define lt_bitwise_or_type 1086 -#define gte_bitwise_or_type 1087 -#define gt_bitwise_or_type 1088 -#define notin_bitwise_or_type 1089 -#define in_bitwise_or_type 1090 -#define isnot_bitwise_or_type 1091 -#define is_bitwise_or_type 1092 -#define bitwise_or_type 1093 // Left-recursive -#define bitwise_xor_type 1094 // Left-recursive -#define bitwise_and_type 1095 // Left-recursive -#define shift_expr_type 1096 // Left-recursive -#define sum_type 1097 // Left-recursive -#define term_type 1098 // Left-recursive -#define factor_type 1099 -#define power_type 1100 -#define await_primary_type 1101 -#define primary_type 1102 // Left-recursive -#define slices_type 1103 -#define slice_type 1104 -#define atom_type 1105 -#define strings_type 1106 -#define list_type 1107 -#define listcomp_type 1108 -#define tuple_type 1109 -#define group_type 1110 -#define genexp_type 1111 -#define set_type 1112 -#define setcomp_type 1113 -#define dict_type 1114 -#define dictcomp_type 1115 -#define double_starred_kvpairs_type 1116 -#define double_starred_kvpair_type 1117 -#define kvpair_type 1118 -#define for_if_clauses_type 1119 -#define for_if_clause_type 1120 -#define yield_expr_type 1121 -#define arguments_type 1122 -#define args_type 1123 -#define kwargs_type 1124 -#define starred_expression_type 1125 -#define kwarg_or_starred_type 1126 -#define kwarg_or_double_starred_type 1127 -#define star_targets_type 1128 -#define star_targets_list_seq_type 1129 -#define star_targets_tuple_seq_type 1130 -#define star_target_type 1131 -#define target_with_star_atom_type 1132 -#define star_atom_type 1133 -#define single_target_type 1134 -#define single_subscript_attribute_target_type 1135 -#define del_targets_type 1136 -#define del_target_type 1137 -#define del_t_atom_type 1138 -#define t_primary_type 1139 // Left-recursive -#define t_lookahead_type 1140 -#define invalid_arguments_type 1141 -#define invalid_kwarg_type 1142 -#define invalid_named_expression_type 1143 -#define invalid_assignment_type 1144 -#define invalid_ann_assign_target_type 1145 -#define invalid_del_stmt_type 1146 -#define invalid_block_type 1147 -#define invalid_primary_type 1148 // Left-recursive -#define invalid_comprehension_type 1149 -#define invalid_dict_comprehension_type 1150 -#define invalid_parameters_type 1151 -#define invalid_lambda_parameters_type 1152 -#define invalid_star_etc_type 1153 -#define invalid_lambda_star_etc_type 1154 -#define invalid_double_type_comments_type 1155 -#define invalid_with_item_type 1156 -#define invalid_for_target_type 1157 -#define invalid_group_type 1158 -#define invalid_import_from_targets_type 1159 -#define _loop0_1_type 1160 -#define _loop0_2_type 1161 -#define _loop0_4_type 1162 -#define _gather_3_type 1163 -#define _loop0_6_type 1164 -#define _gather_5_type 1165 -#define _loop0_8_type 1166 -#define _gather_7_type 1167 -#define _loop0_10_type 1168 -#define _gather_9_type 1169 -#define _loop1_11_type 1170 -#define _loop0_13_type 1171 -#define _gather_12_type 1172 -#define _tmp_14_type 1173 -#define _tmp_15_type 1174 -#define _tmp_16_type 1175 -#define _tmp_17_type 1176 -#define _tmp_18_type 1177 -#define _tmp_19_type 1178 -#define _tmp_20_type 1179 -#define _tmp_21_type 1180 -#define _loop1_22_type 1181 -#define _tmp_23_type 1182 -#define _tmp_24_type 1183 -#define _loop0_26_type 1184 -#define _gather_25_type 1185 -#define _loop0_28_type 1186 -#define _gather_27_type 1187 -#define _tmp_29_type 1188 -#define _tmp_30_type 1189 -#define _loop0_31_type 1190 -#define _loop1_32_type 1191 -#define _loop0_34_type 1192 -#define _gather_33_type 1193 -#define _tmp_35_type 1194 -#define _loop0_37_type 1195 -#define _gather_36_type 1196 -#define _tmp_38_type 1197 -#define _loop0_40_type 1198 -#define _gather_39_type 1199 -#define _loop0_42_type 1200 -#define _gather_41_type 1201 -#define _loop0_44_type 1202 -#define _gather_43_type 1203 -#define _loop0_46_type 1204 -#define _gather_45_type 1205 -#define _tmp_47_type 1206 -#define _loop1_48_type 1207 -#define _tmp_49_type 1208 -#define _tmp_50_type 1209 -#define _tmp_51_type 1210 -#define _tmp_52_type 1211 -#define _tmp_53_type 1212 -#define _loop0_54_type 1213 -#define _loop0_55_type 1214 -#define _loop0_56_type 1215 -#define _loop1_57_type 1216 -#define _loop0_58_type 1217 -#define _loop1_59_type 1218 -#define _loop1_60_type 1219 -#define _loop1_61_type 1220 -#define _loop0_62_type 1221 -#define _loop1_63_type 1222 -#define _loop0_64_type 1223 -#define _loop1_65_type 1224 -#define _loop0_66_type 1225 -#define _loop1_67_type 1226 -#define _loop1_68_type 1227 -#define _tmp_69_type 1228 -#define _loop1_70_type 1229 -#define _loop0_72_type 1230 -#define _gather_71_type 1231 -#define _loop1_73_type 1232 -#define _loop0_74_type 1233 -#define _loop0_75_type 1234 -#define _loop0_76_type 1235 -#define _loop1_77_type 1236 -#define _loop0_78_type 1237 -#define _loop1_79_type 1238 -#define _loop1_80_type 1239 -#define _loop1_81_type 1240 -#define _loop0_82_type 1241 -#define _loop1_83_type 1242 -#define _loop0_84_type 1243 -#define _loop1_85_type 1244 -#define _loop0_86_type 1245 -#define _loop1_87_type 1246 -#define _loop1_88_type 1247 -#define _loop1_89_type 1248 -#define _loop1_90_type 1249 -#define _tmp_91_type 1250 -#define _loop0_93_type 1251 -#define _gather_92_type 1252 -#define _tmp_94_type 1253 -#define _tmp_95_type 1254 -#define _tmp_96_type 1255 -#define _tmp_97_type 1256 -#define _loop1_98_type 1257 -#define _tmp_99_type 1258 -#define _tmp_100_type 1259 -#define _loop0_102_type 1260 -#define _gather_101_type 1261 -#define _loop1_103_type 1262 -#define _loop0_104_type 1263 -#define _loop0_105_type 1264 -#define _loop0_107_type 1265 -#define _gather_106_type 1266 -#define _tmp_108_type 1267 -#define _loop0_110_type 1268 -#define _gather_109_type 1269 -#define _loop0_112_type 1270 -#define _gather_111_type 1271 -#define _loop0_114_type 1272 -#define _gather_113_type 1273 -#define _loop0_116_type 1274 -#define _gather_115_type 1275 -#define _loop0_117_type 1276 -#define _loop0_119_type 1277 -#define _gather_118_type 1278 -#define _loop1_120_type 1279 -#define _tmp_121_type 1280 -#define _loop0_123_type 1281 -#define _gather_122_type 1282 -#define _tmp_124_type 1283 -#define _tmp_125_type 1284 -#define _loop0_126_type 1285 -#define _loop0_127_type 1286 -#define _loop0_128_type 1287 -#define _tmp_129_type 1288 -#define _tmp_130_type 1289 -#define _loop0_131_type 1290 -#define _tmp_132_type 1291 -#define _loop0_133_type 1292 -#define _tmp_134_type 1293 -#define _tmp_135_type 1294 -#define _tmp_136_type 1295 -#define _tmp_137_type 1296 -#define _tmp_138_type 1297 -#define _tmp_139_type 1298 -#define _tmp_140_type 1299 -#define _tmp_141_type 1300 -#define _tmp_142_type 1301 -#define _tmp_143_type 1302 -#define _tmp_144_type 1303 -#define _tmp_145_type 1304 -#define _tmp_146_type 1305 -#define _tmp_147_type 1306 -#define _tmp_148_type 1307 -#define _tmp_149_type 1308 -#define _tmp_150_type 1309 -#define _tmp_151_type 1310 -#define _loop1_152_type 1311 -#define _loop1_153_type 1312 -#define _tmp_154_type 1313 -#define _tmp_155_type 1314 - -static mod_ty file_rule(Parser *p); -static mod_ty interactive_rule(Parser *p); -static mod_ty eval_rule(Parser *p); -static mod_ty func_type_rule(Parser *p); -static expr_ty fstring_rule(Parser *p); -static asdl_seq* type_expressions_rule(Parser *p); -static asdl_seq* statements_rule(Parser *p); -static asdl_seq* statement_rule(Parser *p); -static asdl_seq* statement_newline_rule(Parser *p); -static asdl_seq* simple_stmt_rule(Parser *p); -static stmt_ty small_stmt_rule(Parser *p); -static stmt_ty compound_stmt_rule(Parser *p); -static stmt_ty assignment_rule(Parser *p); -static AugOperator* augassign_rule(Parser *p); -static stmt_ty global_stmt_rule(Parser *p); -static stmt_ty nonlocal_stmt_rule(Parser *p); -static stmt_ty yield_stmt_rule(Parser *p); -static stmt_ty assert_stmt_rule(Parser *p); -static stmt_ty del_stmt_rule(Parser *p); -static stmt_ty import_stmt_rule(Parser *p); -static stmt_ty import_name_rule(Parser *p); -static stmt_ty import_from_rule(Parser *p); -static asdl_seq* import_from_targets_rule(Parser *p); -static asdl_seq* import_from_as_names_rule(Parser *p); -static alias_ty import_from_as_name_rule(Parser *p); -static asdl_seq* dotted_as_names_rule(Parser *p); -static alias_ty dotted_as_name_rule(Parser *p); -static expr_ty dotted_name_rule(Parser *p); -static stmt_ty if_stmt_rule(Parser *p); -static stmt_ty elif_stmt_rule(Parser *p); -static asdl_seq* else_block_rule(Parser *p); -static stmt_ty while_stmt_rule(Parser *p); -static stmt_ty for_stmt_rule(Parser *p); -static stmt_ty with_stmt_rule(Parser *p); -static withitem_ty with_item_rule(Parser *p); -static stmt_ty try_stmt_rule(Parser *p); -static excepthandler_ty except_block_rule(Parser *p); -static asdl_seq* finally_block_rule(Parser *p); -static stmt_ty return_stmt_rule(Parser *p); -static stmt_ty raise_stmt_rule(Parser *p); -static stmt_ty function_def_rule(Parser *p); -static stmt_ty function_def_raw_rule(Parser *p); -static Token* func_type_comment_rule(Parser *p); -static arguments_ty params_rule(Parser *p); -static arguments_ty parameters_rule(Parser *p); -static asdl_seq* slash_no_default_rule(Parser *p); -static SlashWithDefault* slash_with_default_rule(Parser *p); -static StarEtc* star_etc_rule(Parser *p); -static arg_ty kwds_rule(Parser *p); -static arg_ty param_no_default_rule(Parser *p); -static NameDefaultPair* param_with_default_rule(Parser *p); -static NameDefaultPair* param_maybe_default_rule(Parser *p); -static arg_ty param_rule(Parser *p); -static expr_ty annotation_rule(Parser *p); -static expr_ty default_rule(Parser *p); -static asdl_seq* decorators_rule(Parser *p); -static stmt_ty class_def_rule(Parser *p); -static stmt_ty class_def_raw_rule(Parser *p); -static asdl_seq* block_rule(Parser *p); -static expr_ty star_expressions_rule(Parser *p); -static expr_ty star_expression_rule(Parser *p); -static asdl_seq* star_named_expressions_rule(Parser *p); -static expr_ty star_named_expression_rule(Parser *p); -static expr_ty named_expression_rule(Parser *p); -static expr_ty annotated_rhs_rule(Parser *p); -static expr_ty expressions_rule(Parser *p); -static expr_ty expression_rule(Parser *p); -static expr_ty lambdef_rule(Parser *p); -static arguments_ty lambda_params_rule(Parser *p); -static arguments_ty lambda_parameters_rule(Parser *p); -static asdl_seq* lambda_slash_no_default_rule(Parser *p); -static SlashWithDefault* lambda_slash_with_default_rule(Parser *p); -static StarEtc* lambda_star_etc_rule(Parser *p); -static arg_ty lambda_kwds_rule(Parser *p); -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 disjunction_rule(Parser *p); -static expr_ty conjunction_rule(Parser *p); -static expr_ty inversion_rule(Parser *p); -static expr_ty comparison_rule(Parser *p); -static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p); -static CmpopExprPair* eq_bitwise_or_rule(Parser *p); -static CmpopExprPair* noteq_bitwise_or_rule(Parser *p); -static CmpopExprPair* lte_bitwise_or_rule(Parser *p); -static CmpopExprPair* lt_bitwise_or_rule(Parser *p); -static CmpopExprPair* gte_bitwise_or_rule(Parser *p); -static CmpopExprPair* gt_bitwise_or_rule(Parser *p); -static CmpopExprPair* notin_bitwise_or_rule(Parser *p); -static CmpopExprPair* in_bitwise_or_rule(Parser *p); -static CmpopExprPair* isnot_bitwise_or_rule(Parser *p); -static CmpopExprPair* is_bitwise_or_rule(Parser *p); -static expr_ty bitwise_or_rule(Parser *p); -static expr_ty bitwise_xor_rule(Parser *p); -static expr_ty bitwise_and_rule(Parser *p); -static expr_ty shift_expr_rule(Parser *p); -static expr_ty sum_rule(Parser *p); -static expr_ty term_rule(Parser *p); -static expr_ty factor_rule(Parser *p); -static expr_ty power_rule(Parser *p); -static expr_ty await_primary_rule(Parser *p); -static expr_ty primary_rule(Parser *p); -static expr_ty slices_rule(Parser *p); -static expr_ty slice_rule(Parser *p); -static expr_ty atom_rule(Parser *p); -static expr_ty strings_rule(Parser *p); -static expr_ty list_rule(Parser *p); -static expr_ty listcomp_rule(Parser *p); -static expr_ty tuple_rule(Parser *p); -static expr_ty group_rule(Parser *p); -static expr_ty genexp_rule(Parser *p); -static expr_ty set_rule(Parser *p); -static expr_ty setcomp_rule(Parser *p); -static expr_ty dict_rule(Parser *p); -static expr_ty dictcomp_rule(Parser *p); -static asdl_seq* double_starred_kvpairs_rule(Parser *p); -static KeyValuePair* double_starred_kvpair_rule(Parser *p); -static KeyValuePair* kvpair_rule(Parser *p); -static asdl_seq* for_if_clauses_rule(Parser *p); -static comprehension_ty for_if_clause_rule(Parser *p); -static expr_ty yield_expr_rule(Parser *p); -static expr_ty arguments_rule(Parser *p); -static expr_ty args_rule(Parser *p); -static asdl_seq* kwargs_rule(Parser *p); -static expr_ty starred_expression_rule(Parser *p); -static KeywordOrStarred* kwarg_or_starred_rule(Parser *p); -static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p); -static expr_ty star_targets_rule(Parser *p); -static asdl_seq* star_targets_list_seq_rule(Parser *p); -static asdl_seq* star_targets_tuple_seq_rule(Parser *p); -static expr_ty star_target_rule(Parser *p); -static expr_ty target_with_star_atom_rule(Parser *p); -static expr_ty star_atom_rule(Parser *p); -static expr_ty single_target_rule(Parser *p); -static expr_ty single_subscript_attribute_target_rule(Parser *p); -static asdl_seq* del_targets_rule(Parser *p); -static expr_ty del_target_rule(Parser *p); -static expr_ty del_t_atom_rule(Parser *p); -static expr_ty t_primary_rule(Parser *p); -static void *t_lookahead_rule(Parser *p); -static void *invalid_arguments_rule(Parser *p); -static void *invalid_kwarg_rule(Parser *p); -static void *invalid_named_expression_rule(Parser *p); -static void *invalid_assignment_rule(Parser *p); -static expr_ty invalid_ann_assign_target_rule(Parser *p); -static void *invalid_del_stmt_rule(Parser *p); -static void *invalid_block_rule(Parser *p); -static void *invalid_primary_rule(Parser *p); -static void *invalid_comprehension_rule(Parser *p); -static void *invalid_dict_comprehension_rule(Parser *p); -static void *invalid_parameters_rule(Parser *p); -static void *invalid_lambda_parameters_rule(Parser *p); -static void *invalid_star_etc_rule(Parser *p); -static void *invalid_lambda_star_etc_rule(Parser *p); -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_from_targets_rule(Parser *p); -static asdl_seq *_loop0_1_rule(Parser *p); -static asdl_seq *_loop0_2_rule(Parser *p); -static asdl_seq *_loop0_4_rule(Parser *p); -static asdl_seq *_gather_3_rule(Parser *p); -static asdl_seq *_loop0_6_rule(Parser *p); -static asdl_seq *_gather_5_rule(Parser *p); -static asdl_seq *_loop0_8_rule(Parser *p); -static asdl_seq *_gather_7_rule(Parser *p); -static asdl_seq *_loop0_10_rule(Parser *p); -static asdl_seq *_gather_9_rule(Parser *p); -static asdl_seq *_loop1_11_rule(Parser *p); -static asdl_seq *_loop0_13_rule(Parser *p); -static asdl_seq *_gather_12_rule(Parser *p); -static void *_tmp_14_rule(Parser *p); -static void *_tmp_15_rule(Parser *p); -static void *_tmp_16_rule(Parser *p); -static void *_tmp_17_rule(Parser *p); -static void *_tmp_18_rule(Parser *p); -static void *_tmp_19_rule(Parser *p); -static void *_tmp_20_rule(Parser *p); -static void *_tmp_21_rule(Parser *p); -static asdl_seq *_loop1_22_rule(Parser *p); -static void *_tmp_23_rule(Parser *p); -static void *_tmp_24_rule(Parser *p); -static asdl_seq *_loop0_26_rule(Parser *p); -static asdl_seq *_gather_25_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 void *_tmp_30_rule(Parser *p); -static asdl_seq *_loop0_31_rule(Parser *p); -static asdl_seq *_loop1_32_rule(Parser *p); -static asdl_seq *_loop0_34_rule(Parser *p); -static asdl_seq *_gather_33_rule(Parser *p); -static void *_tmp_35_rule(Parser *p); -static asdl_seq *_loop0_37_rule(Parser *p); -static asdl_seq *_gather_36_rule(Parser *p); -static void *_tmp_38_rule(Parser *p); -static asdl_seq *_loop0_40_rule(Parser *p); -static asdl_seq *_gather_39_rule(Parser *p); -static asdl_seq *_loop0_42_rule(Parser *p); -static asdl_seq *_gather_41_rule(Parser *p); -static asdl_seq *_loop0_44_rule(Parser *p); -static asdl_seq *_gather_43_rule(Parser *p); -static asdl_seq *_loop0_46_rule(Parser *p); -static asdl_seq *_gather_45_rule(Parser *p); -static void *_tmp_47_rule(Parser *p); -static asdl_seq *_loop1_48_rule(Parser *p); -static void *_tmp_49_rule(Parser *p); -static void *_tmp_50_rule(Parser *p); -static void *_tmp_51_rule(Parser *p); -static void *_tmp_52_rule(Parser *p); -static void *_tmp_53_rule(Parser *p); -static asdl_seq *_loop0_54_rule(Parser *p); -static asdl_seq *_loop0_55_rule(Parser *p); -static asdl_seq *_loop0_56_rule(Parser *p); -static asdl_seq *_loop1_57_rule(Parser *p); -static asdl_seq *_loop0_58_rule(Parser *p); -static asdl_seq *_loop1_59_rule(Parser *p); -static asdl_seq *_loop1_60_rule(Parser *p); -static asdl_seq *_loop1_61_rule(Parser *p); -static asdl_seq *_loop0_62_rule(Parser *p); -static asdl_seq *_loop1_63_rule(Parser *p); -static asdl_seq *_loop0_64_rule(Parser *p); -static asdl_seq *_loop1_65_rule(Parser *p); -static asdl_seq *_loop0_66_rule(Parser *p); -static asdl_seq *_loop1_67_rule(Parser *p); -static asdl_seq *_loop1_68_rule(Parser *p); -static void *_tmp_69_rule(Parser *p); -static asdl_seq *_loop1_70_rule(Parser *p); -static asdl_seq *_loop0_72_rule(Parser *p); -static asdl_seq *_gather_71_rule(Parser *p); -static asdl_seq *_loop1_73_rule(Parser *p); -static asdl_seq *_loop0_74_rule(Parser *p); -static asdl_seq *_loop0_75_rule(Parser *p); -static asdl_seq *_loop0_76_rule(Parser *p); -static asdl_seq *_loop1_77_rule(Parser *p); -static asdl_seq *_loop0_78_rule(Parser *p); -static asdl_seq *_loop1_79_rule(Parser *p); -static asdl_seq *_loop1_80_rule(Parser *p); -static asdl_seq *_loop1_81_rule(Parser *p); -static asdl_seq *_loop0_82_rule(Parser *p); -static asdl_seq *_loop1_83_rule(Parser *p); -static asdl_seq *_loop0_84_rule(Parser *p); -static asdl_seq *_loop1_85_rule(Parser *p); -static asdl_seq *_loop0_86_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 asdl_seq *_loop1_90_rule(Parser *p); -static void *_tmp_91_rule(Parser *p); -static asdl_seq *_loop0_93_rule(Parser *p); -static asdl_seq *_gather_92_rule(Parser *p); -static void *_tmp_94_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 asdl_seq *_loop1_98_rule(Parser *p); -static void *_tmp_99_rule(Parser *p); -static void *_tmp_100_rule(Parser *p); -static asdl_seq *_loop0_102_rule(Parser *p); -static asdl_seq *_gather_101_rule(Parser *p); -static asdl_seq *_loop1_103_rule(Parser *p); -static asdl_seq *_loop0_104_rule(Parser *p); -static asdl_seq *_loop0_105_rule(Parser *p); -static asdl_seq *_loop0_107_rule(Parser *p); -static asdl_seq *_gather_106_rule(Parser *p); -static void *_tmp_108_rule(Parser *p); -static asdl_seq *_loop0_110_rule(Parser *p); -static asdl_seq *_gather_109_rule(Parser *p); -static asdl_seq *_loop0_112_rule(Parser *p); -static asdl_seq *_gather_111_rule(Parser *p); -static asdl_seq *_loop0_114_rule(Parser *p); -static asdl_seq *_gather_113_rule(Parser *p); -static asdl_seq *_loop0_116_rule(Parser *p); -static asdl_seq *_gather_115_rule(Parser *p); -static asdl_seq *_loop0_117_rule(Parser *p); -static asdl_seq *_loop0_119_rule(Parser *p); -static asdl_seq *_gather_118_rule(Parser *p); -static asdl_seq *_loop1_120_rule(Parser *p); -static void *_tmp_121_rule(Parser *p); -static asdl_seq *_loop0_123_rule(Parser *p); -static asdl_seq *_gather_122_rule(Parser *p); -static void *_tmp_124_rule(Parser *p); -static void *_tmp_125_rule(Parser *p); -static asdl_seq *_loop0_126_rule(Parser *p); -static asdl_seq *_loop0_127_rule(Parser *p); -static asdl_seq *_loop0_128_rule(Parser *p); -static void *_tmp_129_rule(Parser *p); -static void *_tmp_130_rule(Parser *p); -static asdl_seq *_loop0_131_rule(Parser *p); -static void *_tmp_132_rule(Parser *p); -static asdl_seq *_loop0_133_rule(Parser *p); -static void *_tmp_134_rule(Parser *p); -static void *_tmp_135_rule(Parser *p); -static void *_tmp_136_rule(Parser *p); -static void *_tmp_137_rule(Parser *p); -static void *_tmp_138_rule(Parser *p); -static void *_tmp_139_rule(Parser *p); -static void *_tmp_140_rule(Parser *p); -static void *_tmp_141_rule(Parser *p); -static void *_tmp_142_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 void *_tmp_149_rule(Parser *p); -static void *_tmp_150_rule(Parser *p); -static void *_tmp_151_rule(Parser *p); -static asdl_seq *_loop1_152_rule(Parser *p); -static asdl_seq *_loop1_153_rule(Parser *p); -static void *_tmp_154_rule(Parser *p); -static void *_tmp_155_rule(Parser *p); - - -// file: statements? $ -static mod_ty -file_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - mod_ty _res = NULL; - int _mark = p->mark; - { // statements? $ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> file[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statements? $")); - void *a; - Token * endmarker_var; - if ( - (a = statements_rule(p), !p->error_indicator) // statements? - && - (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' - ) - { - D(fprintf(stderr, "%*c+ file[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statements? $")); - _res = _PyPegen_make_module ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s file[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statements? $")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// interactive: statement_newline -static mod_ty -interactive_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - mod_ty _res = NULL; - int _mark = p->mark; - { // statement_newline - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> interactive[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement_newline")); - asdl_seq* a; - if ( - (a = statement_newline_rule(p)) // statement_newline - ) - { - D(fprintf(stderr, "%*c+ interactive[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement_newline")); - _res = Interactive ( a , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s interactive[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statement_newline")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// eval: expressions NEWLINE* $ -static mod_ty -eval_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - mod_ty _res = NULL; - int _mark = p->mark; - { // expressions NEWLINE* $ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> eval[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions NEWLINE* $")); - asdl_seq * _loop0_1_var; - expr_ty a; - Token * endmarker_var; - if ( - (a = expressions_rule(p)) // expressions - && - (_loop0_1_var = _loop0_1_rule(p)) // NEWLINE* - && - (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' - ) - { - D(fprintf(stderr, "%*c+ eval[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions NEWLINE* $")); - _res = Expression ( a , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s eval[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions NEWLINE* $")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// func_type: '(' type_expressions? ')' '->' expression NEWLINE* $ -static mod_ty -func_type_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - mod_ty _res = NULL; - int _mark = p->mark; - { // '(' type_expressions? ')' '->' expression NEWLINE* $ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> func_type[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); - Token * _literal; - Token * _literal_1; - Token * _literal_2; - asdl_seq * _loop0_2_var; - void *a; - expr_ty b; - Token * endmarker_var; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = type_expressions_rule(p), !p->error_indicator) // type_expressions? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - && - (_literal_2 = _PyPegen_expect_token(p, 51)) // token='->' - && - (b = expression_rule(p)) // expression - && - (_loop0_2_var = _loop0_2_rule(p)) // NEWLINE* - && - (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' - ) - { - D(fprintf(stderr, "%*c+ func_type[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); - _res = FunctionType ( a , b , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s func_type[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// fstring: star_expressions -static expr_ty -fstring_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - int _mark = p->mark; - { // star_expressions - 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; - if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions - ) - { - D(fprintf(stderr, "%*c+ fstring[%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 fstring[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// type_expressions: -// | ','.expression+ ',' '*' expression ',' '**' expression -// | ','.expression+ ',' '*' expression -// | ','.expression+ ',' '**' expression -// | '*' expression ',' '**' expression -// | '*' expression -// | '**' expression -// | ','.expression+ -static asdl_seq* -type_expressions_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.expression+ ',' '*' expression ',' '**' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); - Token * _literal; - Token * _literal_1; - Token * _literal_2; - Token * _literal_3; - asdl_seq * a; - expr_ty b; - expr_ty c; - if ( - (a = _gather_3_rule(p)) // ','.expression+ - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_literal_1 = _PyPegen_expect_token(p, 16)) // token='*' - && - (b = expression_rule(p)) // expression - && - (_literal_2 = _PyPegen_expect_token(p, 12)) // token=',' - && - (_literal_3 = _PyPegen_expect_token(p, 35)) // token='**' - && - (c = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); - _res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_seq_append_to_end ( p , a , 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 type_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); - } - { // ','.expression+ ',' '*' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression")); - Token * _literal; - Token * _literal_1; - asdl_seq * a; - expr_ty b; - if ( - (a = _gather_5_rule(p)) // ','.expression+ - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_literal_1 = _PyPegen_expect_token(p, 16)) // token='*' - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression")); - _res = _PyPegen_seq_append_to_end ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s type_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+ ',' '*' expression")); - } - { // ','.expression+ ',' '**' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression")); - Token * _literal; - Token * _literal_1; - asdl_seq * a; - expr_ty b; - if ( - (a = _gather_7_rule(p)) // ','.expression+ - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_literal_1 = _PyPegen_expect_token(p, 35)) // token='**' - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression")); - _res = _PyPegen_seq_append_to_end ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s type_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+ ',' '**' expression")); - } - { // '*' expression ',' '**' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression")); - Token * _literal; - Token * _literal_1; - Token * _literal_2; - expr_ty a; - expr_ty b; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = expression_rule(p)) // expression - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - && - (_literal_2 = _PyPegen_expect_token(p, 35)) // token='**' - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression")); - _res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_singleton_seq ( p , a ) ) , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s type_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression ',' '**' expression")); - } - { // '*' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression")); - _res = _PyPegen_singleton_seq ( p , 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_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression")); - } - { // '**' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression")); - _res = _PyPegen_singleton_seq ( p , 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_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' expression")); - } - { // ','.expression+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+")); - asdl_seq * _gather_9_var; - if ( - (_gather_9_var = _gather_9_rule(p)) // ','.expression+ - ) - { - D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+")); - _res = _gather_9_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s type_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.expression+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// statements: statement+ -static asdl_seq* -statements_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // statement+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> statements[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement+")); - asdl_seq * a; - if ( - (a = _loop1_11_rule(p)) // statement+ - ) - { - D(fprintf(stderr, "%*c+ statements[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement+")); - _res = _PyPegen_seq_flatten ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s statements[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statement+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// statement: compound_stmt | simple_stmt -static asdl_seq* -statement_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // compound_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt")); - stmt_ty a; - if ( - (a = compound_stmt_rule(p)) // compound_stmt - ) - { - D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt")); - _res = _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s statement[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compound_stmt")); - } - { // simple_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - asdl_seq* simple_stmt_var; - if ( - (simple_stmt_var = simple_stmt_rule(p)) // simple_stmt - ) - { - D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - _res = simple_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s statement[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// statement_newline: compound_stmt NEWLINE | simple_stmt | NEWLINE | $ -static asdl_seq* -statement_newline_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _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 - { // compound_stmt NEWLINE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt NEWLINE")); - stmt_ty a; - Token * newline_var; - if ( - (a = compound_stmt_rule(p)) // compound_stmt - && - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - ) - { - D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt NEWLINE")); - _res = _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s statement_newline[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compound_stmt NEWLINE")); - } - { // simple_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - asdl_seq* simple_stmt_var; - if ( - (simple_stmt_var = simple_stmt_rule(p)) // simple_stmt - ) - { - D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - _res = simple_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s statement_newline[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt")); - } - { // NEWLINE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> statement_newline[%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+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); - 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_singleton_seq ( p , CHECK ( _Py_Pass ( EXTRA ) ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s statement_newline[%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> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "$")); - Token * endmarker_var; - if ( - (endmarker_var = _PyPegen_expect_token(p, ENDMARKER)) // token='ENDMARKER' - ) - { - D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "$")); - _res = _PyPegen_interactive_exit ( p ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s statement_newline[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "$")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// simple_stmt: small_stmt !';' NEWLINE | ';'.small_stmt+ ';'? NEWLINE -static asdl_seq* -simple_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // small_stmt !';' NEWLINE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "small_stmt !';' NEWLINE")); - stmt_ty a; - Token * newline_var; - if ( - (a = small_stmt_rule(p)) // small_stmt - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 13) // token=';' - && - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - ) - { - D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "small_stmt !';' NEWLINE")); - _res = _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "small_stmt !';' NEWLINE")); - } - { // ';'.small_stmt+ ';'? NEWLINE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'.small_stmt+ ';'? NEWLINE")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - Token * newline_var; - if ( - (a = _gather_12_rule(p)) // ';'.small_stmt+ - && - (_opt_var = _PyPegen_expect_token(p, 13), !p->error_indicator) // ';'? - && - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - ) - { - D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'.small_stmt+ ';'? NEWLINE")); - _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 simple_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';'.small_stmt+ ';'? NEWLINE")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// small_stmt: -// | assignment -// | star_expressions -// | &'return' return_stmt -// | &('import' | 'from') import_stmt -// | &'raise' raise_stmt -// | 'pass' -// | &'del' del_stmt -// | &'yield' yield_stmt -// | &'assert' assert_stmt -// | 'break' -// | 'continue' -// | &'global' global_stmt -// | &'nonlocal' nonlocal_stmt -static stmt_ty -small_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - stmt_ty _res = NULL; - if (_PyPegen_is_memoized(p, small_stmt_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 - { // assignment - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment")); - stmt_ty assignment_var; - if ( - (assignment_var = assignment_rule(p)) // assignment - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment")); - _res = assignment_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment")); - } - { // star_expressions - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty e; - if ( - (e = star_expressions_rule(p)) // star_expressions - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - 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 = _Py_Expr ( e , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); - } - { // &'return' return_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'return' return_stmt")); - stmt_ty return_stmt_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 500) // token='return' - && - (return_stmt_var = return_stmt_rule(p)) // return_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'return' return_stmt")); - _res = return_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'return' return_stmt")); - } - { // &('import' | 'from') import_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); - stmt_ty import_stmt_var; - if ( - _PyPegen_lookahead(1, _tmp_14_rule, p) - && - (import_stmt_var = import_stmt_rule(p)) // import_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); - _res = import_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('import' | 'from') import_stmt")); - } - { // &'raise' raise_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'raise' raise_stmt")); - stmt_ty raise_stmt_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 501) // token='raise' - && - (raise_stmt_var = raise_stmt_rule(p)) // raise_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'raise' raise_stmt")); - _res = raise_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'raise' raise_stmt")); - } - { // 'pass' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'pass'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 502)) // token='pass' - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'pass'")); - 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 = _Py_Pass ( EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'pass'")); - } - { // &'del' del_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_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, 503) // token='del' - && - (del_stmt_var = del_stmt_rule(p)) // del_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'del' del_stmt")); - _res = del_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'del' del_stmt")); - } - { // &'yield' yield_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'yield' yield_stmt")); - stmt_ty yield_stmt_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 504) // token='yield' - && - (yield_stmt_var = yield_stmt_rule(p)) // yield_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'yield' yield_stmt")); - _res = yield_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'yield' yield_stmt")); - } - { // &'assert' assert_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'assert' assert_stmt")); - stmt_ty assert_stmt_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 505) // token='assert' - && - (assert_stmt_var = assert_stmt_rule(p)) // assert_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'assert' assert_stmt")); - _res = assert_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'assert' assert_stmt")); - } - { // 'break' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'break'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 506)) // token='break' - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'break'")); - 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 = _Py_Break ( EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'break'")); - } - { // 'continue' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'continue'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 507)) // token='continue' - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'continue'")); - 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 = _Py_Continue ( EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'continue'")); - } - { // &'global' global_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'global' global_stmt")); - stmt_ty global_stmt_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 508) // token='global' - && - (global_stmt_var = global_stmt_rule(p)) // global_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'global' global_stmt")); - _res = global_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'global' global_stmt")); - } - { // &'nonlocal' nonlocal_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'nonlocal' nonlocal_stmt")); - stmt_ty nonlocal_stmt_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 509) // token='nonlocal' - && - (nonlocal_stmt_var = nonlocal_stmt_rule(p)) // nonlocal_stmt - ) - { - D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'nonlocal' nonlocal_stmt")); - _res = nonlocal_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s small_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'nonlocal' nonlocal_stmt")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, small_stmt_type, _res); - p->level--; - return _res; -} - -// compound_stmt: -// | &('def' | '@' | ASYNC) function_def -// | &'if' if_stmt -// | &('class' | '@') class_def -// | &('with' | ASYNC) with_stmt -// | &('for' | ASYNC) for_stmt -// | &'try' try_stmt -// | &'while' while_stmt -static stmt_ty -compound_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - stmt_ty _res = NULL; - int _mark = p->mark; - { // &('def' | '@' | ASYNC) function_def - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_15_rule, p) - && - (function_def_var = function_def_rule(p)) // function_def - ) - { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); - _res = function_def_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); - } - { // &'if' if_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - 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, 510) // token='if' - && - (if_stmt_var = if_stmt_rule(p)) // if_stmt - ) - { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt")); - _res = if_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'if' if_stmt")); - } - { // &('class' | '@') class_def - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_16_rule, p) - && - (class_def_var = class_def_rule(p)) // class_def - ) - { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('class' | '@') class_def")); - _res = class_def_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('class' | '@') class_def")); - } - { // &('with' | ASYNC) with_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_17_rule, p) - && - (with_stmt_var = with_stmt_rule(p)) // with_stmt - ) - { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('with' | ASYNC) with_stmt")); - _res = with_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('with' | ASYNC) with_stmt")); - } - { // &('for' | ASYNC) for_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_18_rule, p) - && - (for_stmt_var = for_stmt_rule(p)) // for_stmt - ) - { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('for' | ASYNC) for_stmt")); - _res = for_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('for' | ASYNC) for_stmt")); - } - { // &'try' try_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - 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, 511) // token='try' - && - (try_stmt_var = try_stmt_rule(p)) // try_stmt - ) - { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt")); - _res = try_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'try' try_stmt")); - } - { // &'while' while_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - 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, 512) // token='while' - && - (while_stmt_var = while_stmt_rule(p)) // while_stmt - ) - { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt")); - _res = while_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'while' while_stmt")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// assignment: -// | NAME ':' expression ['=' annotated_rhs] -// | ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs] -// | ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT? -// | single_target augassign ~ (yield_expr | star_expressions) -// | invalid_assignment -static stmt_ty -assignment_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // NAME ':' expression ['=' annotated_rhs] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); - Token * _literal; - expr_ty a; - expr_ty b; - void *c; - if ( - (a = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = expression_rule(p)) // expression - && - (c = _tmp_19_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]")); - 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 ( 6 , "Variable annotation syntax is" , _Py_AnnAssign ( CHECK ( _PyPegen_set_expr_context ( p , a , Store ) ) , b , c , 1 , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); - } - { // ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); - Token * _literal; - void *a; - expr_ty b; - void *c; - if ( - (a = _tmp_20_rule(p)) // '(' single_target ')' | single_subscript_attribute_target - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = expression_rule(p)) // expression - && - (c = _tmp_21_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]")); - 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 ( 6 , "Variable annotations syntax is" , _Py_AnnAssign ( a , b , c , 0 , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); - } - { // ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); - asdl_seq * a; - void *b; - void *tc; - if ( - (a = _loop1_22_rule(p)) // ((star_targets '='))+ - && - (b = _tmp_23_rule(p)) // yield_expr | star_expressions - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - ) - { - D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); - 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 = _Py_Assign ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); - } - { // single_target augassign ~ (yield_expr | star_expressions) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); - int _cut_var = 0; - expr_ty a; - AugOperator* b; - void *c; - if ( - (a = single_target_rule(p)) // single_target - && - (b = augassign_rule(p)) // augassign - && - (_cut_var = 1) - && - (c = _tmp_24_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)")); - 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 = _Py_AugAssign ( a , b -> kind , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); - if (_cut_var) { - p->level--; - return NULL; - } - } - if (p->call_invalid_rules) { // invalid_assignment - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_assignment")); - void *invalid_assignment_var; - if ( - (invalid_assignment_var = invalid_assignment_rule(p)) // invalid_assignment - ) - { - D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_assignment")); - _res = invalid_assignment_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_assignment")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// augassign: -// | '+=' -// | '-=' -// | '*=' -// | '@=' -// | '/=' -// | '%=' -// | '&=' -// | '|=' -// | '^=' -// | '<<=' -// | '>>=' -// | '**=' -// | '//=' -static AugOperator* -augassign_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - AugOperator* _res = NULL; - int _mark = p->mark; - { // '+=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 36)) // token='+=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+='")); - _res = _PyPegen_augoperator ( p , Add ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 37)) // token='-=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-='")); - _res = _PyPegen_augoperator ( p , Sub ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 38)) // token='*=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*='")); - _res = _PyPegen_augoperator ( p , Mult ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 50)) // token='@=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@='")); - _res = CHECK_VERSION ( 5 , "The '@' operator is" , _PyPegen_augoperator ( p , MatMult ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 39)) // token='/=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/='")); - _res = _PyPegen_augoperator ( p , Div ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'%='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 40)) // token='%=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'%='")); - _res = _PyPegen_augoperator ( p , Mod ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'&='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 41)) // token='&=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'&='")); - _res = _PyPegen_augoperator ( p , BitAnd ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 42)) // token='|=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|='")); - _res = _PyPegen_augoperator ( p , BitOr ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'^='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 43)) // token='^=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'^='")); - _res = _PyPegen_augoperator ( p , BitXor ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<<='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 44)) // token='<<=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<<='")); - _res = _PyPegen_augoperator ( p , LShift ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>>='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 45)) // token='>>=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>>='")); - _res = _PyPegen_augoperator ( p , RShift ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 46)) // token='**=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**='")); - _res = _PyPegen_augoperator ( p , Pow ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%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> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'//='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 48)) // token='//=' - ) - { - D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'//='")); - _res = _PyPegen_augoperator ( p , FloorDiv ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s augassign[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'//='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// global_stmt: 'global' ','.NAME+ -static stmt_ty -global_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'global' ','.NAME+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> global_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); - Token * _keyword; - asdl_seq * a; - if ( - (_keyword = _PyPegen_expect_token(p, 508)) // token='global' - && - (a = _gather_25_rule(p)) // ','.NAME+ - ) - { - D(fprintf(stderr, "%*c+ global_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'global' ','.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 = _Py_Global ( CHECK ( _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s global_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'global' ','.NAME+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// nonlocal_stmt: 'nonlocal' ','.NAME+ -static stmt_ty -nonlocal_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'nonlocal' ','.NAME+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> nonlocal_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); - Token * _keyword; - asdl_seq * a; - if ( - (_keyword = _PyPegen_expect_token(p, 509)) // token='nonlocal' - && - (a = _gather_27_rule(p)) // ','.NAME+ - ) - { - D(fprintf(stderr, "%*c+ nonlocal_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.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 = _Py_Nonlocal ( CHECK ( _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s nonlocal_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'nonlocal' ','.NAME+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// yield_stmt: yield_expr -static stmt_ty -yield_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // yield_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> yield_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); - expr_ty y; - if ( - (y = yield_expr_rule(p)) // yield_expr - ) - { - D(fprintf(stderr, "%*c+ yield_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); - 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 = _Py_Expr ( y , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s yield_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// assert_stmt: 'assert' expression [',' expression] -static stmt_ty -assert_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'assert' expression [',' expression] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> assert_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]")); - Token * _keyword; - expr_ty a; - void *b; - if ( - (_keyword = _PyPegen_expect_token(p, 505)) // token='assert' - && - (a = expression_rule(p)) // expression - && - (b = _tmp_29_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]")); - 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 = _Py_Assert ( a , 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 assert_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'assert' expression [',' expression]")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// del_stmt: 'del' del_targets &(';' | NEWLINE) | invalid_del_stmt -static stmt_ty -del_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'del' del_targets &(';' | NEWLINE) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); - Token * _keyword; - asdl_seq* a; - if ( - (_keyword = _PyPegen_expect_token(p, 503)) // token='del' - && - (a = del_targets_rule(p)) // del_targets - && - _PyPegen_lookahead(1, _tmp_30_rule, p) - ) - { - D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); - 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 = _Py_Delete ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); - } - if (p->call_invalid_rules) { // invalid_del_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_del_stmt")); - void *invalid_del_stmt_var; - if ( - (invalid_del_stmt_var = invalid_del_stmt_rule(p)) // invalid_del_stmt - ) - { - D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_del_stmt")); - _res = invalid_del_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_del_stmt")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// import_stmt: import_name | import_from -static stmt_ty -import_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - stmt_ty _res = NULL; - int _mark = p->mark; - { // import_name - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_name")); - stmt_ty import_name_var; - if ( - (import_name_var = import_name_rule(p)) // import_name - ) - { - D(fprintf(stderr, "%*c+ import_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_name")); - _res = import_name_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, "import_name")); - } - { // import_from - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from")); - stmt_ty import_from_var; - if ( - (import_from_var = import_from_rule(p)) // import_from - ) - { - D(fprintf(stderr, "%*c+ import_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from")); - _res = import_from_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, "import_from")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// import_name: 'import' dotted_as_names -static stmt_ty -import_name_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'import' dotted_as_names - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); - Token * _keyword; - asdl_seq* a; - if ( - (_keyword = _PyPegen_expect_token(p, 513)) // token='import' - && - (a = dotted_as_names_rule(p)) // dotted_as_names - ) - { - D(fprintf(stderr, "%*c+ import_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); - 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 = _Py_Import ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s import_name[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import' dotted_as_names")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// import_from: -// | 'from' (('.' | '...'))* dotted_name 'import' import_from_targets -// | 'from' (('.' | '...'))+ 'import' import_from_targets -static stmt_ty -import_from_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'from' (('.' | '...'))* dotted_name 'import' import_from_targets - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); - Token * _keyword; - Token * _keyword_1; - asdl_seq * a; - expr_ty b; - asdl_seq* c; - if ( - (_keyword = _PyPegen_expect_token(p, 514)) // token='from' - && - (a = _loop0_31_rule(p)) // (('.' | '...'))* - && - (b = dotted_name_rule(p)) // dotted_name - && - (_keyword_1 = _PyPegen_expect_token(p, 513)) // token='import' - && - (c = import_from_targets_rule(p)) // import_from_targets - ) - { - D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); - 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 = _Py_ImportFrom ( b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s import_from[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); - } - { // 'from' (('.' | '...'))+ 'import' import_from_targets - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); - Token * _keyword; - Token * _keyword_1; - asdl_seq * a; - asdl_seq* b; - if ( - (_keyword = _PyPegen_expect_token(p, 514)) // token='from' - && - (a = _loop1_32_rule(p)) // (('.' | '...'))+ - && - (_keyword_1 = _PyPegen_expect_token(p, 513)) // token='import' - && - (b = import_from_targets_rule(p)) // import_from_targets - ) - { - D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); - 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 = _Py_ImportFrom ( NULL , b , _PyPegen_seq_count_dots ( a ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s import_from[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// import_from_targets: -// | '(' import_from_as_names ','? ')' -// | import_from_as_names !',' -// | '*' -// | invalid_import_from_targets -static asdl_seq* -import_from_targets_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // '(' import_from_as_names ','? ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' import_from_as_names ','? ')'")); - Token * _literal; - Token * _literal_1; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq* a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = import_from_as_names_rule(p)) // import_from_as_names - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' import_from_as_names ','? ')'")); - _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 import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' import_from_as_names ','? ')'")); - } - { // import_from_as_names !',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names !','")); - asdl_seq* import_from_as_names_var; - if ( - (import_from_as_names_var = import_from_as_names_rule(p)) // import_from_as_names - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 12) // token=',' - ) - { - D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_names !','")); - _res = import_from_as_names_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_names !','")); - } - { // '*' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - ) - { - D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); - _res = _PyPegen_singleton_seq ( p , CHECK ( _PyPegen_alias_for_star ( p ) ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); - } - if (p->call_invalid_rules) { // invalid_import_from_targets - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_import_from_targets")); - void *invalid_import_from_targets_var; - if ( - (invalid_import_from_targets_var = invalid_import_from_targets_rule(p)) // invalid_import_from_targets - ) - { - D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_import_from_targets")); - _res = invalid_import_from_targets_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_import_from_targets")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// import_from_as_names: ','.import_from_as_name+ -static asdl_seq* -import_from_as_names_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.import_from_as_name+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); - asdl_seq * a; - if ( - (a = _gather_33_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+")); - _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 import_from_as_names[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.import_from_as_name+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// import_from_as_name: NAME ['as' NAME] -static alias_ty -import_from_as_name_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - alias_ty _res = NULL; - int _mark = p->mark; - { // NAME ['as' NAME] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> import_from_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ['as' NAME]")); - expr_ty a; - void *b; - if ( - (a = _PyPegen_name_token(p)) // NAME - && - (b = _tmp_35_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]")); - _res = _Py_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s import_from_as_name[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ['as' NAME]")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// dotted_as_names: ','.dotted_as_name+ -static asdl_seq* -dotted_as_names_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.dotted_as_name+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> dotted_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); - asdl_seq * a; - if ( - (a = _gather_36_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+")); - _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 dotted_as_names[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.dotted_as_name+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// dotted_as_name: dotted_name ['as' NAME] -static alias_ty -dotted_as_name_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - alias_ty _res = NULL; - int _mark = p->mark; - { // dotted_name ['as' NAME] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> dotted_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name ['as' NAME]")); - expr_ty a; - void *b; - if ( - (a = dotted_name_rule(p)) // dotted_name - && - (b = _tmp_38_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]")); - _res = _Py_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s dotted_as_name[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name ['as' NAME]")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// dotted_name: dotted_name '.' NAME | NAME -static expr_ty dotted_name_raw(Parser *); -static expr_ty -dotted_name_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, dotted_name_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_0 = _PyPegen_update_memo(p, _mark, dotted_name_type, _res); - if (tmpvar_0) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = dotted_name_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -dotted_name_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - int _mark = p->mark; - { // dotted_name '.' NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name '.' NAME")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = dotted_name_rule(p)) // dotted_name - && - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - && - (b = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ dotted_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name '.' NAME")); - _res = _PyPegen_join_names_with_dot ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s dotted_name[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name '.' NAME")); - } - { // NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); - expr_ty name_var; - if ( - (name_var = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ dotted_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); - _res = name_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s dotted_name[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// if_stmt: -// | 'if' named_expression ':' block elif_stmt -// | 'if' named_expression ':' block else_block? -static stmt_ty -if_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'if' named_expression ':' block elif_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt")); - Token * _keyword; - Token * _literal; - expr_ty a; - asdl_seq* b; - stmt_ty c; - if ( - (_keyword = _PyPegen_expect_token(p, 510)) // token='if' - && - (a = named_expression_rule(p)) // named_expression - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - && - (c = elif_stmt_rule(p)) // elif_stmt - ) - { - D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt")); - 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 = _Py_If ( a , b , CHECK ( _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s if_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' named_expression ':' block elif_stmt")); - } - { // 'if' named_expression ':' block else_block? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?")); - Token * _keyword; - Token * _literal; - expr_ty a; - asdl_seq* b; - void *c; - if ( - (_keyword = _PyPegen_expect_token(p, 510)) // token='if' - && - (a = named_expression_rule(p)) // named_expression - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - && - (c = else_block_rule(p), !p->error_indicator) // else_block? - ) - { - D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?")); - 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 = _Py_If ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s if_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' named_expression ':' block else_block?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// elif_stmt: -// | 'elif' named_expression ':' block elif_stmt -// | 'elif' named_expression ':' block else_block? -static stmt_ty -elif_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'elif' named_expression ':' block elif_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); - Token * _keyword; - Token * _literal; - expr_ty a; - asdl_seq* b; - stmt_ty c; - if ( - (_keyword = _PyPegen_expect_token(p, 515)) // token='elif' - && - (a = named_expression_rule(p)) // named_expression - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - && - (c = elif_stmt_rule(p)) // elif_stmt - ) - { - D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); - 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 = _Py_If ( a , b , CHECK ( _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s elif_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); - } - { // 'elif' named_expression ':' block else_block? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?")); - Token * _keyword; - Token * _literal; - expr_ty a; - asdl_seq* b; - void *c; - if ( - (_keyword = _PyPegen_expect_token(p, 515)) // token='elif' - && - (a = named_expression_rule(p)) // named_expression - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - && - (c = else_block_rule(p), !p->error_indicator) // else_block? - ) - { - D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?")); - 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 = _Py_If ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s elif_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'elif' named_expression ':' block else_block?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// else_block: 'else' ':' block -static asdl_seq* -else_block_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // 'else' ':' block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> else_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' ':' block")); - Token * _keyword; - Token * _literal; - asdl_seq* b; - if ( - (_keyword = _PyPegen_expect_token(p, 516)) // token='else' - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ else_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' ':' block")); - _res = b; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s else_block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else' ':' block")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// while_stmt: 'while' named_expression ':' block else_block? -static stmt_ty -while_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'while' named_expression ':' block else_block? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?")); - Token * _keyword; - Token * _literal; - expr_ty a; - asdl_seq* b; - void *c; - if ( - (_keyword = _PyPegen_expect_token(p, 512)) // token='while' - && - (a = named_expression_rule(p)) // named_expression - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - && - (c = else_block_rule(p), !p->error_indicator) // else_block? - ) - { - D(fprintf(stderr, "%*c+ while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?")); - 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 = _Py_While ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s while_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'while' named_expression ':' block else_block?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// for_stmt: -// | 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? -// | ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? -// | invalid_for_target -static stmt_ty -for_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); - int _cut_var = 0; - Token * _keyword; - Token * _keyword_1; - Token * _literal; - asdl_seq* b; - void *el; - expr_ty ex; - expr_ty t; - void *tc; - if ( - (_keyword = _PyPegen_expect_token(p, 517)) // token='for' - && - (t = star_targets_rule(p)) // star_targets - && - (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' - && - (_cut_var = 1) - && - (ex = star_expressions_rule(p)) // star_expressions - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - && - (b = block_rule(p)) // block - && - (el = else_block_rule(p), !p->error_indicator) // else_block? - ) - { - D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); - 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 = _Py_For ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); - if (_cut_var) { - p->level--; - return NULL; - } - } - { // ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); - int _cut_var = 0; - Token * _keyword; - Token * _keyword_1; - Token * _literal; - Token * async_var; - asdl_seq* b; - void *el; - expr_ty ex; - expr_ty t; - void *tc; - if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' - && - (_keyword = _PyPegen_expect_token(p, 517)) // token='for' - && - (t = star_targets_rule(p)) // star_targets - && - (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' - && - (_cut_var = 1) - && - (ex = star_expressions_rule(p)) // star_expressions - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - && - (b = block_rule(p)) // block - && - (el = else_block_rule(p), !p->error_indicator) // else_block? - ) - { - D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); - 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 ( 5 , "Async for loops are" , _Py_AsyncFor ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); - if (_cut_var) { - p->level--; - return NULL; - } - } - if (p->call_invalid_rules) { // invalid_for_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); - void *invalid_for_target_var; - if ( - (invalid_for_target_var = invalid_for_target_rule(p)) // invalid_for_target - ) - { - D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); - _res = invalid_for_target_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_for_target")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// with_stmt: -// | 'with' '(' ','.with_item+ ','? ')' ':' block -// | 'with' ','.with_item+ ':' TYPE_COMMENT? block -// | ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block -// | ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block -static stmt_ty -with_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'with' '(' ','.with_item+ ','? ')' ':' block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); - Token * _keyword; - Token * _literal; - Token * _literal_1; - Token * _literal_2; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - asdl_seq* b; - if ( - (_keyword = _PyPegen_expect_token(p, 519)) // token='with' - && - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = _gather_39_rule(p)) // ','.with_item+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - && - (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); - 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 = _Py_With ( a , b , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); - } - { // 'with' ','.with_item+ ':' TYPE_COMMENT? block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); - Token * _keyword; - Token * _literal; - asdl_seq * a; - asdl_seq* b; - void *tc; - if ( - (_keyword = _PyPegen_expect_token(p, 519)) // token='with' - && - (a = _gather_41_rule(p)) // ','.with_item+ - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - && - (b = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); - 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 = _Py_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); - } - { // ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); - Token * _keyword; - Token * _literal; - Token * _literal_1; - Token * _literal_2; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - Token * async_var; - asdl_seq* b; - if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' - && - (_keyword = _PyPegen_expect_token(p, 519)) // token='with' - && - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = _gather_43_rule(p)) // ','.with_item+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - && - (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); - 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 ( 5 , "Async with statements are" , _Py_AsyncWith ( a , b , NULL , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); - } - { // ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); - Token * _keyword; - Token * _literal; - asdl_seq * a; - Token * async_var; - asdl_seq* b; - void *tc; - if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' - && - (_keyword = _PyPegen_expect_token(p, 519)) // token='with' - && - (a = _gather_45_rule(p)) // ','.with_item+ - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - && - (b = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); - 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 ( 5 , "Async with statements are" , _Py_AsyncWith ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// with_item: -// | expression 'as' star_target &(',' | ')' | ':') -// | invalid_with_item -// | expression -static withitem_ty -with_item_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - withitem_ty _res = NULL; - int _mark = p->mark; - { // expression 'as' star_target &(',' | ')' | ':') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); - Token * _keyword; - expr_ty e; - expr_ty t; - if ( - (e = expression_rule(p)) // expression - && - (_keyword = _PyPegen_expect_token(p, 520)) // token='as' - && - (t = star_target_rule(p)) // star_target - && - _PyPegen_lookahead(1, _tmp_47_rule, p) - ) - { - D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); - _res = _Py_withitem ( e , t , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s with_item[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); - } - if (p->call_invalid_rules) { // invalid_with_item - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_item")); - void *invalid_with_item_var; - if ( - (invalid_with_item_var = invalid_with_item_rule(p)) // invalid_with_item - ) - { - D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_with_item")); - _res = invalid_with_item_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s with_item[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_with_item")); - } - { // expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); - expr_ty e; - if ( - (e = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); - _res = _Py_withitem ( e , NULL , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s with_item[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// try_stmt: -// | 'try' ':' block finally_block -// | 'try' ':' block except_block+ else_block? finally_block? -static stmt_ty -try_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'try' ':' block finally_block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block finally_block")); - Token * _keyword; - Token * _literal; - asdl_seq* b; - asdl_seq* f; - if ( - (_keyword = _PyPegen_expect_token(p, 511)) // token='try' - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - && - (f = finally_block_rule(p)) // finally_block - ) - { - D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block finally_block")); - 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 = _Py_Try ( b , NULL , NULL , f , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s try_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' ':' block finally_block")); - } - { // 'try' ':' block except_block+ else_block? finally_block? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block except_block+ else_block? finally_block?")); - Token * _keyword; - Token * _literal; - asdl_seq* b; - void *el; - asdl_seq * ex; - void *f; - if ( - (_keyword = _PyPegen_expect_token(p, 511)) // token='try' - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - && - (ex = _loop1_48_rule(p)) // except_block+ - && - (el = else_block_rule(p), !p->error_indicator) // else_block? - && - (f = finally_block_rule(p), !p->error_indicator) // finally_block? - ) - { - D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block except_block+ else_block? finally_block?")); - 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 = _Py_Try ( b , ex , el , f , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s try_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' ':' block except_block+ else_block? finally_block?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// except_block: 'except' expression ['as' NAME] ':' block | 'except' ':' block -static excepthandler_ty -except_block_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - excepthandler_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 - { // 'except' expression ['as' NAME] ':' block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block")); - Token * _keyword; - Token * _literal; - asdl_seq* b; - expr_ty e; - void *t; - if ( - (_keyword = _PyPegen_expect_token(p, 521)) // token='except' - && - (e = expression_rule(p)) // expression - && - (t = _tmp_49_rule(p), !p->error_indicator) // ['as' NAME] - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block")); - 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 = _Py_ExceptHandler ( e , ( t ) ? ( ( expr_ty ) t ) -> v . Name . id : NULL , 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 except_block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' expression ['as' NAME] ':' block")); - } - { // 'except' ':' block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' ':' block")); - Token * _keyword; - Token * _literal; - asdl_seq* b; - if ( - (_keyword = _PyPegen_expect_token(p, 521)) // token='except' - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' block")); - 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 = _Py_ExceptHandler ( NULL , NULL , 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 except_block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' ':' block")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// finally_block: 'finally' ':' block -static asdl_seq* -finally_block_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // 'finally' ':' block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> finally_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally' ':' block")); - Token * _keyword; - Token * _literal; - asdl_seq* a; - if ( - (_keyword = _PyPegen_expect_token(p, 522)) // token='finally' - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (a = block_rule(p)) // block - ) - { - D(fprintf(stderr, "%*c+ finally_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally' ':' block")); - _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 finally_block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally' ':' block")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// return_stmt: 'return' star_expressions? -static stmt_ty -return_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'return' star_expressions? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> return_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?")); - Token * _keyword; - void *a; - if ( - (_keyword = _PyPegen_expect_token(p, 500)) // token='return' - && - (a = star_expressions_rule(p), !p->error_indicator) // star_expressions? - ) - { - D(fprintf(stderr, "%*c+ return_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?")); - 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 = _Py_Return ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s return_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'return' star_expressions?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// raise_stmt: 'raise' expression ['from' expression] | 'raise' -static stmt_ty -raise_stmt_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'raise' expression ['from' expression] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]")); - Token * _keyword; - expr_ty a; - void *b; - if ( - (_keyword = _PyPegen_expect_token(p, 501)) // token='raise' - && - (a = expression_rule(p)) // expression - && - (b = _tmp_50_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]")); - 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 = _Py_Raise ( a , 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 raise_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'raise' expression ['from' expression]")); - } - { // 'raise' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 501)) // token='raise' - ) - { - D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise'")); - 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 = _Py_Raise ( NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s raise_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'raise'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// function_def: decorators function_def_raw | function_def_raw -static stmt_ty -function_def_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - stmt_ty _res = NULL; - int _mark = p->mark; - { // decorators function_def_raw - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw")); - asdl_seq* d; - stmt_ty f; - if ( - (d = decorators_rule(p)) // decorators - && - (f = function_def_raw_rule(p)) // function_def_raw - ) - { - D(fprintf(stderr, "%*c+ function_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw")); - _res = _PyPegen_function_def_decorators ( p , d , f ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s function_def[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "decorators function_def_raw")); - } - { // function_def_raw - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "function_def_raw")); - stmt_ty function_def_raw_var; - if ( - (function_def_raw_var = function_def_raw_rule(p)) // function_def_raw - ) - { - D(fprintf(stderr, "%*c+ function_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "function_def_raw")); - _res = function_def_raw_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s function_def[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "function_def_raw")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// function_def_raw: -// | 'def' NAME '(' params? ')' ['->' expression] ':' func_type_comment? block -// | ASYNC 'def' NAME '(' 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(); - } - 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 - { // 'def' NAME '(' 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")); - Token * _keyword; - Token * _literal; - Token * _literal_1; - Token * _literal_2; - void *a; - asdl_seq* b; - expr_ty n; - void *params; - void *tc; - if ( - (_keyword = _PyPegen_expect_token(p, 523)) // token='def' - && - (n = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (params = params_rule(p), !p->error_indicator) // params? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - && - (a = _tmp_51_rule(p), !p->error_indicator) // ['->' expression] - && - (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' - && - (tc = func_type_comment_rule(p), !p->error_indicator) // func_type_comment? - && - (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")); - 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 = _Py_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - 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")); - } - { // ASYNC 'def' NAME '(' 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")); - Token * _keyword; - Token * _literal; - Token * _literal_1; - Token * _literal_2; - void *a; - Token * async_var; - asdl_seq* b; - expr_ty n; - void *params; - void *tc; - if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' - && - (_keyword = _PyPegen_expect_token(p, 523)) // token='def' - && - (n = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (params = params_rule(p), !p->error_indicator) // params? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - && - (a = _tmp_52_rule(p), !p->error_indicator) // ['->' expression] - && - (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' - && - (tc = func_type_comment_rule(p), !p->error_indicator) // func_type_comment? - && - (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")); - 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 ( 5 , "Async functions are" , _Py_AsyncFunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - 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")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// func_type_comment: -// | NEWLINE TYPE_COMMENT &(NEWLINE INDENT) -// | invalid_double_type_comments -// | TYPE_COMMENT -static Token* -func_type_comment_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - Token* _res = NULL; - int _mark = p->mark; - { // NEWLINE TYPE_COMMENT &(NEWLINE INDENT) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); - Token * newline_var; - Token * t; - if ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - && - (t = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' - && - _PyPegen_lookahead(1, _tmp_53_rule, p) - ) - { - D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); - _res = t; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s func_type_comment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); - } - if (p->call_invalid_rules) { // invalid_double_type_comments - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_double_type_comments")); - void *invalid_double_type_comments_var; - if ( - (invalid_double_type_comments_var = invalid_double_type_comments_rule(p)) // invalid_double_type_comments - ) - { - D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_double_type_comments")); - _res = invalid_double_type_comments_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s func_type_comment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_double_type_comments")); - } - { // TYPE_COMMENT - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT")); - Token * type_comment_var; - if ( - (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' - ) - { - D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT")); - _res = type_comment_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s func_type_comment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "TYPE_COMMENT")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// params: invalid_parameters | parameters -static arguments_ty -params_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arguments_ty _res = NULL; - int _mark = p->mark; - if (p->call_invalid_rules) { // invalid_parameters - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_parameters")); - void *invalid_parameters_var; - if ( - (invalid_parameters_var = invalid_parameters_rule(p)) // invalid_parameters - ) - { - D(fprintf(stderr, "%*c+ params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_parameters")); - _res = invalid_parameters_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s params[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_parameters")); - } - { // parameters - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "parameters")); - arguments_ty parameters_var; - if ( - (parameters_var = parameters_rule(p)) // parameters - ) - { - D(fprintf(stderr, "%*c+ params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "parameters")); - _res = parameters_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s params[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "parameters")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// parameters: -// | slash_no_default param_no_default* param_with_default* star_etc? -// | slash_with_default param_with_default* star_etc? -// | param_no_default+ param_with_default* star_etc? -// | param_with_default+ star_etc? -// | star_etc -static arguments_ty -parameters_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arguments_ty _res = NULL; - int _mark = p->mark; - { // slash_no_default param_no_default* param_with_default* star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - asdl_seq* a; - asdl_seq * b; - asdl_seq * c; - void *d; - if ( - (a = slash_no_default_rule(p)) // slash_no_default - && - (b = _loop0_54_rule(p)) // param_no_default* - && - (c = _loop0_55_rule(p)) // param_with_default* - && - (d = star_etc_rule(p), !p->error_indicator) // star_etc? - ) - { - D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - } - { // slash_with_default param_with_default* star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); - SlashWithDefault* a; - asdl_seq * b; - void *c; - if ( - (a = slash_with_default_rule(p)) // slash_with_default - && - (b = _loop0_56_rule(p)) // param_with_default* - && - (c = star_etc_rule(p), !p->error_indicator) // star_etc? - ) - { - D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , 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 parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default param_with_default* star_etc?")); - } - { // param_no_default+ param_with_default* star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); - asdl_seq * a; - asdl_seq * b; - void *c; - if ( - (a = _loop1_57_rule(p)) // param_no_default+ - && - (b = _loop0_58_rule(p)) // param_with_default* - && - (c = star_etc_rule(p), !p->error_indicator) // star_etc? - ) - { - D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , NULL , a , 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 parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); - } - { // param_with_default+ star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+ star_etc?")); - asdl_seq * a; - void *b; - if ( - (a = _loop1_59_rule(p)) // param_with_default+ - && - (b = star_etc_rule(p), !p->error_indicator) // star_etc? - ) - { - D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+ star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+ star_etc?")); - } - { // star_etc - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_etc")); - StarEtc* a; - if ( - (a = star_etc_rule(p)) // star_etc - ) - { - D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_etc")); - _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_etc")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// slash_no_default: param_no_default+ '/' ',' | param_no_default+ '/' &')' -static asdl_seq* -slash_no_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // param_no_default+ '/' ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','")); - Token * _literal; - Token * _literal_1; - asdl_seq * a; - if ( - (a = _loop1_60_rule(p)) // param_no_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','")); - _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 slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default+ '/' ','")); - } - { // param_no_default+ '/' &')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'")); - Token * _literal; - asdl_seq * a; - if ( - (a = _loop1_61_rule(p)) // param_no_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' - ) - { - D(fprintf(stderr, "%*c+ slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'")); - _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 slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default+ '/' &')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// slash_with_default: -// | param_no_default* param_with_default+ '/' ',' -// | param_no_default* param_with_default+ '/' &')' -static SlashWithDefault* -slash_with_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - SlashWithDefault* _res = NULL; - int _mark = p->mark; - { // param_no_default* param_with_default+ '/' ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); - Token * _literal; - Token * _literal_1; - asdl_seq * a; - asdl_seq * b; - if ( - (a = _loop0_62_rule(p)) // param_no_default* - && - (b = _loop1_63_rule(p)) // param_with_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); - _res = _PyPegen_slash_with_default ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); - } - { // param_no_default* param_with_default+ '/' &')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); - Token * _literal; - asdl_seq * a; - asdl_seq * b; - if ( - (a = _loop0_64_rule(p)) // param_no_default* - && - (b = _loop1_65_rule(p)) // param_with_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' - ) - { - D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); - _res = _PyPegen_slash_with_default ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// star_etc: -// | '*' param_no_default param_maybe_default* kwds? -// | '*' ',' param_maybe_default+ kwds? -// | kwds -// | invalid_star_etc -static StarEtc* -star_etc_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - StarEtc* _res = NULL; - int _mark = p->mark; - { // '*' param_no_default param_maybe_default* kwds? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); - Token * _literal; - arg_ty a; - asdl_seq * b; - void *c; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = param_no_default_rule(p)) // param_no_default - && - (b = _loop0_66_rule(p)) // param_maybe_default* - && - (c = kwds_rule(p), !p->error_indicator) // kwds? - ) - { - D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); - _res = _PyPegen_star_etc ( p , a , 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 star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); - } - { // '*' ',' param_maybe_default+ kwds? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); - Token * _literal; - Token * _literal_1; - asdl_seq * b; - void *c; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - && - (b = _loop1_67_rule(p)) // param_maybe_default+ - && - (c = kwds_rule(p), !p->error_indicator) // kwds? - ) - { - D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); - _res = _PyPegen_star_etc ( p , NULL , 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 star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); - } - { // kwds - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwds")); - arg_ty a; - if ( - (a = kwds_rule(p)) // kwds - ) - { - D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwds")); - _res = _PyPegen_star_etc ( p , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwds")); - } - if (p->call_invalid_rules) { // invalid_star_etc - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); - void *invalid_star_etc_var; - if ( - (invalid_star_etc_var = invalid_star_etc_rule(p)) // invalid_star_etc - ) - { - D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); - _res = invalid_star_etc_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_star_etc")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// kwds: '**' param_no_default -static arg_ty -kwds_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arg_ty _res = NULL; - int _mark = p->mark; - { // '**' param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param_no_default")); - Token * _literal; - arg_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - && - (a = param_no_default_rule(p)) // param_no_default - ) - { - D(fprintf(stderr, "%*c+ kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param_no_default")); - _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 kwds[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param_no_default")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// param_no_default: param ',' TYPE_COMMENT? | param TYPE_COMMENT? &')' -static arg_ty -param_no_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arg_ty _res = NULL; - int _mark = p->mark; - { // param ',' TYPE_COMMENT? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param ',' TYPE_COMMENT?")); - Token * _literal; - arg_ty a; - void *tc; - if ( - (a = param_rule(p)) // param - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - ) - { - D(fprintf(stderr, "%*c+ param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param ',' TYPE_COMMENT?")); - _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s param_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param ',' TYPE_COMMENT?")); - } - { // param TYPE_COMMENT? &')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param TYPE_COMMENT? &')'")); - arg_ty a; - void *tc; - if ( - (a = param_rule(p)) // param - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' - ) - { - D(fprintf(stderr, "%*c+ param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param TYPE_COMMENT? &')'")); - _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s param_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param TYPE_COMMENT? &')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// param_with_default: param default ',' TYPE_COMMENT? | param default TYPE_COMMENT? &')' -static NameDefaultPair* -param_with_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - NameDefaultPair* _res = NULL; - int _mark = p->mark; - { // param default ',' TYPE_COMMENT? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default ',' TYPE_COMMENT?")); - Token * _literal; - arg_ty a; - expr_ty c; - void *tc; - if ( - (a = param_rule(p)) // param - && - (c = default_rule(p)) // default - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - ) - { - D(fprintf(stderr, "%*c+ param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default ',' TYPE_COMMENT?")); - _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s param_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default ',' TYPE_COMMENT?")); - } - { // param default TYPE_COMMENT? &')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default TYPE_COMMENT? &')'")); - arg_ty a; - expr_ty c; - void *tc; - if ( - (a = param_rule(p)) // param - && - (c = default_rule(p)) // default - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' - ) - { - D(fprintf(stderr, "%*c+ param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default TYPE_COMMENT? &')'")); - _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s param_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default TYPE_COMMENT? &')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// param_maybe_default: -// | param default? ',' TYPE_COMMENT? -// | param default? TYPE_COMMENT? &')' -static NameDefaultPair* -param_maybe_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - NameDefaultPair* _res = NULL; - int _mark = p->mark; - { // param default? ',' TYPE_COMMENT? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? ',' TYPE_COMMENT?")); - Token * _literal; - arg_ty a; - void *c; - void *tc; - if ( - (a = param_rule(p)) // param - && - (c = default_rule(p), !p->error_indicator) // default? - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - ) - { - D(fprintf(stderr, "%*c+ param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default? ',' TYPE_COMMENT?")); - _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default? ',' TYPE_COMMENT?")); - } - { // param default? TYPE_COMMENT? &')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? TYPE_COMMENT? &')'")); - arg_ty a; - void *c; - void *tc; - if ( - (a = param_rule(p)) // param - && - (c = default_rule(p), !p->error_indicator) // default? - && - (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' - ) - { - D(fprintf(stderr, "%*c+ param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default? TYPE_COMMENT? &')'")); - _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param default? TYPE_COMMENT? &')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// param: NAME annotation? -static arg_ty -param_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arg_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 - { // NAME annotation? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME annotation?")); - expr_ty a; - void *b; - if ( - (a = _PyPegen_name_token(p)) // NAME - && - (b = annotation_rule(p), !p->error_indicator) // annotation? - ) - { - D(fprintf(stderr, "%*c+ param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME annotation?")); - 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 = _Py_arg ( a -> v . Name . id , b , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s param[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME annotation?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// annotation: ':' expression -static expr_ty -annotation_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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> annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression")); - _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 annotation[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// default: '=' expression -static expr_ty -default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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> default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' expression")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' expression")); - _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 default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// decorators: (('@' named_expression NEWLINE))+ -static asdl_seq* -decorators_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // (('@' named_expression NEWLINE))+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> decorators[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); - asdl_seq * a; - if ( - (a = _loop1_68_rule(p)) // (('@' named_expression NEWLINE))+ - ) - { - D(fprintf(stderr, "%*c+ decorators[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); - _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 decorators[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(('@' named_expression NEWLINE))+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// class_def: decorators class_def_raw | class_def_raw -static stmt_ty -class_def_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - stmt_ty _res = NULL; - int _mark = p->mark; - { // decorators class_def_raw - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw")); - asdl_seq* a; - stmt_ty b; - if ( - (a = decorators_rule(p)) // decorators - && - (b = class_def_raw_rule(p)) // class_def_raw - ) - { - D(fprintf(stderr, "%*c+ class_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw")); - _res = _PyPegen_class_def_decorators ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s class_def[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "decorators class_def_raw")); - } - { // class_def_raw - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "class_def_raw")); - stmt_ty class_def_raw_var; - if ( - (class_def_raw_var = class_def_raw_rule(p)) // class_def_raw - ) - { - D(fprintf(stderr, "%*c+ class_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "class_def_raw")); - _res = class_def_raw_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s class_def[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "class_def_raw")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// class_def_raw: 'class' NAME ['(' arguments? ')'] ':' block -static stmt_ty -class_def_raw_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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 - { // 'class' NAME ['(' 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")); - Token * _keyword; - Token * _literal; - expr_ty a; - void *b; - asdl_seq* c; - if ( - (_keyword = _PyPegen_expect_token(p, 524)) // token='class' - && - (a = _PyPegen_name_token(p)) // NAME - && - (b = _tmp_69_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")); - 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 = _Py_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - 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")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// block: NEWLINE INDENT statements DEDENT | simple_stmt | invalid_block -static asdl_seq* -block_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - if (_PyPegen_is_memoized(p, block_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - { // NEWLINE INDENT statements DEDENT - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT")); - asdl_seq* a; - Token * dedent_var; - Token * indent_var; - Token * newline_var; - if ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - && - (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' - && - (a = statements_rule(p)) // statements - && - (dedent_var = _PyPegen_expect_token(p, DEDENT)) // token='DEDENT' - ) - { - D(fprintf(stderr, "%*c+ block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT")); - _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 block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT statements DEDENT")); - } - { // simple_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - asdl_seq* simple_stmt_var; - if ( - (simple_stmt_var = simple_stmt_rule(p)) // simple_stmt - ) - { - D(fprintf(stderr, "%*c+ block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - _res = simple_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt")); - } - if (p->call_invalid_rules) { // invalid_block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_block")); - void *invalid_block_var; - if ( - (invalid_block_var = invalid_block_rule(p)) // invalid_block - ) - { - D(fprintf(stderr, "%*c+ block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_block")); - _res = invalid_block_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_block")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, block_type, _res); - p->level--; - return _res; -} - -// star_expressions: -// | star_expression ((',' star_expression))+ ','? -// | star_expression ',' -// | star_expression -static expr_ty -star_expressions_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // star_expression ((',' star_expression))+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_expression))+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty a; - asdl_seq * b; - if ( - (a = star_expression_rule(p)) // star_expression - && - (b = _loop1_70_rule(p)) // ((',' star_expression))+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_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 = _Py_Tuple ( CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expression ((',' star_expression))+ ','?")); - } - { // star_expression ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ','")); - Token * _literal; - expr_ty a; - if ( - (a = star_expression_rule(p)) // star_expression - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_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 = _Py_Tuple ( CHECK ( _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expression ','")); - } - { // star_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression")); - expr_ty star_expression_var; - if ( - (star_expression_var = star_expression_rule(p)) // star_expression - ) - { - D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression")); - _res = star_expression_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// star_expression: '*' bitwise_or | expression -static expr_ty -star_expression_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, star_expression_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 - { // '*' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ star_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); - 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 = _Py_Starred ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' bitwise_or")); - } - { // expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); - expr_ty expression_var; - if ( - (expression_var = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ star_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); - _res = expression_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, star_expression_type, _res); - p->level--; - return _res; -} - -// star_named_expressions: ','.star_named_expression+ ','? -static asdl_seq* -star_named_expressions_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.star_named_expression+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_named_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - if ( - (a = _gather_71_rule(p)) // ','.star_named_expression+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ star_named_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?")); - _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 star_named_expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.star_named_expression+ ','?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// star_named_expression: '*' bitwise_or | named_expression -static expr_ty -star_named_expression_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '*' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ star_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); - 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 = _Py_Starred ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_named_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' bitwise_or")); - } - { // named_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_named_expression[%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+ star_named_expression[%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 star_named_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// named_expression: NAME ':=' ~ expression | expression !':=' | invalid_named_expression -static expr_ty -named_expression_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 ':=' ~ expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ expression")); - int _cut_var = 0; - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 53)) // token=':=' - && - (_cut_var = 1) - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ 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 = _Py_NamedExpr ( CHECK ( _PyPegen_set_expr_context ( p , a , Store ) ) , 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 named_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ':=' ~ expression")); - if (_cut_var) { - p->level--; - return NULL; - } - } - { // expression !':=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); - expr_ty expression_var; - if ( - (expression_var = expression_rule(p)) // expression - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' - ) - { - D(fprintf(stderr, "%*c+ named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); - _res = expression_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s named_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); - } - if (p->call_invalid_rules) { // invalid_named_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_named_expression")); - void *invalid_named_expression_var; - if ( - (invalid_named_expression_var = invalid_named_expression_rule(p)) // invalid_named_expression - ) - { - D(fprintf(stderr, "%*c+ named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_named_expression")); - _res = invalid_named_expression_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s named_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_named_expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// annotated_rhs: yield_expr | star_expressions -static expr_ty -annotated_rhs_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - int _mark = p->mark; - { // yield_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> annotated_rhs[%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+ annotated_rhs[%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 annotated_rhs[%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> annotated_rhs[%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+ annotated_rhs[%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 annotated_rhs[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); - } - _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(); - } - 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; - 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 - { // expression ((',' expression))+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ((',' expression))+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty a; - asdl_seq * b; - if ( - (a = expression_rule(p)) // expression - && - (b = _loop1_73_rule(p)) // ((',' expression))+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ((',' 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 = _Py_Tuple ( CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ((',' expression))+ ','?")); - } - { // expression ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ','")); - Token * _literal; - expr_ty a; - if ( - (a = expression_rule(p)) // expression - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "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 = _Py_Tuple ( CHECK ( _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ','")); - } - { // expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); - expr_ty expression_var; - if ( - (expression_var = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); - _res = expression_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s expressions[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// expression: disjunction 'if' disjunction 'else' expression | disjunction | lambdef -static expr_ty -expression_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, expression_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 - { // disjunction 'if' disjunction 'else' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); - Token * _keyword; - Token * _keyword_1; - expr_ty a; - expr_ty b; - expr_ty c; - if ( - (a = disjunction_rule(p)) // disjunction - && - (_keyword = _PyPegen_expect_token(p, 510)) // token='if' - && - (b = disjunction_rule(p)) // disjunction - && - (_keyword_1 = _PyPegen_expect_token(p, 516)) // token='else' - && - (c = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' 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 = _Py_IfExp ( b , a , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); - } - { // disjunction - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction")); - expr_ty disjunction_var; - if ( - (disjunction_var = disjunction_rule(p)) // disjunction - ) - { - D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction")); - _res = disjunction_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction")); - } - { // lambdef - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambdef")); - expr_ty lambdef_var; - if ( - (lambdef_var = lambdef_rule(p)) // lambdef - ) - { - D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambdef")); - _res = lambdef_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambdef")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, expression_type, _res); - p->level--; - return _res; -} - -// lambdef: 'lambda' lambda_params? ':' expression -static expr_ty -lambdef_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // 'lambda' lambda_params? ':' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambdef[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression")); - Token * _keyword; - Token * _literal; - void *a; - expr_ty b; - if ( - (_keyword = _PyPegen_expect_token(p, 525)) // token='lambda' - && - (a = lambda_params_rule(p), !p->error_indicator) // lambda_params? - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ lambdef[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_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 = _Py_Lambda ( ( a ) ? a : CHECK ( _PyPegen_empty_arguments ( p ) ) , 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 lambdef[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_params: invalid_lambda_parameters | lambda_parameters -static arguments_ty -lambda_params_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arguments_ty _res = NULL; - int _mark = p->mark; - if (p->call_invalid_rules) { // invalid_lambda_parameters - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters")); - void *invalid_lambda_parameters_var; - if ( - (invalid_lambda_parameters_var = invalid_lambda_parameters_rule(p)) // invalid_lambda_parameters - ) - { - D(fprintf(stderr, "%*c+ lambda_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters")); - _res = invalid_lambda_parameters_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_params[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_parameters")); - } - { // lambda_parameters - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_parameters")); - arguments_ty lambda_parameters_var; - if ( - (lambda_parameters_var = lambda_parameters_rule(p)) // lambda_parameters - ) - { - D(fprintf(stderr, "%*c+ lambda_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_parameters")); - _res = lambda_parameters_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_params[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_parameters")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_parameters: -// | lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc? -// | lambda_slash_with_default lambda_param_with_default* lambda_star_etc? -// | lambda_param_no_default+ lambda_param_with_default* lambda_star_etc? -// | lambda_param_with_default+ lambda_star_etc? -// | lambda_star_etc -static arguments_ty -lambda_parameters_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arguments_ty _res = NULL; - int _mark = p->mark; - { // lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - asdl_seq* a; - asdl_seq * b; - asdl_seq * c; - void *d; - if ( - (a = lambda_slash_no_default_rule(p)) // lambda_slash_no_default - && - (b = _loop0_74_rule(p)) // lambda_param_no_default* - && - (c = _loop0_75_rule(p)) // lambda_param_with_default* - && - (d = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? - ) - { - D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - } - { // lambda_slash_with_default lambda_param_with_default* lambda_star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); - SlashWithDefault* a; - asdl_seq * b; - void *c; - if ( - (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default - && - (b = _loop0_76_rule(p)) // lambda_param_with_default* - && - (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? - ) - { - D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , 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 lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); - } - { // lambda_param_no_default+ lambda_param_with_default* lambda_star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); - asdl_seq * a; - asdl_seq * b; - void *c; - if ( - (a = _loop1_77_rule(p)) // lambda_param_no_default+ - && - (b = _loop0_78_rule(p)) // lambda_param_with_default* - && - (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? - ) - { - D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , NULL , a , 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 lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); - } - { // lambda_param_with_default+ lambda_star_etc? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); - asdl_seq * a; - void *b; - if ( - (a = _loop1_79_rule(p)) // lambda_param_with_default+ - && - (b = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? - ) - { - D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); - } - { // lambda_star_etc - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_star_etc")); - StarEtc* a; - if ( - (a = lambda_star_etc_rule(p)) // lambda_star_etc - ) - { - D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_star_etc")); - _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_star_etc")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_slash_no_default: -// | lambda_param_no_default+ '/' ',' -// | lambda_param_no_default+ '/' &':' -static asdl_seq* -lambda_slash_no_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // lambda_param_no_default+ '/' ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','")); - Token * _literal; - Token * _literal_1; - asdl_seq * a; - if ( - (a = _loop1_80_rule(p)) // lambda_param_no_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ lambda_slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','")); - _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 lambda_slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default+ '/' ','")); - } - { // lambda_param_no_default+ '/' &':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'")); - Token * _literal; - asdl_seq * a; - if ( - (a = _loop1_81_rule(p)) // lambda_param_no_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' - ) - { - D(fprintf(stderr, "%*c+ lambda_slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'")); - _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 lambda_slash_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default+ '/' &':'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_slash_with_default: -// | lambda_param_no_default* lambda_param_with_default+ '/' ',' -// | lambda_param_no_default* lambda_param_with_default+ '/' &':' -static SlashWithDefault* -lambda_slash_with_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - SlashWithDefault* _res = NULL; - int _mark = p->mark; - { // lambda_param_no_default* lambda_param_with_default+ '/' ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); - Token * _literal; - Token * _literal_1; - asdl_seq * a; - asdl_seq * b; - if ( - (a = _loop0_82_rule(p)) // lambda_param_no_default* - && - (b = _loop1_83_rule(p)) // lambda_param_with_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); - _res = _PyPegen_slash_with_default ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); - } - { // lambda_param_no_default* lambda_param_with_default+ '/' &':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); - Token * _literal; - asdl_seq * a; - asdl_seq * b; - if ( - (a = _loop0_84_rule(p)) // lambda_param_no_default* - && - (b = _loop1_85_rule(p)) // lambda_param_with_default+ - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' - ) - { - D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); - _res = _PyPegen_slash_with_default ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_slash_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_star_etc: -// | '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? -// | '*' ',' lambda_param_maybe_default+ lambda_kwds? -// | lambda_kwds -// | invalid_lambda_star_etc -static StarEtc* -lambda_star_etc_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - StarEtc* _res = NULL; - int _mark = p->mark; - { // '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); - Token * _literal; - arg_ty a; - asdl_seq * b; - void *c; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = lambda_param_no_default_rule(p)) // lambda_param_no_default - && - (b = _loop0_86_rule(p)) // lambda_param_maybe_default* - && - (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); - _res = _PyPegen_star_etc ( p , a , 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 lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); - } - { // '*' ',' lambda_param_maybe_default+ lambda_kwds? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); - Token * _literal; - Token * _literal_1; - asdl_seq * b; - void *c; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - && - (b = _loop1_87_rule(p)) // lambda_param_maybe_default+ - && - (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); - _res = _PyPegen_star_etc ( p , NULL , 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 lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); - } - { // lambda_kwds - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); - arg_ty a; - if ( - (a = lambda_kwds_rule(p)) // lambda_kwds - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); - _res = _PyPegen_star_etc ( p , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_kwds")); - } - if (p->call_invalid_rules) { // invalid_lambda_star_etc - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); - void *invalid_lambda_star_etc_var; - if ( - (invalid_lambda_star_etc_var = invalid_lambda_star_etc_rule(p)) // invalid_lambda_star_etc - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); - _res = invalid_lambda_star_etc_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_star_etc")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_kwds: '**' lambda_param_no_default -static arg_ty -lambda_kwds_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arg_ty _res = NULL; - int _mark = p->mark; - { // '**' lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param_no_default")); - Token * _literal; - arg_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - && - (a = lambda_param_no_default_rule(p)) // lambda_param_no_default - ) - { - D(fprintf(stderr, "%*c+ lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param_no_default")); - _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 lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param_no_default")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_param_no_default: lambda_param ',' | lambda_param &':' -static arg_ty -lambda_param_no_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arg_ty _res = NULL; - int _mark = p->mark; - { // lambda_param ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param ','")); - Token * _literal; - arg_ty a; - if ( - (a = lambda_param_rule(p)) // lambda_param - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ lambda_param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_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 lambda_param_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param ','")); - } - { // lambda_param &':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param &':'")); - arg_ty a; - if ( - (a = lambda_param_rule(p)) // lambda_param - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' - ) - { - D(fprintf(stderr, "%*c+ lambda_param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_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 lambda_param_no_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param &':'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_param_with_default: lambda_param default ',' | lambda_param default &':' -static NameDefaultPair* -lambda_param_with_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - NameDefaultPair* _res = NULL; - int _mark = p->mark; - { // lambda_param default ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default ','")); - Token * _literal; - arg_ty a; - expr_ty c; - if ( - (a = lambda_param_rule(p)) // lambda_param - && - (c = default_rule(p)) // default - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ lambda_param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default ','")); - _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_param_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default ','")); - } - { // lambda_param default &':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default &':'")); - arg_ty a; - expr_ty c; - if ( - (a = lambda_param_rule(p)) // lambda_param - && - (c = default_rule(p)) // default - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' - ) - { - D(fprintf(stderr, "%*c+ lambda_param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default &':'")); - _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_param_with_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default &':'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_param_maybe_default: lambda_param default? ',' | lambda_param default? &':' -static NameDefaultPair* -lambda_param_maybe_default_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - NameDefaultPair* _res = NULL; - int _mark = p->mark; - { // lambda_param default? ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? ','")); - Token * _literal; - arg_ty a; - void *c; - if ( - (a = lambda_param_rule(p)) // lambda_param - && - (c = default_rule(p), !p->error_indicator) // default? - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ lambda_param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default? ','")); - _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default? ','")); - } - { // lambda_param default? &':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? &':'")); - arg_ty a; - void *c; - if ( - (a = lambda_param_rule(p)) // lambda_param - && - (c = default_rule(p), !p->error_indicator) // default? - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 11) // token=':' - ) - { - D(fprintf(stderr, "%*c+ lambda_param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default? &':'")); - _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_param_maybe_default[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param default? &':'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lambda_param: NAME -static arg_ty -lambda_param_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - arg_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 - { // NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); - expr_ty a; - if ( - (a = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ lambda_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 = _Py_arg ( a -> v . Name . id , NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_param[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// disjunction: conjunction (('or' conjunction))+ | conjunction -static expr_ty -disjunction_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, disjunction_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 - { // conjunction (('or' conjunction))+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); - expr_ty a; - asdl_seq * b; - if ( - (a = conjunction_rule(p)) // conjunction - && - (b = _loop1_88_rule(p)) // (('or' conjunction))+ - ) - { - D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); - 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 = _Py_BoolOp ( Or , CHECK ( _PyPegen_seq_insert_in_front ( p , a , 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 disjunction[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "conjunction (('or' conjunction))+")); - } - { // conjunction - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction")); - expr_ty conjunction_var; - if ( - (conjunction_var = conjunction_rule(p)) // conjunction - ) - { - D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction")); - _res = conjunction_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s disjunction[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "conjunction")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, disjunction_type, _res); - p->level--; - return _res; -} - -// conjunction: inversion (('and' inversion))+ | inversion -static expr_ty -conjunction_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, conjunction_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 - { // inversion (('and' inversion))+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); - expr_ty a; - asdl_seq * b; - if ( - (a = inversion_rule(p)) // inversion - && - (b = _loop1_89_rule(p)) // (('and' inversion))+ - ) - { - D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); - 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 = _Py_BoolOp ( And , CHECK ( _PyPegen_seq_insert_in_front ( p , a , 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 conjunction[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "inversion (('and' inversion))+")); - } - { // inversion - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion")); - expr_ty inversion_var; - if ( - (inversion_var = inversion_rule(p)) // inversion - ) - { - D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion")); - _res = inversion_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s conjunction[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "inversion")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, conjunction_type, _res); - p->level--; - return _res; -} - -// inversion: 'not' inversion | comparison -static expr_ty -inversion_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, inversion_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 - { // 'not' inversion - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' inversion")); - Token * _keyword; - expr_ty a; - if ( - (_keyword = _PyPegen_expect_token(p, 526)) // token='not' - && - (a = inversion_rule(p)) // inversion - ) - { - D(fprintf(stderr, "%*c+ inversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'not' inversion")); - 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 = _Py_UnaryOp ( Not , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s inversion[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'not' inversion")); - } - { // comparison - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "comparison")); - expr_ty comparison_var; - if ( - (comparison_var = comparison_rule(p)) // comparison - ) - { - D(fprintf(stderr, "%*c+ inversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "comparison")); - _res = comparison_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s inversion[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "comparison")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, inversion_type, _res); - p->level--; - return _res; -} - -// comparison: bitwise_or compare_op_bitwise_or_pair+ | bitwise_or -static expr_ty -comparison_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // bitwise_or compare_op_bitwise_or_pair+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); - expr_ty a; - asdl_seq * b; - if ( - (a = bitwise_or_rule(p)) // bitwise_or - && - (b = _loop1_90_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+")); - 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 = _Py_Compare ( a , CHECK ( _PyPegen_get_cmpops ( p , b ) ) , CHECK ( _PyPegen_get_exprs ( p , 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 comparison[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); - } - { // bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or")); - expr_ty bitwise_or_var; - if ( - (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or")); - _res = bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s comparison[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// compare_op_bitwise_or_pair: -// | eq_bitwise_or -// | noteq_bitwise_or -// | lte_bitwise_or -// | lt_bitwise_or -// | gte_bitwise_or -// | gt_bitwise_or -// | notin_bitwise_or -// | in_bitwise_or -// | isnot_bitwise_or -// | is_bitwise_or -static CmpopExprPair* -compare_op_bitwise_or_pair_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // eq_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "eq_bitwise_or")); - CmpopExprPair* eq_bitwise_or_var; - if ( - (eq_bitwise_or_var = eq_bitwise_or_rule(p)) // eq_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "eq_bitwise_or")); - _res = eq_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "eq_bitwise_or")); - } - { // noteq_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "noteq_bitwise_or")); - CmpopExprPair* noteq_bitwise_or_var; - if ( - (noteq_bitwise_or_var = noteq_bitwise_or_rule(p)) // noteq_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "noteq_bitwise_or")); - _res = noteq_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "noteq_bitwise_or")); - } - { // lte_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lte_bitwise_or")); - CmpopExprPair* lte_bitwise_or_var; - if ( - (lte_bitwise_or_var = lte_bitwise_or_rule(p)) // lte_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lte_bitwise_or")); - _res = lte_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lte_bitwise_or")); - } - { // lt_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lt_bitwise_or")); - CmpopExprPair* lt_bitwise_or_var; - if ( - (lt_bitwise_or_var = lt_bitwise_or_rule(p)) // lt_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lt_bitwise_or")); - _res = lt_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lt_bitwise_or")); - } - { // gte_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gte_bitwise_or")); - CmpopExprPair* gte_bitwise_or_var; - if ( - (gte_bitwise_or_var = gte_bitwise_or_rule(p)) // gte_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "gte_bitwise_or")); - _res = gte_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "gte_bitwise_or")); - } - { // gt_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gt_bitwise_or")); - CmpopExprPair* gt_bitwise_or_var; - if ( - (gt_bitwise_or_var = gt_bitwise_or_rule(p)) // gt_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "gt_bitwise_or")); - _res = gt_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "gt_bitwise_or")); - } - { // notin_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "notin_bitwise_or")); - CmpopExprPair* notin_bitwise_or_var; - if ( - (notin_bitwise_or_var = notin_bitwise_or_rule(p)) // notin_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "notin_bitwise_or")); - _res = notin_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "notin_bitwise_or")); - } - { // in_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "in_bitwise_or")); - CmpopExprPair* in_bitwise_or_var; - if ( - (in_bitwise_or_var = in_bitwise_or_rule(p)) // in_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "in_bitwise_or")); - _res = in_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "in_bitwise_or")); - } - { // isnot_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "isnot_bitwise_or")); - CmpopExprPair* isnot_bitwise_or_var; - if ( - (isnot_bitwise_or_var = isnot_bitwise_or_rule(p)) // isnot_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "isnot_bitwise_or")); - _res = isnot_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "isnot_bitwise_or")); - } - { // is_bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "is_bitwise_or")); - CmpopExprPair* is_bitwise_or_var; - if ( - (is_bitwise_or_var = is_bitwise_or_rule(p)) // is_bitwise_or - ) - { - D(fprintf(stderr, "%*c+ compare_op_bitwise_or_pair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "is_bitwise_or")); - _res = is_bitwise_or_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s compare_op_bitwise_or_pair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "is_bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// eq_bitwise_or: '==' bitwise_or -static CmpopExprPair* -eq_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // '==' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> eq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'==' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 27)) // token='==' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ eq_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'==' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , Eq , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s eq_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'==' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// noteq_bitwise_or: ('!=') bitwise_or -static CmpopExprPair* -noteq_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // ('!=') bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); - void *_tmp_91_var; - expr_ty a; - if ( - (_tmp_91_var = _tmp_91_rule(p)) // '!=' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ noteq_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , NotEq , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s noteq_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('!=') bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lte_bitwise_or: '<=' bitwise_or -static CmpopExprPair* -lte_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // '<=' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<=' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 29)) // token='<=' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ lte_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<=' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , LtE , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lte_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'<=' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// lt_bitwise_or: '<' bitwise_or -static CmpopExprPair* -lt_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // '<' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 20)) // token='<' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ lt_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , Lt , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lt_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'<' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// gte_bitwise_or: '>=' bitwise_or -static CmpopExprPair* -gte_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // '>=' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> gte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>=' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 30)) // token='>=' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ gte_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>=' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , GtE , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s gte_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'>=' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// gt_bitwise_or: '>' bitwise_or -static CmpopExprPair* -gt_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // '>' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> gt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 21)) // token='>' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ gt_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , Gt , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s gt_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'>' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// notin_bitwise_or: 'not' 'in' bitwise_or -static CmpopExprPair* -notin_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // 'not' 'in' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> notin_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' 'in' bitwise_or")); - Token * _keyword; - Token * _keyword_1; - expr_ty a; - if ( - (_keyword = _PyPegen_expect_token(p, 526)) // token='not' - && - (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ notin_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'not' 'in' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , NotIn , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s notin_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'not' 'in' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// in_bitwise_or: 'in' bitwise_or -static CmpopExprPair* -in_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // 'in' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> in_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'in' bitwise_or")); - Token * _keyword; - expr_ty a; - if ( - (_keyword = _PyPegen_expect_token(p, 518)) // token='in' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ in_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'in' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , In , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s in_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'in' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// isnot_bitwise_or: 'is' 'not' bitwise_or -static CmpopExprPair* -isnot_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // 'is' 'not' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> isnot_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' 'not' bitwise_or")); - Token * _keyword; - Token * _keyword_1; - expr_ty a; - if ( - (_keyword = _PyPegen_expect_token(p, 527)) // token='is' - && - (_keyword_1 = _PyPegen_expect_token(p, 526)) // token='not' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ isnot_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'is' 'not' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , IsNot , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s isnot_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'is' 'not' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// is_bitwise_or: 'is' bitwise_or -static CmpopExprPair* -is_bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - CmpopExprPair* _res = NULL; - int _mark = p->mark; - { // 'is' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> is_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' bitwise_or")); - Token * _keyword; - expr_ty a; - if ( - (_keyword = _PyPegen_expect_token(p, 527)) // token='is' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ is_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'is' bitwise_or")); - _res = _PyPegen_cmpop_expr_pair ( p , Is , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s is_bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'is' bitwise_or")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// bitwise_or: bitwise_or '|' bitwise_xor | bitwise_xor -static expr_ty bitwise_or_raw(Parser *); -static expr_ty -bitwise_or_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, bitwise_or_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_1 = _PyPegen_update_memo(p, _mark, bitwise_or_type, _res); - if (tmpvar_1) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = bitwise_or_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -bitwise_or_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // bitwise_or '|' bitwise_xor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = bitwise_or_rule(p)) // bitwise_or - && - (_literal = _PyPegen_expect_token(p, 18)) // token='|' - && - (b = bitwise_xor_rule(p)) // bitwise_xor - ) - { - D(fprintf(stderr, "%*c+ bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor")); - 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 = _Py_BinOp ( a , BitOr , 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 bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_or '|' bitwise_xor")); - } - { // bitwise_xor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor")); - expr_ty bitwise_xor_var; - if ( - (bitwise_xor_var = bitwise_xor_rule(p)) // bitwise_xor - ) - { - D(fprintf(stderr, "%*c+ bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_xor")); - _res = bitwise_xor_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s bitwise_or[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_xor")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// bitwise_xor: bitwise_xor '^' bitwise_and | bitwise_and -static expr_ty bitwise_xor_raw(Parser *); -static expr_ty -bitwise_xor_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, bitwise_xor_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_2 = _PyPegen_update_memo(p, _mark, bitwise_xor_type, _res); - if (tmpvar_2) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = bitwise_xor_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -bitwise_xor_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // bitwise_xor '^' bitwise_and - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = bitwise_xor_rule(p)) // bitwise_xor - && - (_literal = _PyPegen_expect_token(p, 32)) // token='^' - && - (b = bitwise_and_rule(p)) // bitwise_and - ) - { - D(fprintf(stderr, "%*c+ bitwise_xor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and")); - 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 = _Py_BinOp ( a , BitXor , 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 bitwise_xor[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_xor '^' bitwise_and")); - } - { // bitwise_and - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and")); - expr_ty bitwise_and_var; - if ( - (bitwise_and_var = bitwise_and_rule(p)) // bitwise_and - ) - { - D(fprintf(stderr, "%*c+ bitwise_xor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_and")); - _res = bitwise_and_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s bitwise_xor[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_and")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// bitwise_and: bitwise_and '&' shift_expr | shift_expr -static expr_ty bitwise_and_raw(Parser *); -static expr_ty -bitwise_and_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, bitwise_and_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_3 = _PyPegen_update_memo(p, _mark, bitwise_and_type, _res); - if (tmpvar_3) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = bitwise_and_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -bitwise_and_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // bitwise_and '&' shift_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = bitwise_and_rule(p)) // bitwise_and - && - (_literal = _PyPegen_expect_token(p, 19)) // token='&' - && - (b = shift_expr_rule(p)) // shift_expr - ) - { - D(fprintf(stderr, "%*c+ bitwise_and[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr")); - 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 = _Py_BinOp ( a , BitAnd , 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 bitwise_and[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "bitwise_and '&' shift_expr")); - } - { // shift_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr")); - expr_ty shift_expr_var; - if ( - (shift_expr_var = shift_expr_rule(p)) // shift_expr - ) - { - D(fprintf(stderr, "%*c+ bitwise_and[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr")); - _res = shift_expr_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s bitwise_and[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "shift_expr")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// shift_expr: shift_expr '<<' sum | shift_expr '>>' sum | sum -static expr_ty shift_expr_raw(Parser *); -static expr_ty -shift_expr_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, shift_expr_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_4 = _PyPegen_update_memo(p, _mark, shift_expr_type, _res); - if (tmpvar_4) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = shift_expr_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -shift_expr_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // shift_expr '<<' sum - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = shift_expr_rule(p)) // shift_expr - && - (_literal = _PyPegen_expect_token(p, 33)) // token='<<' - && - (b = sum_rule(p)) // sum - ) - { - D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum")); - 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 = _Py_BinOp ( a , LShift , 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 shift_expr[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "shift_expr '<<' sum")); - } - { // shift_expr '>>' sum - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = shift_expr_rule(p)) // shift_expr - && - (_literal = _PyPegen_expect_token(p, 34)) // token='>>' - && - (b = sum_rule(p)) // sum - ) - { - D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum")); - 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 = _Py_BinOp ( a , RShift , 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 shift_expr[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "shift_expr '>>' sum")); - } - { // sum - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum")); - expr_ty sum_var; - if ( - (sum_var = sum_rule(p)) // sum - ) - { - D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum")); - _res = sum_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s shift_expr[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "sum")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// sum: sum '+' term | sum '-' term | term -static expr_ty sum_raw(Parser *); -static expr_ty -sum_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, sum_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_5 = _PyPegen_update_memo(p, _mark, sum_type, _res); - if (tmpvar_5) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = sum_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -sum_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // sum '+' term - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '+' term")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = sum_rule(p)) // sum - && - (_literal = _PyPegen_expect_token(p, 14)) // token='+' - && - (b = term_rule(p)) // term - ) - { - D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '+' term")); - 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 = _Py_BinOp ( a , Add , 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 sum[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "sum '+' term")); - } - { // sum '-' term - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '-' term")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = sum_rule(p)) // sum - && - (_literal = _PyPegen_expect_token(p, 15)) // token='-' - && - (b = term_rule(p)) // term - ) - { - D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '-' term")); - 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 = _Py_BinOp ( a , Sub , 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 sum[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "sum '-' term")); - } - { // term - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term")); - expr_ty term_var; - if ( - (term_var = term_rule(p)) // term - ) - { - D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term")); - _res = term_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s sum[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// term: -// | term '*' factor -// | term '/' factor -// | term '//' factor -// | term '%' factor -// | term '@' factor -// | factor -static expr_ty term_raw(Parser *); -static expr_ty -term_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, term_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_6 = _PyPegen_update_memo(p, _mark, term_type, _res); - if (tmpvar_6) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = term_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -term_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // term '*' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '*' factor")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = term_rule(p)) // term - && - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (b = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '*' factor")); - 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 = _Py_BinOp ( a , Mult , 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 term[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '*' factor")); - } - { // term '/' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '/' factor")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = term_rule(p)) // term - && - (_literal = _PyPegen_expect_token(p, 17)) // token='/' - && - (b = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '/' factor")); - 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 = _Py_BinOp ( a , Div , 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 term[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '/' factor")); - } - { // term '//' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '//' factor")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = term_rule(p)) // term - && - (_literal = _PyPegen_expect_token(p, 47)) // token='//' - && - (b = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '//' factor")); - 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 = _Py_BinOp ( a , FloorDiv , 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 term[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '//' factor")); - } - { // term '%' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '%' factor")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = term_rule(p)) // term - && - (_literal = _PyPegen_expect_token(p, 24)) // token='%' - && - (b = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '%' factor")); - 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 = _Py_BinOp ( a , Mod , 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 term[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '%' factor")); - } - { // term '@' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '@' factor")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = term_rule(p)) // term - && - (_literal = _PyPegen_expect_token(p, 49)) // token='@' - && - (b = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '@' factor")); - 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 ( 5 , "The '@' operator is" , _Py_BinOp ( a , MatMult , 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 term[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "term '@' factor")); - } - { // factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "factor")); - expr_ty factor_var; - if ( - (factor_var = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "factor")); - _res = factor_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s term[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "factor")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// factor: '+' factor | '-' factor | '~' factor | power -static expr_ty -factor_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, factor_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 - { // '+' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+' factor")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 14)) // token='+' - && - (a = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+' factor")); - 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 = _Py_UnaryOp ( UAdd , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+' factor")); - } - { // '-' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' factor")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 15)) // token='-' - && - (a = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' factor")); - 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 = _Py_UnaryOp ( USub , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-' factor")); - } - { // '~' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'~' factor")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 31)) // token='~' - && - (a = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'~' factor")); - 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 = _Py_UnaryOp ( Invert , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'~' factor")); - } - { // power - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "power")); - expr_ty power_var; - if ( - (power_var = power_rule(p)) // power - ) - { - D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "power")); - _res = power_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s factor[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "power")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, factor_type, _res); - p->level--; - return _res; -} - -// power: await_primary '**' factor | await_primary -static expr_ty -power_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // await_primary '**' factor - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = await_primary_rule(p)) // await_primary - && - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - && - (b = factor_rule(p)) // factor - ) - { - D(fprintf(stderr, "%*c+ power[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor")); - 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 = _Py_BinOp ( a , Pow , 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 power[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "await_primary '**' factor")); - } - { // await_primary - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary")); - expr_ty await_primary_var; - if ( - (await_primary_var = await_primary_rule(p)) // await_primary - ) - { - D(fprintf(stderr, "%*c+ power[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "await_primary")); - _res = await_primary_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s power[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "await_primary")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// await_primary: AWAIT primary | primary -static expr_ty -await_primary_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, await_primary_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 - { // AWAIT primary - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); - expr_ty a; - Token * await_var; - if ( - (await_var = _PyPegen_expect_token(p, AWAIT)) // token='AWAIT' - && - (a = primary_rule(p)) // primary - ) - { - D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); - 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 ( 5 , "Await expressions are" , _Py_Await ( a , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s await_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "AWAIT primary")); - } - { // primary - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary")); - expr_ty primary_var; - if ( - (primary_var = primary_rule(p)) // primary - ) - { - D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary")); - _res = primary_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s await_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, await_primary_type, _res); - p->level--; - return _res; -} - -// Left-recursive -// primary: -// | invalid_primary -// | primary '.' NAME -// | primary genexp -// | primary '(' arguments? ')' -// | primary '[' slices ']' -// | atom -static expr_ty primary_raw(Parser *); -static expr_ty -primary_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, primary_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_7 = _PyPegen_update_memo(p, _mark, primary_type, _res); - if (tmpvar_7) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = primary_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -primary_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - if (p->call_invalid_rules) { // invalid_primary - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_primary")); - void *invalid_primary_var; - if ( - (invalid_primary_var = invalid_primary_rule(p)) // invalid_primary - ) - { - D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_primary")); - _res = invalid_primary_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_primary")); - } - { // primary '.' NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '.' NAME")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = primary_rule(p)) // primary - && - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - && - (b = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '.' 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 = _Py_Attribute ( a , b -> v . Name . id , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary '.' NAME")); - } - { // primary genexp - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary genexp")); - expr_ty a; - expr_ty b; - if ( - (a = primary_rule(p)) // primary - && - (b = genexp_rule(p)) // genexp - ) - { - D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary genexp")); - 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 = _Py_Call ( a , CHECK ( _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary genexp")); - } - { // primary '(' arguments? ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'")); - Token * _literal; - Token * _literal_1; - expr_ty a; - void *b; - if ( - (a = primary_rule(p)) // primary - && - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (b = arguments_rule(p), !p->error_indicator) // arguments? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'")); - 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 = _Py_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary '(' arguments? ')'")); - } - { // primary '[' slices ']' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'")); - Token * _literal; - Token * _literal_1; - expr_ty a; - expr_ty b; - if ( - (a = primary_rule(p)) // primary - && - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (b = slices_rule(p)) // slices - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - ) - { - D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'")); - 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 = _Py_Subscript ( a , b , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary '[' slices ']'")); - } - { // atom - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom")); - expr_ty atom_var; - if ( - (atom_var = atom_rule(p)) // atom - ) - { - D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "atom")); - _res = atom_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "atom")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// slices: slice !',' | ','.slice+ ','? -static expr_ty -slices_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // slice !',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice !','")); - expr_ty a; - if ( - (a = slice_rule(p)) // slice - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 12) // token=',' - ) - { - D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice !','")); - _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 slices[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice !','")); - } - { // ','.slice+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - if ( - (a = _gather_92_rule(p)) // ','.slice+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); - 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 = _Py_Tuple ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s slices[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.slice+ ','?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// slice: expression? ':' expression? [':' expression?] | expression -static expr_ty -slice_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // expression? ':' expression? [':' expression?] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]")); - Token * _literal; - void *a; - void *b; - void *c; - if ( - (a = expression_rule(p), !p->error_indicator) // expression? - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = expression_rule(p), !p->error_indicator) // expression? - && - (c = _tmp_94_rule(p), !p->error_indicator) // [':' expression?] - ) - { - D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' 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 = _Py_Slice ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s slice[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression? ':' expression? [':' expression?]")); - } - { // expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); - expr_ty a; - if ( - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); - _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 slice[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// atom: -// | NAME -// | 'True' -// | 'False' -// | 'None' -// | '__peg_parser__' -// | &STRING strings -// | NUMBER -// | &'(' (tuple | group | genexp) -// | &'[' (list | listcomp) -// | &'{' (dict | set | dictcomp | setcomp) -// | '...' -static expr_ty -atom_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); - expr_ty name_var; - if ( - (name_var = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); - _res = name_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, "NAME")); - } - { // 'True' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 528)) // token='True' - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); - 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 = _Py_Constant ( Py_True , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "'True'")); - } - { // 'False' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 529)) // token='False' - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); - 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 = _Py_Constant ( Py_False , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "'False'")); - } - { // 'None' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 530)) // token='None' - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); - 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 = _Py_Constant ( Py_None , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "'None'")); - } - { // '__peg_parser__' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'__peg_parser__'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 531)) // token='__peg_parser__' - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'__peg_parser__'")); - _res = RAISE_SYNTAX_ERROR ( "You found it!" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "'__peg_parser__'")); - } - { // &STRING 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")); - expr_ty strings_var; - if ( - _PyPegen_lookahead(1, _PyPegen_string_token, p) - && - (strings_var = strings_rule(p)) // strings - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&STRING 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")); - } - { // NUMBER - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); - expr_ty number_var; - if ( - (number_var = _PyPegen_number_token(p)) // NUMBER - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NUMBER")); - _res = number_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, "NUMBER")); - } - { // &'(' (tuple | group | genexp) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - void *_tmp_95_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 7) // token='(' - && - (_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_95_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, "&'(' (tuple | group | genexp)")); - } - { // &'[' (list | listcomp) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - void *_tmp_96_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 9) // token='[' - && - (_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_96_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, "&'[' (list | listcomp)")); - } - { // &'{' (dict | set | dictcomp | setcomp) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - void *_tmp_97_var; - if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 25) // token='{' - && - (_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_97_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, "&'{' (dict | set | dictcomp | setcomp)")); - } - { // '...' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 52)) // token='...' - ) - { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); - 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 = _Py_Constant ( Py_Ellipsis , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "'...'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// strings: STRING+ -static expr_ty -strings_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, strings_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - { // 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; - if ( - (a = _loop1_98_rule(p)) // STRING+ - ) - { - D(fprintf(stderr, "%*c+ strings[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING+")); - _res = _PyPegen_concatenate_strings ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s strings[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING+")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, strings_type, _res); - p->level--; - return _res; -} - -// list: '[' star_named_expressions? ']' -static expr_ty -list_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '[' star_named_expressions? ']' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> list[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (a = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - ) - { - D(fprintf(stderr, "%*c+ list[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'")); - 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 = _Py_List ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s list[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' star_named_expressions? ']'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// listcomp: '[' named_expression ~ for_if_clauses ']' | invalid_comprehension -static expr_ty -listcomp_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '[' named_expression ~ for_if_clauses ']' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' named_expression ~ for_if_clauses ']'")); - int _cut_var = 0; - Token * _literal; - Token * _literal_1; - expr_ty a; - asdl_seq* b; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (a = named_expression_rule(p)) // named_expression - && - (_cut_var = 1) - && - (b = for_if_clauses_rule(p)) // for_if_clauses - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - ) - { - D(fprintf(stderr, "%*c+ listcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' named_expression ~ for_if_clauses ']'")); - 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 = _Py_ListComp ( a , 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 listcomp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' named_expression ~ for_if_clauses ']'")); - if (_cut_var) { - p->level--; - return NULL; - } - } - if (p->call_invalid_rules) { // invalid_comprehension - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); - void *invalid_comprehension_var; - if ( - (invalid_comprehension_var = invalid_comprehension_rule(p)) // invalid_comprehension - ) - { - D(fprintf(stderr, "%*c+ listcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); - _res = invalid_comprehension_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s listcomp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_comprehension")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// tuple: '(' [star_named_expression ',' star_named_expressions?] ')' -static expr_ty -tuple_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '(' [star_named_expression ',' star_named_expressions?] ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> tuple[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = _tmp_99_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ tuple[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); - 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 = _Py_Tuple ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s tuple[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// group: '(' (yield_expr | named_expression) ')' | invalid_group -static expr_ty -group_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - int _mark = p->mark; - { // '(' (yield_expr | named_expression) ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = _tmp_100_rule(p)) // yield_expr | named_expression - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); - _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 group[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); - } - if (p->call_invalid_rules) { // invalid_group - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_group")); - void *invalid_group_var; - if ( - (invalid_group_var = invalid_group_rule(p)) // invalid_group - ) - { - D(fprintf(stderr, "%*c+ group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_group")); - _res = invalid_group_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s group[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_group")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// genexp: '(' named_expression ~ for_if_clauses ')' | invalid_comprehension -static expr_ty -genexp_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '(' named_expression ~ for_if_clauses ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'")); - int _cut_var = 0; - Token * _literal; - Token * _literal_1; - expr_ty a; - asdl_seq* b; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = named_expression_rule(p)) // named_expression - && - (_cut_var = 1) - && - (b = for_if_clauses_rule(p)) // for_if_clauses - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'")); - 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 = _Py_GeneratorExp ( a , 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 genexp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'")); - if (_cut_var) { - p->level--; - return NULL; - } - } - if (p->call_invalid_rules) { // invalid_comprehension - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); - void *invalid_comprehension_var; - if ( - (invalid_comprehension_var = invalid_comprehension_rule(p)) // invalid_comprehension - ) - { - D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); - _res = invalid_comprehension_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s genexp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_comprehension")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// set: '{' star_named_expressions '}' -static expr_ty -set_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '{' star_named_expressions '}' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> set[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'")); - Token * _literal; - Token * _literal_1; - asdl_seq* a; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - && - (a = star_named_expressions_rule(p)) // star_named_expressions - && - (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' - ) - { - D(fprintf(stderr, "%*c+ set[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'")); - 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 = _Py_Set ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s set[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' star_named_expressions '}'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// setcomp: '{' named_expression ~ for_if_clauses '}' | invalid_comprehension -static expr_ty -setcomp_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '{' named_expression ~ for_if_clauses '}' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' named_expression ~ for_if_clauses '}'")); - int _cut_var = 0; - Token * _literal; - Token * _literal_1; - expr_ty a; - asdl_seq* b; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - && - (a = named_expression_rule(p)) // named_expression - && - (_cut_var = 1) - && - (b = for_if_clauses_rule(p)) // for_if_clauses - && - (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' - ) - { - D(fprintf(stderr, "%*c+ setcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' named_expression ~ for_if_clauses '}'")); - 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 = _Py_SetComp ( a , 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 setcomp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' named_expression ~ for_if_clauses '}'")); - if (_cut_var) { - p->level--; - return NULL; - } - } - if (p->call_invalid_rules) { // invalid_comprehension - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); - void *invalid_comprehension_var; - if ( - (invalid_comprehension_var = invalid_comprehension_rule(p)) // invalid_comprehension - ) - { - D(fprintf(stderr, "%*c+ setcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); - _res = invalid_comprehension_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s setcomp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_comprehension")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// dict: '{' double_starred_kvpairs? '}' -static expr_ty -dict_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '{' double_starred_kvpairs? '}' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> dict[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - && - (a = double_starred_kvpairs_rule(p), !p->error_indicator) // double_starred_kvpairs? - && - (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' - ) - { - D(fprintf(stderr, "%*c+ dict[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'")); - 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 = _Py_Dict ( CHECK ( _PyPegen_get_keys ( p , a ) ) , CHECK ( _PyPegen_get_values ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s dict[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' double_starred_kvpairs? '}'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// dictcomp: '{' kvpair for_if_clauses '}' | invalid_dict_comprehension -static expr_ty -dictcomp_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '{' kvpair for_if_clauses '}' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'")); - Token * _literal; - Token * _literal_1; - KeyValuePair* a; - asdl_seq* b; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - && - (a = kvpair_rule(p)) // kvpair - && - (b = for_if_clauses_rule(p)) // for_if_clauses - && - (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' - ) - { - D(fprintf(stderr, "%*c+ dictcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'")); - 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 = _Py_DictComp ( a -> key , a -> value , 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 dictcomp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' kvpair for_if_clauses '}'")); - } - if (p->call_invalid_rules) { // invalid_dict_comprehension - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_dict_comprehension")); - void *invalid_dict_comprehension_var; - if ( - (invalid_dict_comprehension_var = invalid_dict_comprehension_rule(p)) // invalid_dict_comprehension - ) - { - D(fprintf(stderr, "%*c+ dictcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_dict_comprehension")); - _res = invalid_dict_comprehension_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s dictcomp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_dict_comprehension")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// double_starred_kvpairs: ','.double_starred_kvpair+ ','? -static asdl_seq* -double_starred_kvpairs_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.double_starred_kvpair+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - if ( - (a = _gather_101_rule(p)) // ','.double_starred_kvpair+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ','?")); - _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 double_starred_kvpairs[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.double_starred_kvpair+ ','?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// double_starred_kvpair: '**' bitwise_or | kvpair -static KeyValuePair* -double_starred_kvpair_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - KeyValuePair* _res = NULL; - int _mark = p->mark; - { // '**' bitwise_or - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - && - (a = bitwise_or_rule(p)) // bitwise_or - ) - { - D(fprintf(stderr, "%*c+ double_starred_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or")); - _res = _PyPegen_key_value_pair ( p , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s double_starred_kvpair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' bitwise_or")); - } - { // kvpair - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kvpair")); - KeyValuePair* kvpair_var; - if ( - (kvpair_var = kvpair_rule(p)) // kvpair - ) - { - D(fprintf(stderr, "%*c+ double_starred_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kvpair")); - _res = kvpair_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s double_starred_kvpair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kvpair")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// kvpair: expression ':' expression -static KeyValuePair* -kvpair_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - KeyValuePair* _res = NULL; - int _mark = p->mark; - { // expression ':' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = expression_rule(p)) // expression - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); - _res = _PyPegen_key_value_pair ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kvpair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// for_if_clauses: for_if_clause+ -static asdl_seq* -for_if_clauses_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // for_if_clause+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> for_if_clauses[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); - asdl_seq * _loop1_103_var; - if ( - (_loop1_103_var = _loop1_103_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+")); - _res = _loop1_103_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s for_if_clauses[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// for_if_clause: -// | ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))* -// | 'for' star_targets 'in' ~ disjunction (('if' disjunction))* -// | invalid_for_target -static comprehension_ty -for_if_clause_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - comprehension_ty _res = NULL; - int _mark = p->mark; - { // ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))* - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); - int _cut_var = 0; - Token * _keyword; - Token * _keyword_1; - expr_ty a; - Token * async_var; - expr_ty b; - asdl_seq * c; - if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' - && - (_keyword = _PyPegen_expect_token(p, 517)) // token='for' - && - (a = star_targets_rule(p)) // star_targets - && - (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' - && - (_cut_var = 1) - && - (b = disjunction_rule(p)) // disjunction - && - (c = _loop0_104_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))*")); - _res = CHECK_VERSION ( 6 , "Async comprehensions are" , _Py_comprehension ( a , b , c , 1 , p -> arena ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); - if (_cut_var) { - p->level--; - return NULL; - } - } - { // 'for' star_targets 'in' ~ disjunction (('if' disjunction))* - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); - int _cut_var = 0; - Token * _keyword; - Token * _keyword_1; - expr_ty a; - expr_ty b; - asdl_seq * c; - if ( - (_keyword = _PyPegen_expect_token(p, 517)) // token='for' - && - (a = star_targets_rule(p)) // star_targets - && - (_keyword_1 = _PyPegen_expect_token(p, 518)) // token='in' - && - (_cut_var = 1) - && - (b = disjunction_rule(p)) // disjunction - && - (c = _loop0_105_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))*")); - _res = _Py_comprehension ( a , b , c , 0 , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); - if (_cut_var) { - p->level--; - return NULL; - } - } - if (p->call_invalid_rules) { // invalid_for_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); - void *invalid_for_target_var; - if ( - (invalid_for_target_var = invalid_for_target_rule(p)) // invalid_for_target - ) - { - D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); - _res = invalid_for_target_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_for_target")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// yield_expr: 'yield' 'from' expression | 'yield' star_expressions? -static expr_ty -yield_expr_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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' 'from' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' 'from' expression")); - Token * _keyword; - Token * _keyword_1; - expr_ty a; - if ( - (_keyword = _PyPegen_expect_token(p, 504)) // token='yield' - && - (_keyword_1 = _PyPegen_expect_token(p, 514)) // token='from' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' 'from' 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 = _Py_YieldFrom ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s yield_expr[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'yield' 'from' expression")); - } - { // 'yield' star_expressions? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?")); - Token * _keyword; - void *a; - if ( - (_keyword = _PyPegen_expect_token(p, 504)) // token='yield' - && - (a = star_expressions_rule(p), !p->error_indicator) // star_expressions? - ) - { - D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?")); - 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 = _Py_Yield ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s yield_expr[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'yield' star_expressions?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// arguments: args ','? &')' | invalid_arguments -static expr_ty -arguments_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, arguments_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - { // args ','? &')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','? &')'")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty a; - if ( - (a = args_rule(p)) // args - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - && - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' - ) - { - D(fprintf(stderr, "%*c+ arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','? &')'")); - _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 arguments[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ','? &')'")); - } - if (p->call_invalid_rules) { // invalid_arguments - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_arguments")); - void *invalid_arguments_var; - if ( - (invalid_arguments_var = invalid_arguments_rule(p)) // invalid_arguments - ) - { - D(fprintf(stderr, "%*c+ arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_arguments")); - _res = invalid_arguments_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s arguments[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_arguments")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, arguments_type, _res); - p->level--; - return _res; -} - -// args: ','.(starred_expression | named_expression !'=')+ [',' kwargs] | kwargs -static expr_ty -args_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // ','.(starred_expression | named_expression !'=')+ [',' kwargs] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); - asdl_seq * a; - void *b; - if ( - (a = _gather_106_rule(p)) // ','.(starred_expression | named_expression !'=')+ - && - (b = _tmp_108_rule(p), !p->error_indicator) // [',' kwargs] - ) - { - D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); - 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_collect_call_seqs ( p , a , 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 args[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); - } - { // kwargs - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwargs")); - asdl_seq* a; - if ( - (a = kwargs_rule(p)) // kwargs - ) - { - D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwargs")); - 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 = _Py_Call ( _PyPegen_dummy_name ( p ) , CHECK_NULL_ALLOWED ( _PyPegen_seq_extract_starred_exprs ( p , a ) ) , CHECK_NULL_ALLOWED ( _PyPegen_seq_delete_starred_exprs ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s args[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwargs")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// kwargs: -// | ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+ -// | ','.kwarg_or_starred+ -// | ','.kwarg_or_double_starred+ -static asdl_seq* -kwargs_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); - Token * _literal; - asdl_seq * a; - asdl_seq * b; - if ( - (a = _gather_109_rule(p)) // ','.kwarg_or_starred+ - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (b = _gather_111_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+")); - _res = _PyPegen_join_sequences ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwargs[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); - } - { // ','.kwarg_or_starred+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - asdl_seq * _gather_113_var; - if ( - (_gather_113_var = _gather_113_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_113_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwargs[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.kwarg_or_starred+")); - } - { // ','.kwarg_or_double_starred+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - asdl_seq * _gather_115_var; - if ( - (_gather_115_var = _gather_115_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_115_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwargs[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.kwarg_or_double_starred+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// starred_expression: '*' expression -static expr_ty -starred_expression_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // '*' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' 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 = _Py_Starred ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "'*' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// kwarg_or_starred: NAME '=' expression | starred_expression | invalid_kwarg -static KeywordOrStarred* -kwarg_or_starred_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - KeywordOrStarred* _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 - { // NAME '=' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' 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 = _PyPegen_keyword_or_starred ( p , CHECK ( _Py_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwarg_or_starred[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' expression")); - } - { // starred_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); - expr_ty a; - if ( - (a = starred_expression_rule(p)) // starred_expression - ) - { - D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); - _res = _PyPegen_keyword_or_starred ( p , a , 0 ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwarg_or_starred[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); - } - if (p->call_invalid_rules) { // invalid_kwarg - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); - void *invalid_kwarg_var; - if ( - (invalid_kwarg_var = invalid_kwarg_rule(p)) // invalid_kwarg - ) - { - D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); - _res = invalid_kwarg_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwarg_or_starred[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_kwarg")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// kwarg_or_double_starred: NAME '=' expression | '**' expression | invalid_kwarg -static KeywordOrStarred* -kwarg_or_double_starred_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - KeywordOrStarred* _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 - { // NAME '=' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - && - (b = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' 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 = _PyPegen_keyword_or_starred ( p , CHECK ( _Py_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwarg_or_double_starred[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' expression")); - } - { // '**' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression")); - Token * _literal; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' 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 = _PyPegen_keyword_or_starred ( p , CHECK ( _Py_keyword ( NULL , a , EXTRA ) ) , 1 ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwarg_or_double_starred[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' expression")); - } - if (p->call_invalid_rules) { // invalid_kwarg - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); - void *invalid_kwarg_var; - if ( - (invalid_kwarg_var = invalid_kwarg_rule(p)) // invalid_kwarg - ) - { - D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); - _res = invalid_kwarg_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s kwarg_or_double_starred[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_kwarg")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// star_targets: star_target !',' | star_target ((',' star_target))* ','? -static expr_ty -star_targets_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // star_target !',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target !','")); - expr_ty a; - if ( - (a = star_target_rule(p)) // star_target - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 12) // token=',' - ) - { - D(fprintf(stderr, "%*c+ star_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target !','")); - _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 star_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target !','")); - } - { // star_target ((',' star_target))* ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty a; - asdl_seq * b; - if ( - (a = star_target_rule(p)) // star_target - && - (b = _loop0_117_rule(p)) // ((',' star_target))* - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ star_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?")); - 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 = _Py_Tuple ( CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ((',' star_target))* ','?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// star_targets_list_seq: ','.star_target+ ','? -static asdl_seq* -star_targets_list_seq_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.star_target+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_targets_list_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - if ( - (a = _gather_118_rule(p)) // ','.star_target+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ star_targets_list_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?")); - _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 star_targets_list_seq[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.star_target+ ','?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// star_targets_tuple_seq: star_target ((',' star_target))+ ','? | star_target ',' -static asdl_seq* -star_targets_tuple_seq_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // star_target ((',' star_target))+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty a; - asdl_seq * b; - if ( - (a = star_target_rule(p)) // star_target - && - (b = _loop1_120_rule(p)) // ((',' star_target))+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?")); - _res = _PyPegen_seq_insert_in_front ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_targets_tuple_seq[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ((',' star_target))+ ','?")); - } - { // star_target ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ','")); - Token * _literal; - expr_ty a; - if ( - (a = star_target_rule(p)) // star_target - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ','")); - _res = _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_targets_tuple_seq[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ','")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// star_target: '*' (!'*' star_target) | target_with_star_atom -static expr_ty -star_target_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, star_target_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 - { // '*' (!'*' star_target) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); - Token * _literal; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = _tmp_121_rule(p)) // !'*' star_target - ) - { - D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); - 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 = _Py_Starred ( CHECK ( _PyPegen_set_expr_context ( p , a , Store ) ) , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (!'*' star_target)")); - } - { // target_with_star_atom - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target_with_star_atom")); - expr_ty target_with_star_atom_var; - if ( - (target_with_star_atom_var = target_with_star_atom_rule(p)) // target_with_star_atom - ) - { - D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "target_with_star_atom")); - _res = target_with_star_atom_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "target_with_star_atom")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, star_target_type, _res); - p->level--; - return _res; -} - -// target_with_star_atom: -// | t_primary '.' NAME !t_lookahead -// | t_primary '[' slices ']' !t_lookahead -// | star_atom -static expr_ty -target_with_star_atom_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, target_with_star_atom_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 - { // t_primary '.' NAME !t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - && - (b = _PyPegen_name_token(p)) // NAME - && - _PyPegen_lookahead(0, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - 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 = _Py_Attribute ( a , b -> v . Name . id , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - } - { // t_primary '[' slices ']' !t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - Token * _literal; - Token * _literal_1; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (b = slices_rule(p)) // slices - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - && - _PyPegen_lookahead(0, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - 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 = _Py_Subscript ( a , b , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - } - { // star_atom - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_atom")); - expr_ty star_atom_var; - if ( - (star_atom_var = star_atom_rule(p)) // star_atom - ) - { - D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_atom")); - _res = star_atom_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_atom")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, target_with_star_atom_type, _res); - p->level--; - return _res; -} - -// star_atom: -// | NAME -// | '(' target_with_star_atom ')' -// | '(' star_targets_tuple_seq? ')' -// | '[' star_targets_list_seq? ']' -static expr_ty -star_atom_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); - expr_ty a; - if ( - (a = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); - _res = _PyPegen_set_expr_context ( p , a , Store ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); - } - { // '(' target_with_star_atom ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'")); - Token * _literal; - Token * _literal_1; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = target_with_star_atom_rule(p)) // target_with_star_atom - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'")); - _res = _PyPegen_set_expr_context ( p , a , Store ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' target_with_star_atom ')'")); - } - { // '(' star_targets_tuple_seq? ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = star_targets_tuple_seq_rule(p), !p->error_indicator) // star_targets_tuple_seq? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); - 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 = _Py_Tuple ( a , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); - } - { // '[' star_targets_list_seq? ']' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (a = star_targets_list_seq_rule(p), !p->error_indicator) // star_targets_list_seq? - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - ) - { - D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'")); - 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 = _Py_List ( a , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' star_targets_list_seq? ']'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// single_target: single_subscript_attribute_target | NAME | '(' single_target ')' -static expr_ty -single_target_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - int _mark = p->mark; - { // single_subscript_attribute_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> single_target[%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+ single_target[%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 single_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_subscript_attribute_target")); - } - { // NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); - expr_ty a; - if ( - (a = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ single_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); - _res = _PyPegen_set_expr_context ( p , a , Store ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s single_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); - } - { // '(' single_target ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); - Token * _literal; - Token * _literal_1; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = single_target_rule(p)) // single_target - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ single_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); - _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 single_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' single_target ')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// single_subscript_attribute_target: -// | t_primary '.' NAME !t_lookahead -// | t_primary '[' slices ']' !t_lookahead -static expr_ty -single_subscript_attribute_target_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // t_primary '.' NAME !t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - && - (b = _PyPegen_name_token(p)) // NAME - && - _PyPegen_lookahead(0, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - 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 = _Py_Attribute ( a , b -> v . Name . id , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s single_subscript_attribute_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - } - { // t_primary '[' slices ']' !t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - Token * _literal; - Token * _literal_1; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (b = slices_rule(p)) // slices - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - && - _PyPegen_lookahead(0, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - 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 = _Py_Subscript ( a , b , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s single_subscript_attribute_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// del_targets: ','.del_target+ ','? -static asdl_seq* -del_targets_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq* _res = NULL; - int _mark = p->mark; - { // ','.del_target+ ','? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - if ( - (a = _gather_122_rule(p)) // ','.del_target+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - ) - { - D(fprintf(stderr, "%*c+ del_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?")); - _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 del_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.del_target+ ','?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// del_target: -// | t_primary '.' NAME !t_lookahead -// | t_primary '[' slices ']' !t_lookahead -// | del_t_atom -static expr_ty -del_target_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, del_target_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 - { // t_primary '.' NAME !t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - && - (b = _PyPegen_name_token(p)) // NAME - && - _PyPegen_lookahead(0, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - 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 = _Py_Attribute ( a , b -> v . Name . id , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME !t_lookahead")); - } - { // t_primary '[' slices ']' !t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - Token * _literal; - Token * _literal_1; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (b = slices_rule(p)) // slices - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - && - _PyPegen_lookahead(0, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - 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 = _Py_Subscript ( a , b , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); - } - { // del_t_atom - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_t_atom")); - expr_ty del_t_atom_var; - if ( - (del_t_atom_var = del_t_atom_rule(p)) // del_t_atom - ) - { - D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_t_atom")); - _res = del_t_atom_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_t_atom")); - } - _res = NULL; - done: - _PyPegen_insert_memo(p, _mark, del_target_type, _res); - p->level--; - return _res; -} - -// del_t_atom: NAME | '(' del_target ')' | '(' del_targets? ')' | '[' del_targets? ']' -static expr_ty -del_t_atom_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); - expr_ty a; - if ( - (a = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); - _res = _PyPegen_set_expr_context ( p , a , Del ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME")); - } - { // '(' del_target ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_target ')'")); - Token * _literal; - Token * _literal_1; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = del_target_rule(p)) // del_target - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' del_target ')'")); - _res = _PyPegen_set_expr_context ( p , a , Del ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' del_target ')'")); - } - { // '(' del_targets? ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = del_targets_rule(p), !p->error_indicator) // del_targets? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'")); - 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 = _Py_Tuple ( a , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' del_targets? ')'")); - } - { // '[' del_targets? ']' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'")); - Token * _literal; - Token * _literal_1; - void *a; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (a = del_targets_rule(p), !p->error_indicator) // del_targets? - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - ) - { - D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'")); - 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 = _Py_List ( a , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s del_t_atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' del_targets? ']'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// t_primary: -// | t_primary '.' NAME &t_lookahead -// | t_primary '[' slices ']' &t_lookahead -// | t_primary genexp &t_lookahead -// | t_primary '(' arguments? ')' &t_lookahead -// | atom &t_lookahead -static expr_ty t_primary_raw(Parser *); -static expr_ty -t_primary_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - expr_ty _res = NULL; - if (_PyPegen_is_memoized(p, t_primary_type, &_res)) { - p->level--; - return _res; - } - int _mark = p->mark; - int _resmark = p->mark; - while (1) { - int tmpvar_8 = _PyPegen_update_memo(p, _mark, t_primary_type, _res); - if (tmpvar_8) { - p->level--; - return _res; - } - p->mark = _mark; - void *_raw = t_primary_raw(p); - if (p->error_indicator) { - p->level--; - return NULL; - } - if (_raw == NULL || p->mark <= _resmark) - break; - _resmark = p->mark; - _res = _raw; - } - p->mark = _resmark; - p->level--; - return _res; -} -static expr_ty -t_primary_raw(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - 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; - 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 - { // t_primary '.' NAME &t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead")); - Token * _literal; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - && - (b = _PyPegen_name_token(p)) // NAME - && - _PyPegen_lookahead(1, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead")); - 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 = _Py_Attribute ( a , b -> v . Name . id , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME &t_lookahead")); - } - { // t_primary '[' slices ']' &t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); - Token * _literal; - Token * _literal_1; - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - && - (b = slices_rule(p)) // slices - && - (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' - && - _PyPegen_lookahead(1, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); - 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 = _Py_Subscript ( a , b , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); - } - { // t_primary genexp &t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead")); - expr_ty a; - expr_ty b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (b = genexp_rule(p)) // genexp - && - _PyPegen_lookahead(1, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead")); - 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 = _Py_Call ( a , CHECK ( _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary genexp &t_lookahead")); - } - { // t_primary '(' arguments? ')' &t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); - Token * _literal; - Token * _literal_1; - expr_ty a; - void *b; - if ( - (a = t_primary_rule(p)) // t_primary - && - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (b = arguments_rule(p), !p->error_indicator) // arguments? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - && - _PyPegen_lookahead(1, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); - 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 = _Py_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s t_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); - } - { // atom &t_lookahead - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom &t_lookahead")); - expr_ty a; - if ( - (a = atom_rule(p)) // atom - && - _PyPegen_lookahead(1, t_lookahead_rule, p) - ) - { - D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "atom &t_lookahead")); - _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 t_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "atom &t_lookahead")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// t_lookahead: '(' | '[' | '.' -static void * -t_lookahead_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; - { // '(' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - ) - { - D(fprintf(stderr, "%*c+ t_lookahead[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s t_lookahead[%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> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - ) - { - D(fprintf(stderr, "%*c+ t_lookahead[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s t_lookahead[%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> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - ) - { - D(fprintf(stderr, "%*c+ t_lookahead[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s t_lookahead[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_arguments: -// | args ',' '*' -// | expression for_if_clauses ',' [args | expression for_if_clauses] -// | args for_if_clauses -// | args ',' expression for_if_clauses -// | args ',' args -static void * -invalid_arguments_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; - { // args ',' '*' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' '*'")); - Token * _literal; - Token * _literal_1; - expr_ty args_var; - if ( - (args_var = args_rule(p)) // args - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_literal_1 = _PyPegen_expect_token(p, 16)) // token='*' - ) - { - D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' '*'")); - _res = RAISE_SYNTAX_ERROR ( "iterable argument unpacking follows 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_arguments[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ',' '*'")); - } - { // expression for_if_clauses ',' [args | expression for_if_clauses] - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); - Token * _literal; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty a; - asdl_seq* for_if_clauses_var; - if ( - (a = expression_rule(p)) // expression - && - (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_opt_var = _tmp_124_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]")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "Generator expression must be parenthesized" ); - 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, "expression for_if_clauses ',' [args | expression for_if_clauses]")); - } - { // args for_if_clauses - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args for_if_clauses")); - expr_ty a; - asdl_seq* for_if_clauses_var; - if ( - (a = args_rule(p)) // args - && - (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses - ) - { - D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args for_if_clauses")); - _res = _PyPegen_nonparen_genexp_in_call ( p , a ); - 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 for_if_clauses")); - } - { // args ',' expression for_if_clauses - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); - Token * _literal; - expr_ty a; - expr_ty args_var; - asdl_seq* for_if_clauses_var; - if ( - (args_var = args_rule(p)) // args - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (a = expression_rule(p)) // expression - && - (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses - ) - { - D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "Generator expression must be parenthesized" ); - 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 ',' expression for_if_clauses")); - } - { // args ',' args - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' args")); - Token * _literal; - expr_ty a; - expr_ty args_var; - if ( - (a = args_rule(p)) // args - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (args_var = args_rule(p)) // args - ) - { - D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' args")); - _res = _PyPegen_arguments_parsing_error ( p , a ); - 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 ',' args")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_kwarg: !(NAME '=') expression '=' -static void * -invalid_kwarg_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; - { // !(NAME '=') expression '=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(NAME '=') expression '='")); - expr_ty a; - Token * b; - if ( - _PyPegen_lookahead(0, _tmp_125_rule, p) - && - (a = expression_rule(p)) // expression - && - (b = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(NAME '=') expression '='")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression cannot contain assignment, perhaps you meant \"==\"?" ); - 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, "!(NAME '=') expression '='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_named_expression: expression ':=' expression -static void * -invalid_named_expression_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; - { // expression ':=' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':=' expression")); - Token * _literal; - expr_ty a; - expr_ty expression_var; - if ( - (a = expression_rule(p)) // expression - && - (_literal = _PyPegen_expect_token(p, 53)) // token=':=' - && - (expression_var = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':=' expression")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use assignment expressions with %s" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_named_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':=' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_assignment: -// | invalid_ann_assign_target ':' expression -// | star_named_expression ',' star_named_expressions* ':' expression -// | expression ':' expression -// | ((star_targets '='))* star_expressions '=' -// | ((star_targets '='))* yield_expr '=' -// | star_expressions augassign (yield_expr | star_expressions) -static void * -invalid_assignment_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; - { // invalid_ann_assign_target ':' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_ann_assign_target ':' expression")); - Token * _literal; - expr_ty a; - expr_ty expression_var; - if ( - (a = invalid_ann_assign_target_rule(p)) // invalid_ann_assign_target - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (expression_var = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_ann_assign_target ':' expression")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not %s) can be annotated" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_ann_assign_target ':' expression")); - } - { // star_named_expression ',' star_named_expressions* ':' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_126_var; - expr_ty a; - expr_ty expression_var; - if ( - (a = star_named_expression_rule(p)) // star_named_expression - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_loop0_126_var = _loop0_126_rule(p)) // star_named_expressions* - && - (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' - && - (expression_var = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not tuple) can be annotated" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); - } - { // expression ':' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); - Token * _literal; - expr_ty a; - expr_ty expression_var; - if ( - (a = expression_rule(p)) // expression - && - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (expression_var = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "illegal target for annotation" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' expression")); - } - { // ((star_targets '='))* star_expressions '=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); - Token * _literal; - asdl_seq * _loop0_127_var; - expr_ty a; - if ( - (_loop0_127_var = _loop0_127_rule(p)) // ((star_targets '='))* - && - (a = star_expressions_rule(p)) // star_expressions - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); - _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))* star_expressions '='")); - } - { // ((star_targets '='))* yield_expr '=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); - Token * _literal; - asdl_seq * _loop0_128_var; - expr_ty a; - if ( - (_loop0_128_var = _loop0_128_rule(p)) // ((star_targets '='))* - && - (a = yield_expr_rule(p)) // yield_expr - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "assignment to yield expression not possible" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))* yield_expr '='")); - } - { // star_expressions augassign (yield_expr | star_expressions) - if (p->error_indicator) { - p->level--; - 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_129_var; - expr_ty a; - AugOperator* augassign_var; - if ( - (a = star_expressions_rule(p)) // star_expressions - && - (augassign_var = augassign_rule(p)) // augassign - && - (_tmp_129_var = _tmp_129_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)")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "'%s' is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_ann_assign_target: list | tuple | '(' invalid_ann_assign_target ')' -static expr_ty -invalid_ann_assign_target_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - int _mark = p->mark; - { // list - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_ann_assign_target[%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+ invalid_ann_assign_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); - _res = list_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_ann_assign_target[%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> invalid_ann_assign_target[%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+ invalid_ann_assign_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); - _res = tuple_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_ann_assign_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); - } - { // '(' invalid_ann_assign_target ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' invalid_ann_assign_target ')'")); - Token * _literal; - Token * _literal_1; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = invalid_ann_assign_target_rule(p)) // invalid_ann_assign_target - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ invalid_ann_assign_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' invalid_ann_assign_target ')'")); - _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 invalid_ann_assign_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' invalid_ann_assign_target ')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_del_stmt: 'del' star_expressions -static void * -invalid_del_stmt_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; - { // 'del' star_expressions - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' star_expressions")); - Token * _keyword; - expr_ty a; - if ( - (_keyword = _PyPegen_expect_token(p, 503)) // token='del' - && - (a = star_expressions_rule(p)) // star_expressions - ) - { - D(fprintf(stderr, "%*c+ invalid_del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' star_expressions")); - _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( DEL_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_del_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'del' star_expressions")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_block: NEWLINE !INDENT -static void * -invalid_block_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; - { // NEWLINE !INDENT - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE !INDENT")); - Token * newline_var; - if ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT - ) - { - D(fprintf(stderr, "%*c+ invalid_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE !INDENT")); - _res = RAISE_INDENTATION_ERROR ( "expected an indented block" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE !INDENT")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// Left-recursive -// invalid_primary: primary '{' -static void * -invalid_primary_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; - { // primary '{' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '{'")); - Token * a; - expr_ty primary_var; - if ( - (primary_var = primary_rule(p)) // primary - && - (a = _PyPegen_expect_token(p, 25)) // token='{' - ) - { - D(fprintf(stderr, "%*c+ invalid_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '{'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "invalid syntax" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "primary '{'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_comprehension: ('[' | '(' | '{') starred_expression for_if_clauses -static void * -invalid_comprehension_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; - { // ('[' | '(' | '{') starred_expression for_if_clauses - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_130_var; - expr_ty a; - asdl_seq* for_if_clauses_var; - if ( - (_tmp_130_var = _tmp_130_rule(p)) // '[' | '(' | '{' - && - (a = starred_expression_rule(p)) // starred_expression - && - (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses - ) - { - D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "iterable unpacking cannot be used in comprehension" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_comprehension[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_dict_comprehension: '{' '**' bitwise_or for_if_clauses '}' -static void * -invalid_dict_comprehension_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; - { // '{' '**' bitwise_or for_if_clauses '}' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_dict_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'")); - Token * _literal; - Token * _literal_1; - Token * a; - expr_ty bitwise_or_var; - asdl_seq* for_if_clauses_var; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - && - (a = _PyPegen_expect_token(p, 35)) // token='**' - && - (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or - && - (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses - && - (_literal_1 = _PyPegen_expect_token(p, 26)) // token='}' - ) - { - D(fprintf(stderr, "%*c+ invalid_dict_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "dict unpacking cannot be used in dict comprehension" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_dict_comprehension[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_parameters: -// | param_no_default* (slash_with_default | param_with_default+) param_no_default -static void * -invalid_parameters_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; - { // param_no_default* (slash_with_default | param_with_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, "param_no_default* (slash_with_default | param_with_default+) param_no_default")); - asdl_seq * _loop0_131_var; - void *_tmp_132_var; - arg_ty param_no_default_var; - if ( - (_loop0_131_var = _loop0_131_rule(p)) // param_no_default* - && - (_tmp_132_var = _tmp_132_rule(p)) // slash_with_default | param_with_default+ - && - (param_no_default_var = param_no_default_rule(p)) // param_no_default - ) - { - D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* (slash_with_default | param_with_default+) param_no_default")); - _res = RAISE_SYNTAX_ERROR ( "non-default argument follows default argument" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - 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* (slash_with_default | param_with_default+) param_no_default")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_lambda_parameters: -// | lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default -static void * -invalid_lambda_parameters_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_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) 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* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default")); - asdl_seq * _loop0_133_var; - void *_tmp_134_var; - arg_ty lambda_param_no_default_var; - if ( - (_loop0_133_var = _loop0_133_rule(p)) // lambda_param_no_default* - && - (_tmp_134_var = _tmp_134_rule(p)) // lambda_slash_with_default | lambda_param_with_default+ - && - (lambda_param_no_default_var = 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, "lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default")); - _res = RAISE_SYNTAX_ERROR ( "non-default argument follows default argument" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - 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_slash_with_default | lambda_param_with_default+) lambda_param_no_default")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_star_etc: '*' (')' | ',' (')' | '**')) | '*' ',' TYPE_COMMENT -static void * -invalid_star_etc_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; - { // '*' (')' | ',' (')' | '**')) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - Token * _literal; - void *_tmp_135_var; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (_tmp_135_var = _tmp_135_rule(p)) // ')' | ',' (')' | '**') - ) - { - D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - } - { // '*' ',' TYPE_COMMENT - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); - Token * _literal; - Token * _literal_1; - Token * type_comment_var; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - && - (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' - ) - { - D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); - _res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' TYPE_COMMENT")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_lambda_star_etc: '*' (':' | ',' (':' | '**')) -static void * -invalid_lambda_star_etc_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; - { // '*' (':' | ',' (':' | '**')) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); - Token * _literal; - void *_tmp_136_var; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (_tmp_136_var = _tmp_136_rule(p)) // ':' | ',' (':' | '**') - ) - { - D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); - _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_double_type_comments: TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT -static void * -invalid_double_type_comments_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; - { // TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_double_type_comments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); - Token * indent_var; - Token * newline_var; - Token * newline_var_1; - Token * type_comment_var; - Token * type_comment_var_1; - if ( - (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' - && - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - && - (type_comment_var_1 = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' - && - (newline_var_1 = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - && - (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' - ) - { - D(fprintf(stderr, "%*c+ invalid_double_type_comments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); - _res = RAISE_SYNTAX_ERROR ( "Cannot have two type comments on def" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_double_type_comments[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_with_item: expression 'as' expression -static void * -invalid_with_item_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; - { // expression 'as' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' expression")); - Token * _keyword; - expr_ty a; - expr_ty expression_var; - if ( - (expression_var = expression_rule(p)) // expression - && - (_keyword = _PyPegen_expect_token(p, 520)) // token='as' - && - (a = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression")); - _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_with_item[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression 'as' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_for_target: ASYNC? 'for' star_expressions -static void * -invalid_for_target_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; - { // ASYNC? 'for' star_expressions - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_for_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions")); - Token * _keyword; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty a; - if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? - && - (_keyword = _PyPegen_expect_token(p, 517)) // token='for' - && - (a = star_expressions_rule(p)) // star_expressions - ) - { - D(fprintf(stderr, "%*c+ invalid_for_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions")); - _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( FOR_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_for_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'for' star_expressions")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// invalid_group: '(' starred_expression ')' -static void * -invalid_group_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; - { // '(' starred_expression ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' starred_expression ')'")); - Token * _literal; - Token * _literal_1; - expr_ty a; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (a = starred_expression_rule(p)) // starred_expression - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ invalid_group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' starred_expression ')'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "can't use starred expression here" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_group[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' starred_expression ')'")); - } - _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(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // import_from_as_names ',' NEWLINE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> invalid_import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names ',' NEWLINE")); - Token * _literal; - asdl_seq* import_from_as_names_var; - Token * newline_var; - if ( - (import_from_as_names_var = import_from_as_names_rule(p)) // import_from_as_names - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - ) - { - D(fprintf(stderr, "%*c+ invalid_import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_names ',' NEWLINE")); - _res = RAISE_SYNTAX_ERROR ( "trailing comma not allowed without surrounding 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_import_from_targets[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_names ',' NEWLINE")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_1: NEWLINE -static asdl_seq * -_loop0_1_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // NEWLINE - 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' - ) - { - _res = newline_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_1[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_1_type, _seq); - p->level--; - return _seq; -} - -// _loop0_2: NEWLINE -static asdl_seq * -_loop0_2_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; - } - ssize_t _children_capacity = 1; - 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' - ) - { - _res = newline_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_2[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_2_type, _seq); - p->level--; - return _seq; -} - -// _loop0_4: ',' expression -static asdl_seq * -_loop0_4_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = expression_rule(p)) // expression - ) - { - _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) { - 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_4[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_4_type, _seq); - p->level--; - return _seq; -} - -// _gather_3: expression _loop0_4 -static asdl_seq * -_gather_3_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // expression _loop0_4 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_4")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = expression_rule(p)) // expression - && - (seq = _loop0_4_rule(p)) // _loop0_4 - ) - { - D(fprintf(stderr, "%*c+ _gather_3[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_4")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_3[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_4")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_6: ',' expression -static asdl_seq * -_loop0_6_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = expression_rule(p)) // expression - ) - { - _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) { - 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_6[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_6_type, _seq); - p->level--; - return _seq; -} - -// _gather_5: expression _loop0_6 -static asdl_seq * -_gather_5_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // expression _loop0_6 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_6")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = expression_rule(p)) // expression - && - (seq = _loop0_6_rule(p)) // _loop0_6 - ) - { - D(fprintf(stderr, "%*c+ _gather_5[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_6")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_5[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_6")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_8: ',' expression -static asdl_seq * -_loop0_8_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = expression_rule(p)) // expression - ) - { - _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) { - 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_8[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_8_type, _seq); - p->level--; - return _seq; -} - -// _gather_7: expression _loop0_8 -static asdl_seq * -_gather_7_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // expression _loop0_8 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_8")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = expression_rule(p)) // expression - && - (seq = _loop0_8_rule(p)) // _loop0_8 - ) - { - D(fprintf(stderr, "%*c+ _gather_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_8")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_7[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_8")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_10: ',' expression -static asdl_seq * -_loop0_10_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = expression_rule(p)) // expression - ) - { - _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) { - 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_10[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_10_type, _seq); - p->level--; - return _seq; -} - -// _gather_9: expression _loop0_10 -static asdl_seq * -_gather_9_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // expression _loop0_10 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_10")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = expression_rule(p)) // expression - && - (seq = _loop0_10_rule(p)) // _loop0_10 - ) - { - D(fprintf(stderr, "%*c+ _gather_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_10")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_9[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_10")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_11: statement -static asdl_seq * -_loop1_11_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // statement - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); - asdl_seq* statement_var; - while ( - (statement_var = statement_rule(p)) // statement - ) - { - _res = statement_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_11[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_11_type, _seq); - p->level--; - return _seq; -} - -// _loop0_13: ';' small_stmt -static asdl_seq * -_loop0_13_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ';' small_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' small_stmt")); - Token * _literal; - stmt_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 13)) // token=';' - && - (elem = small_stmt_rule(p)) // small_stmt - ) - { - _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) { - 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_13[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';' small_stmt")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_13_type, _seq); - p->level--; - return _seq; -} - -// _gather_12: small_stmt _loop0_13 -static asdl_seq * -_gather_12_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // small_stmt _loop0_13 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "small_stmt _loop0_13")); - stmt_ty elem; - asdl_seq * seq; - if ( - (elem = small_stmt_rule(p)) // small_stmt - && - (seq = _loop0_13_rule(p)) // _loop0_13 - ) - { - D(fprintf(stderr, "%*c+ _gather_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "small_stmt _loop0_13")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_12[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "small_stmt _loop0_13")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_14: 'import' | 'from' -static void * -_tmp_14_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; - { // 'import' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 513)) // token='import' - ) - { - D(fprintf(stderr, "%*c+ _tmp_14[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_14[%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_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 514)) // token='from' - ) - { - D(fprintf(stderr, "%*c+ _tmp_14[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_14[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_15: 'def' | '@' | ASYNC -static void * -_tmp_15_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; - { // 'def' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 523)) // token='def' - ) - { - D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); - _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, "'def'")); - } - { // '@' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 49)) // token='@' - ) - { - D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); - _res = _literal; - 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, "'@'")); - } - { // ASYNC - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_15[%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_15[%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_15[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_16: 'class' | '@' -static void * -_tmp_16_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; - { // 'class' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 524)) // token='class' - ) - { - D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); - _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, "'class'")); - } - { // '@' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 49)) // token='@' - ) - { - D(fprintf(stderr, "%*c+ _tmp_16[%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, "'@'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_17: 'with' | ASYNC -static void * -_tmp_17_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; - { // 'with' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 519)) // token='with' - ) - { - D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); - _res = _keyword; - 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, "'with'")); - } - { // ASYNC - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_17[%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_17[%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_17[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_18: 'for' | ASYNC -static void * -_tmp_18_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; - { // 'for' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 517)) // token='for' - ) - { - D(fprintf(stderr, "%*c+ _tmp_18[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_18[%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_18[%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_18[%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_18[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_19: '=' annotated_rhs -static void * -_tmp_19_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; - { // '=' annotated_rhs - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_19[%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+ _tmp_19[%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 _tmp_19[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_20: '(' single_target ')' | single_subscript_attribute_target -static void * -_tmp_20_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; - { // '(' single_target ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_20[%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+ _tmp_20[%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; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_20[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' single_target ')'")); - } - { // single_subscript_attribute_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_20[%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_20[%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_20[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_subscript_attribute_target")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_21: '=' annotated_rhs -static void * -_tmp_21_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; - { // '=' annotated_rhs - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_21[%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+ _tmp_21[%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 _tmp_21[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_22: (star_targets '=') -static asdl_seq * -_loop1_22_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // (star_targets '=') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_137_var; - while ( - (_tmp_137_var = _tmp_137_rule(p)) // star_targets '=' - ) - { - _res = _tmp_137_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_22[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_22_type, _seq); - p->level--; - return _seq; -} - -// _tmp_23: yield_expr | star_expressions -static void * -_tmp_23_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; - { // yield_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_23[%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_23[%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_23[%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_23[%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_23[%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_23[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_24: yield_expr | star_expressions -static void * -_tmp_24_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; - { // yield_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_24[%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_24[%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_24[%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_24[%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_24[%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_24[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_26: ',' NAME -static asdl_seq * -_loop0_26_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_26[%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) { - 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_26[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_26_type, _seq); - p->level--; - return _seq; -} - -// _gather_25: NAME _loop0_26 -static asdl_seq * -_gather_25_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // NAME _loop0_26 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_26")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = _PyPegen_name_token(p)) // NAME - && - (seq = _loop0_26_rule(p)) // _loop0_26 - ) - { - D(fprintf(stderr, "%*c+ _gather_25[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_26")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_25[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_26")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_28: ',' NAME -static asdl_seq * -_loop0_28_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_28[%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) { - 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_28[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_28_type, _seq); - p->level--; - return _seq; -} - -// _gather_27: NAME _loop0_28 -static asdl_seq * -_gather_27_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // NAME _loop0_28 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_28")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = _PyPegen_name_token(p)) // NAME - && - (seq = _loop0_28_rule(p)) // _loop0_28 - ) - { - D(fprintf(stderr, "%*c+ _gather_27[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_28")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_27[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_28")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_29: ',' expression -static void * -_tmp_29_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; - { // ',' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_29[%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_29[%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_29[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_30: ';' | NEWLINE -static void * -_tmp_30_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; - { // ';' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 13)) // token=';' - ) - { - D(fprintf(stderr, "%*c+ _tmp_30[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_30[%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_30[%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_30[%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_30[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_31: ('.' | '...') -static asdl_seq * -_loop0_31_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ('.' | '...') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_138_var; - while ( - (_tmp_138_var = _tmp_138_rule(p)) // '.' | '...' - ) - { - _res = _tmp_138_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_31[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_31_type, _seq); - p->level--; - return _seq; -} - -// _loop1_32: ('.' | '...') -static asdl_seq * -_loop1_32_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ('.' | '...') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_139_var; - while ( - (_tmp_139_var = _tmp_139_rule(p)) // '.' | '...' - ) - { - _res = _tmp_139_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_32[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_32_type, _seq); - p->level--; - return _seq; -} - -// _loop0_34: ',' import_from_as_name -static asdl_seq * -_loop0_34_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' import_from_as_name - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name")); - Token * _literal; - alias_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = import_from_as_name_rule(p)) // import_from_as_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) { - 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_34[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' import_from_as_name")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_34_type, _seq); - p->level--; - return _seq; -} - -// _gather_33: import_from_as_name _loop0_34 -static asdl_seq * -_gather_33_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // import_from_as_name _loop0_34 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_34")); - alias_ty elem; - asdl_seq * seq; - if ( - (elem = import_from_as_name_rule(p)) // import_from_as_name - && - (seq = _loop0_34_rule(p)) // _loop0_34 - ) - { - D(fprintf(stderr, "%*c+ _gather_33[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_34")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_33[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_name _loop0_34")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_35: 'as' NAME -static void * -_tmp_35_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; - { // 'as' NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty z; - if ( - (_keyword = _PyPegen_expect_token(p, 520)) // token='as' - && - (z = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ _tmp_35[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _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_35[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_37: ',' dotted_as_name -static asdl_seq * -_loop0_37_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' dotted_as_name - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name")); - Token * _literal; - alias_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = dotted_as_name_rule(p)) // dotted_as_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) { - 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_37[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_as_name")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_37_type, _seq); - p->level--; - return _seq; -} - -// _gather_36: dotted_as_name _loop0_37 -static asdl_seq * -_gather_36_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // dotted_as_name _loop0_37 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_37")); - alias_ty elem; - asdl_seq * seq; - if ( - (elem = dotted_as_name_rule(p)) // dotted_as_name - && - (seq = _loop0_37_rule(p)) // _loop0_37 - ) - { - D(fprintf(stderr, "%*c+ _gather_36[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_37")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_36[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_as_name _loop0_37")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_38: 'as' NAME -static void * -_tmp_38_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; - { // 'as' NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty z; - if ( - (_keyword = _PyPegen_expect_token(p, 520)) // token='as' - && - (z = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ _tmp_38[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _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_38[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_40: ',' with_item -static asdl_seq * -_loop0_40_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' with_item - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); - Token * _literal; - withitem_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = with_item_rule(p)) // with_item - ) - { - _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) { - 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_40[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_40_type, _seq); - p->level--; - return _seq; -} - -// _gather_39: with_item _loop0_40 -static asdl_seq * -_gather_39_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // with_item _loop0_40 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_40")); - withitem_ty elem; - asdl_seq * seq; - if ( - (elem = with_item_rule(p)) // with_item - && - (seq = _loop0_40_rule(p)) // _loop0_40 - ) - { - D(fprintf(stderr, "%*c+ _gather_39[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_40")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_39[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_40")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_42: ',' with_item -static asdl_seq * -_loop0_42_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' with_item - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); - Token * _literal; - withitem_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = with_item_rule(p)) // with_item - ) - { - _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) { - 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_42[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_42_type, _seq); - p->level--; - return _seq; -} - -// _gather_41: with_item _loop0_42 -static asdl_seq * -_gather_41_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // with_item _loop0_42 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_42")); - withitem_ty elem; - asdl_seq * seq; - if ( - (elem = with_item_rule(p)) // with_item - && - (seq = _loop0_42_rule(p)) // _loop0_42 - ) - { - D(fprintf(stderr, "%*c+ _gather_41[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_42")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_41[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_42")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_44: ',' with_item -static asdl_seq * -_loop0_44_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' with_item - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); - Token * _literal; - withitem_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = with_item_rule(p)) // with_item - ) - { - _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) { - 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_44[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_44_type, _seq); - p->level--; - return _seq; -} - -// _gather_43: with_item _loop0_44 -static asdl_seq * -_gather_43_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // with_item _loop0_44 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_43[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_44")); - withitem_ty elem; - asdl_seq * seq; - if ( - (elem = with_item_rule(p)) // with_item - && - (seq = _loop0_44_rule(p)) // _loop0_44 - ) - { - D(fprintf(stderr, "%*c+ _gather_43[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_44")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_43[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_44")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_46: ',' with_item -static asdl_seq * -_loop0_46_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' with_item - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); - Token * _literal; - withitem_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = with_item_rule(p)) // with_item - ) - { - _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) { - 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_46[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_46_type, _seq); - p->level--; - return _seq; -} - -// _gather_45: with_item _loop0_46 -static asdl_seq * -_gather_45_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // with_item _loop0_46 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_46")); - withitem_ty elem; - asdl_seq * seq; - if ( - (elem = with_item_rule(p)) // with_item - && - (seq = _loop0_46_rule(p)) // _loop0_46 - ) - { - D(fprintf(stderr, "%*c+ _gather_45[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_46")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_45[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_46")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_47: ',' | ')' | ':' -static void * -_tmp_47_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; - { // ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ _tmp_47[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_47[%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_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ _tmp_47[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_47[%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_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - ) - { - D(fprintf(stderr, "%*c+ _tmp_47[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_47[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_48: except_block -static asdl_seq * -_loop1_48_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // except_block - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_48[%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 - ) - { - _res = except_block_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_48[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_48_type, _seq); - p->level--; - return _seq; -} - -// _tmp_49: 'as' NAME -static void * -_tmp_49_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; - { // 'as' NAME - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty z; - if ( - (_keyword = _PyPegen_expect_token(p, 520)) // token='as' - && - (z = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ _tmp_49[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _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_49[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_50: 'from' expression -static void * -_tmp_50_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; - { // 'from' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression")); - Token * _keyword; - expr_ty z; - if ( - (_keyword = _PyPegen_expect_token(p, 514)) // token='from' - && - (z = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ _tmp_50[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' 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_50[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_51: '->' expression -static void * -_tmp_51_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; - { // '->' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); - Token * _literal; - expr_ty z; - if ( - (_literal = _PyPegen_expect_token(p, 51)) // token='->' - && - (z = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ _tmp_51[%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_51[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_52: '->' expression -static void * -_tmp_52_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; - { // '->' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); - Token * _literal; - expr_ty z; - if ( - (_literal = _PyPegen_expect_token(p, 51)) // token='->' - && - (z = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ _tmp_52[%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_52[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_53: NEWLINE INDENT -static void * -_tmp_53_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; - { // NEWLINE INDENT - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); - Token * indent_var; - Token * newline_var; - if ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - && - (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' - ) - { - D(fprintf(stderr, "%*c+ _tmp_53[%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_53[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_54: param_no_default -static asdl_seq * -_loop0_54_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_54[%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 - ) - { - _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) { - 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_54[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_54_type, _seq); - p->level--; - return _seq; -} - -// _loop0_55: param_with_default -static asdl_seq * -_loop0_55_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_55[%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 - ) - { - _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) { - 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_55[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_55_type, _seq); - p->level--; - return _seq; -} - -// _loop0_56: param_with_default -static asdl_seq * -_loop0_56_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_56[%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 - ) - { - _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) { - 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_56[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_56_type, _seq); - p->level--; - return _seq; -} - -// _loop1_57: param_no_default -static asdl_seq * -_loop1_57_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_57[%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 - ) - { - _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) { - 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_57[%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; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_57_type, _seq); - p->level--; - return _seq; -} - -// _loop0_58: param_with_default -static asdl_seq * -_loop0_58_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_58[%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 - ) - { - _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) { - 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_58[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_58_type, _seq); - p->level--; - return _seq; -} - -// _loop1_59: param_with_default -static asdl_seq * -_loop1_59_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_59[%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 - ) - { - _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) { - 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_59[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_59_type, _seq); - p->level--; - return _seq; -} - -// _loop1_60: param_no_default -static asdl_seq * -_loop1_60_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_60[%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 - ) - { - _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) { - 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_60[%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; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_60_type, _seq); - p->level--; - return _seq; -} - -// _loop1_61: param_no_default -static asdl_seq * -_loop1_61_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_61[%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 - ) - { - _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) { - 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_61[%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; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_61_type, _seq); - p->level--; - return _seq; -} - -// _loop0_62: param_no_default -static asdl_seq * -_loop0_62_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_62[%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 - ) - { - _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) { - 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_62[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_62_type, _seq); - p->level--; - return _seq; -} - -// _loop1_63: param_with_default -static asdl_seq * -_loop1_63_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_63[%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 - ) - { - _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) { - 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_63[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_63_type, _seq); - p->level--; - return _seq; -} - -// _loop0_64: param_no_default -static asdl_seq * -_loop0_64_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_64[%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 - ) - { - _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) { - 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_64[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_64_type, _seq); - p->level--; - return _seq; -} - -// _loop1_65: param_with_default -static asdl_seq * -_loop1_65_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_65[%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 - ) - { - _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) { - 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_65[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_65_type, _seq); - p->level--; - return _seq; -} - -// _loop0_66: param_maybe_default -static asdl_seq * -_loop0_66_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_maybe_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_66[%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) { - 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_66[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_66_type, _seq); - p->level--; - return _seq; -} - -// _loop1_67: param_maybe_default -static asdl_seq * -_loop1_67_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_maybe_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_67[%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) { - 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_67[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_67_type, _seq); - p->level--; - return _seq; -} - -// _loop1_68: ('@' named_expression NEWLINE) -static asdl_seq * -_loop1_68_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ('@' named_expression NEWLINE) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_140_var; - while ( - (_tmp_140_var = _tmp_140_rule(p)) // '@' named_expression NEWLINE - ) - { - _res = _tmp_140_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_68[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('@' named_expression NEWLINE)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_68_type, _seq); - p->level--; - return _seq; -} - -// _tmp_69: '(' arguments? ')' -static void * -_tmp_69_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; - { // '(' arguments? ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); - Token * _literal; - Token * _literal_1; - void *z; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (z = arguments_rule(p), !p->error_indicator) // arguments? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); - _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_69[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_70: (',' star_expression) -static asdl_seq * -_loop1_70_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // (',' star_expression) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_141_var; - while ( - (_tmp_141_var = _tmp_141_rule(p)) // ',' star_expression - ) - { - _res = _tmp_141_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_70[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_70_type, _seq); - p->level--; - return _seq; -} - -// _loop0_72: ',' star_named_expression -static asdl_seq * -_loop0_72_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' star_named_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = star_named_expression_rule(p)) // star_named_expression - ) - { - _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) { - 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_72[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_72_type, _seq); - p->level--; - return _seq; -} - -// _gather_71: star_named_expression _loop0_72 -static asdl_seq * -_gather_71_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // star_named_expression _loop0_72 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_72")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = star_named_expression_rule(p)) // star_named_expression - && - (seq = _loop0_72_rule(p)) // _loop0_72 - ) - { - D(fprintf(stderr, "%*c+ _gather_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_72")); - _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, "star_named_expression _loop0_72")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_73: (',' expression) -static asdl_seq * -_loop1_73_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // (',' expression) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_142_var; - while ( - (_tmp_142_var = _tmp_142_rule(p)) // ',' expression - ) - { - _res = _tmp_142_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_73[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' expression)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_73_type, _seq); - p->level--; - return _seq; -} - -// _loop0_74: lambda_param_no_default -static asdl_seq * -_loop0_74_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_74[%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) { - 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_74[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_74_type, _seq); - p->level--; - return _seq; -} - -// _loop0_75: lambda_param_with_default -static asdl_seq * -_loop0_75_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_75[%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) { - 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_75[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_75_type, _seq); - p->level--; - return _seq; -} - -// _loop0_76: lambda_param_with_default -static asdl_seq * -_loop0_76_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_76[%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) { - 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_76[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_76_type, _seq); - p->level--; - return _seq; -} - -// _loop1_77: lambda_param_no_default -static asdl_seq * -_loop1_77_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_77[%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) { - 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_77[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_77_type, _seq); - p->level--; - return _seq; -} - -// _loop0_78: lambda_param_with_default -static asdl_seq * -_loop0_78_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_78[%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) { - 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_78[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_78_type, _seq); - p->level--; - return _seq; -} - -// _loop1_79: lambda_param_with_default -static asdl_seq * -_loop1_79_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_79[%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) { - 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_79[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_79_type, _seq); - p->level--; - return _seq; -} - -// _loop1_80: lambda_param_no_default -static asdl_seq * -_loop1_80_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_80[%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) { - 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_80[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_80_type, _seq); - p->level--; - return _seq; -} - -// _loop1_81: lambda_param_no_default -static asdl_seq * -_loop1_81_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_81[%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) { - 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_81[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_81_type, _seq); - p->level--; - return _seq; -} - -// _loop0_82: lambda_param_no_default -static asdl_seq * -_loop0_82_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_82[%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) { - 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, "lambda_param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_82_type, _seq); - p->level--; - return _seq; -} - -// _loop1_83: lambda_param_with_default -static asdl_seq * -_loop1_83_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_83[%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) { - 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_83[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_83_type, _seq); - p->level--; - return _seq; -} - -// _loop0_84: lambda_param_no_default -static asdl_seq * -_loop0_84_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_84[%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) { - 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_84[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_84_type, _seq); - p->level--; - return _seq; -} - -// _loop1_85: lambda_param_with_default -static asdl_seq * -_loop1_85_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_85[%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) { - 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_85[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_85_type, _seq); - p->level--; - return _seq; -} - -// _loop0_86: lambda_param_maybe_default -static asdl_seq * -_loop0_86_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_maybe_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_86[%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 - ) - { - _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) { - 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_86[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_86_type, _seq); - p->level--; - return _seq; -} - -// _loop1_87: lambda_param_maybe_default -static asdl_seq * -_loop1_87_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_maybe_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_87[%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 - ) - { - _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) { - 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_87[%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; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_87_type, _seq); - p->level--; - return _seq; -} - -// _loop1_88: ('or' conjunction) -static asdl_seq * -_loop1_88_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ('or' conjunction) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_143_var; - while ( - (_tmp_143_var = _tmp_143_rule(p)) // 'or' conjunction - ) - { - _res = _tmp_143_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_88[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_88_type, _seq); - p->level--; - return _seq; -} - -// _loop1_89: ('and' inversion) -static asdl_seq * -_loop1_89_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ('and' inversion) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_144_var; - while ( - (_tmp_144_var = _tmp_144_rule(p)) // 'and' inversion - ) - { - _res = _tmp_144_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_89[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_89_type, _seq); - p->level--; - return _seq; -} - -// _loop1_90: compare_op_bitwise_or_pair -static asdl_seq * -_loop1_90_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // compare_op_bitwise_or_pair - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_90[%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 - ) - { - _res = compare_op_bitwise_or_pair_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_90[%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) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_90_type, _seq); - p->level--; - return _seq; -} - -// _tmp_91: '!=' -static void * -_tmp_91_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; - { // '!=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); - Token * tok; - if ( - (tok = _PyPegen_expect_token(p, 28)) // token='!=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_91[%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; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_93: ',' slice -static asdl_seq * -_loop0_93_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' slice - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' slice")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = slice_rule(p)) // slice - ) - { - _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) { - 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_93[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' slice")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_93_type, _seq); - p->level--; - return _seq; -} - -// _gather_92: slice _loop0_93 -static asdl_seq * -_gather_92_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // slice _loop0_93 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice _loop0_93")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = slice_rule(p)) // slice - && - (seq = _loop0_93_rule(p)) // _loop0_93 - ) - { - D(fprintf(stderr, "%*c+ _gather_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice _loop0_93")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_92[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice _loop0_93")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_94: ':' expression? -static void * -_tmp_94_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; - { // ':' expression? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); - Token * _literal; - void *d; - if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - && - (d = expression_rule(p), !p->error_indicator) // expression? - ) - { - D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); - _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 _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_95: tuple | group | genexp -static void * -_tmp_95_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; - { // tuple - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_95[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); - } - { // group - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_95[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group")); - } - { // genexp - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_95[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_96: list | listcomp -static void * -_tmp_96_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; - { // list - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_96[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); - } - { // listcomp - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_96[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "listcomp")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_97: dict | set | dictcomp | setcomp -static void * -_tmp_97_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; - { // dict - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_97[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dict")); - } - { // set - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_97[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "set")); - } - { // dictcomp - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_97[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dictcomp")); - } - { // setcomp - if (p->error_indicator) { - p->level--; - return NULL; - } - 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_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_97[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "setcomp")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_98: STRING -static asdl_seq * -_loop1_98_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // STRING - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); - expr_ty string_var; - while ( - (string_var = _PyPegen_string_token(p)) // STRING - ) - { - _res = string_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_98[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_98_type, _seq); - p->level--; - return _seq; -} - -// _tmp_99: star_named_expression ',' star_named_expressions? -static void * -_tmp_99_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; - { // star_named_expression ',' star_named_expressions? - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); - Token * _literal; - expr_ty y; - void *z; - if ( - (y = star_named_expression_rule(p)) // star_named_expression - && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (z = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? - ) - { - D(fprintf(stderr, "%*c+ _tmp_99[%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; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_99[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions?")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_100: yield_expr | named_expression -static void * -_tmp_100_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; - { // yield_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_100[%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_100[%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_100[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); - } - { // named_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_100[%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_100[%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_100[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_102: ',' double_starred_kvpair -static asdl_seq * -_loop0_102_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' double_starred_kvpair - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); - Token * _literal; - KeyValuePair* elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair - ) - { - _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) { - 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_102[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_102_type, _seq); - p->level--; - return _seq; -} - -// _gather_101: double_starred_kvpair _loop0_102 -static asdl_seq * -_gather_101_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // double_starred_kvpair _loop0_102 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_102")); - KeyValuePair* elem; - asdl_seq * seq; - if ( - (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair - && - (seq = _loop0_102_rule(p)) // _loop0_102 - ) - { - D(fprintf(stderr, "%*c+ _gather_101[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_102")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_101[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_102")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_103: for_if_clause -static asdl_seq * -_loop1_103_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // for_if_clause - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_103[%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 - ) - { - _res = for_if_clause_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_103[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_103_type, _seq); - p->level--; - return _seq; -} - -// _loop0_104: ('if' disjunction) -static asdl_seq * -_loop0_104_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ('if' disjunction) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_145_var; - while ( - (_tmp_145_var = _tmp_145_rule(p)) // 'if' disjunction - ) - { - _res = _tmp_145_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_104[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_104_type, _seq); - p->level--; - return _seq; -} - -// _loop0_105: ('if' disjunction) -static asdl_seq * -_loop0_105_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ('if' disjunction) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_146_var; - while ( - (_tmp_146_var = _tmp_146_rule(p)) // 'if' disjunction - ) - { - _res = _tmp_146_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_105[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_105_type, _seq); - p->level--; - return _seq; -} - -// _loop0_107: ',' (starred_expression | named_expression !'=') -static asdl_seq * -_loop0_107_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' (starred_expression | named_expression !'=') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | named_expression !'=')")); - Token * _literal; - void *elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = _tmp_147_rule(p)) // starred_expression | named_expression !'=' - ) - { - _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) { - 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, "',' (starred_expression | named_expression !'=')")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_107_type, _seq); - p->level--; - return _seq; -} - -// _gather_106: (starred_expression | named_expression !'=') _loop0_107 -static asdl_seq * -_gather_106_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // (starred_expression | named_expression !'=') _loop0_107 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | named_expression !'=') _loop0_107")); - void *elem; - asdl_seq * seq; - if ( - (elem = _tmp_147_rule(p)) // starred_expression | named_expression !'=' - && - (seq = _loop0_107_rule(p)) // _loop0_107 - ) - { - D(fprintf(stderr, "%*c+ _gather_106[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | named_expression !'=') _loop0_107")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_106[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | named_expression !'=') _loop0_107")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_108: ',' kwargs -static void * -_tmp_108_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; - { // ',' kwargs - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); - Token * _literal; - asdl_seq* k; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (k = kwargs_rule(p)) // kwargs - ) - { - D(fprintf(stderr, "%*c+ _tmp_108[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); - _res = k; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_108[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_110: ',' kwarg_or_starred -static asdl_seq * -_loop0_110_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' kwarg_or_starred - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); - Token * _literal; - KeywordOrStarred* elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred - ) - { - _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) { - 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_110[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_110_type, _seq); - p->level--; - return _seq; -} - -// _gather_109: kwarg_or_starred _loop0_110 -static asdl_seq * -_gather_109_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // kwarg_or_starred _loop0_110 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_110")); - KeywordOrStarred* elem; - asdl_seq * seq; - if ( - (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred - && - (seq = _loop0_110_rule(p)) // _loop0_110 - ) - { - D(fprintf(stderr, "%*c+ _gather_109[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_110")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_109[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_110")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_112: ',' kwarg_or_double_starred -static asdl_seq * -_loop0_112_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' kwarg_or_double_starred - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); - Token * _literal; - KeywordOrStarred* elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred - ) - { - _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) { - 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_112[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq); - p->level--; - return _seq; -} - -// _gather_111: kwarg_or_double_starred _loop0_112 -static asdl_seq * -_gather_111_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // kwarg_or_double_starred _loop0_112 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_112")); - KeywordOrStarred* elem; - asdl_seq * seq; - if ( - (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred - && - (seq = _loop0_112_rule(p)) // _loop0_112 - ) - { - D(fprintf(stderr, "%*c+ _gather_111[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_112")); - _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, "kwarg_or_double_starred _loop0_112")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_114: ',' kwarg_or_starred -static asdl_seq * -_loop0_114_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' kwarg_or_starred - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); - Token * _literal; - KeywordOrStarred* elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred - ) - { - _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) { - 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_114[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq); - p->level--; - return _seq; -} - -// _gather_113: kwarg_or_starred _loop0_114 -static asdl_seq * -_gather_113_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // kwarg_or_starred _loop0_114 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_114")); - KeywordOrStarred* elem; - asdl_seq * seq; - if ( - (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred - && - (seq = _loop0_114_rule(p)) // _loop0_114 - ) - { - D(fprintf(stderr, "%*c+ _gather_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_114")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_113[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_114")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_116: ',' kwarg_or_double_starred -static asdl_seq * -_loop0_116_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' kwarg_or_double_starred - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); - Token * _literal; - KeywordOrStarred* elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred - ) - { - _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) { - 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_116[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_116_type, _seq); - p->level--; - return _seq; -} - -// _gather_115: kwarg_or_double_starred _loop0_116 -static asdl_seq * -_gather_115_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // kwarg_or_double_starred _loop0_116 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_116")); - KeywordOrStarred* elem; - asdl_seq * seq; - if ( - (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred - && - (seq = _loop0_116_rule(p)) // _loop0_116 - ) - { - D(fprintf(stderr, "%*c+ _gather_115[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_116")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_115[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_116")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_117: (',' star_target) -static asdl_seq * -_loop0_117_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // (',' star_target) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_148_var; - while ( - (_tmp_148_var = _tmp_148_rule(p)) // ',' star_target - ) - { - _res = _tmp_148_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_117[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_117_type, _seq); - p->level--; - return _seq; -} - -// _loop0_119: ',' star_target -static asdl_seq * -_loop0_119_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' star_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = star_target_rule(p)) // 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) { - 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_119[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_119_type, _seq); - p->level--; - return _seq; -} - -// _gather_118: star_target _loop0_119 -static asdl_seq * -_gather_118_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // star_target _loop0_119 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_119")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = star_target_rule(p)) // star_target - && - (seq = _loop0_119_rule(p)) // _loop0_119 - ) - { - D(fprintf(stderr, "%*c+ _gather_118[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_119")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_118[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_119")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_120: (',' star_target) -static asdl_seq * -_loop1_120_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // (',' star_target) - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_149_var; - while ( - (_tmp_149_var = _tmp_149_rule(p)) // ',' star_target - ) - { - _res = _tmp_149_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_120[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_120_type, _seq); - p->level--; - return _seq; -} - -// _tmp_121: !'*' star_target -static void * -_tmp_121_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; - { // !'*' star_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_121[%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='*' - && - (star_target_var = star_target_rule(p)) // star_target - ) - { - D(fprintf(stderr, "%*c+ _tmp_121[%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_121[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_123: ',' del_target -static asdl_seq * -_loop0_123_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // ',' del_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = del_target_rule(p)) // del_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) { - 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_123[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_123_type, _seq); - p->level--; - return _seq; -} - -// _gather_122: del_target _loop0_123 -static asdl_seq * -_gather_122_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // del_target _loop0_123 - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _gather_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_123")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = del_target_rule(p)) // del_target - && - (seq = _loop0_123_rule(p)) // _loop0_123 - ) - { - D(fprintf(stderr, "%*c+ _gather_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_123")); - _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, "del_target _loop0_123")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_124: args | expression for_if_clauses -static void * -_tmp_124_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; - { // args - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_124[%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_124[%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_124[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); - } - { // expression for_if_clauses - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); - expr_ty expression_var; - asdl_seq* for_if_clauses_var; - if ( - (expression_var = expression_rule(p)) // expression - && - (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses - ) - { - D(fprintf(stderr, "%*c+ _tmp_124[%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_124[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_125: NAME '=' -static void * -_tmp_125_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; - { // NAME '=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_125[%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_125[%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_125[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_126: star_named_expressions -static asdl_seq * -_loop0_126_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // star_named_expressions - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); - asdl_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) { - 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_126[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_126_type, _seq); - p->level--; - return _seq; -} - -// _loop0_127: (star_targets '=') -static asdl_seq * -_loop0_127_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // (star_targets '=') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_150_var; - while ( - (_tmp_150_var = _tmp_150_rule(p)) // star_targets '=' - ) - { - _res = _tmp_150_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_127[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq); - p->level--; - return _seq; -} - -// _loop0_128: (star_targets '=') -static asdl_seq * -_loop0_128_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // (star_targets '=') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_151_var; - while ( - (_tmp_151_var = _tmp_151_rule(p)) // star_targets '=' - ) - { - _res = _tmp_151_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_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_128[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); - p->level--; - return _seq; -} - -// _tmp_129: yield_expr | star_expressions -static void * -_tmp_129_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; - { // yield_expr - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_129[%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_129[%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_129[%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_129[%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_129[%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_129[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_130: '[' | '(' | '{' -static void * -_tmp_130_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; - { // '[' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - ) - { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%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_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - ) - { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%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_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - ) - { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_131: param_no_default -static asdl_seq * -_loop0_131_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_131[%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 - ) - { - _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) { - 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_131[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_131_type, _seq); - p->level--; - return _seq; -} - -// _tmp_132: slash_with_default | param_with_default+ -static void * -_tmp_132_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; - { // slash_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_132[%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+ _tmp_132[%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_132[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); - } - { // param_with_default+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_152_var; - if ( - (_loop1_152_var = _loop1_152_rule(p)) // param_with_default+ - ) - { - D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_152_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop0_133: lambda_param_no_default -static asdl_seq * -_loop0_133_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_133[%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) { - 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_133[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - asdl_seq *_seq = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_133_type, _seq); - p->level--; - return _seq; -} - -// _tmp_134: lambda_slash_with_default | lambda_param_with_default+ -static void * -_tmp_134_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_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_134[%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_134[%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_134[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); - } - { // lambda_param_with_default+ - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_153_var; - if ( - (_loop1_153_var = _loop1_153_rule(p)) // lambda_param_with_default+ - ) - { - D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_153_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_135: ')' | ',' (')' | '**') -static void * -_tmp_135_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; - { // ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_135[%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_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - Token * _literal; - void *_tmp_154_var; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_tmp_154_var = _tmp_154_rule(p)) // ')' | '**' - ) - { - D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_154_var); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_136: ':' | ',' (':' | '**') -static void * -_tmp_136_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; - { // ':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - ) - { - D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_136[%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_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - Token * _literal; - void *_tmp_155_var; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_tmp_155_var = _tmp_155_rule(p)) // ':' | '**' - ) - { - D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_155_var); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_137: star_targets '=' -static void * -_tmp_137_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; - { // star_targets '=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); - Token * _literal; - expr_ty z; - if ( - (z = star_targets_rule(p)) // star_targets - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); - _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_137[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_138: '.' | '...' -static void * -_tmp_138_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; - { // '.' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - ) - { - D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_138[%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_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 52)) // token='...' - ) - { - D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_139: '.' | '...' -static void * -_tmp_139_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; - { // '.' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - ) - { - D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_139[%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_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 52)) // token='...' - ) - { - D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_140: '@' named_expression NEWLINE -static void * -_tmp_140_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; - { // '@' named_expression NEWLINE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); - Token * _literal; - expr_ty f; - Token * newline_var; - if ( - (_literal = _PyPegen_expect_token(p, 49)) // token='@' - && - (f = named_expression_rule(p)) // named_expression - && - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' - ) - { - D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); - _res = f; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_141: ',' star_expression -static void * -_tmp_141_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; - { // ',' star_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); - Token * _literal; - expr_ty c; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (c = star_expression_rule(p)) // star_expression - ) - { - D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); - _res = c; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_142: ',' expression -static void * -_tmp_142_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; - { // ',' expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); - Token * _literal; - expr_ty c; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (c = expression_rule(p)) // expression - ) - { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); - _res = c; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_143: 'or' conjunction -static void * -_tmp_143_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; - { // 'or' conjunction - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); - Token * _keyword; - expr_ty c; - if ( - (_keyword = _PyPegen_expect_token(p, 532)) // token='or' - && - (c = conjunction_rule(p)) // conjunction - ) - { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); - _res = c; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_144: 'and' inversion -static void * -_tmp_144_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; - { // 'and' inversion - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); - Token * _keyword; - expr_ty c; - if ( - (_keyword = _PyPegen_expect_token(p, 533)) // token='and' - && - (c = inversion_rule(p)) // inversion - ) - { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); - _res = c; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_145: 'if' disjunction -static void * -_tmp_145_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; - { // 'if' disjunction - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); - Token * _keyword; - expr_ty z; - if ( - (_keyword = _PyPegen_expect_token(p, 510)) // token='if' - && - (z = disjunction_rule(p)) // disjunction - ) - { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); - _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_145[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_146: 'if' disjunction -static void * -_tmp_146_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; - { // 'if' disjunction - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); - Token * _keyword; - expr_ty z; - if ( - (_keyword = _PyPegen_expect_token(p, 510)) // token='if' - && - (z = disjunction_rule(p)) // disjunction - ) - { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); - _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_146[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_147: starred_expression | named_expression !'=' -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; - } - void * _res = NULL; - int _mark = p->mark; - { // starred_expression - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_147[%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_147[%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_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); - } - { // named_expression !'=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_147[%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 - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_147[%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_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression !'='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_148: ',' star_target -static void * -_tmp_148_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; - { // ',' star_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); - Token * _literal; - expr_ty c; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (c = star_target_rule(p)) // star_target - ) - { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); - _res = c; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "',' star_target")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_149: ',' star_target -static void * -_tmp_149_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; - { // ',' star_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); - Token * _literal; - expr_ty c; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (c = star_target_rule(p)) // star_target - ) - { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); - _res = c; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - 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, "',' star_target")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_150: star_targets '=' -static void * -_tmp_150_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; - { // star_targets '=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); - Token * _literal; - expr_ty star_targets_var; - if ( - (star_targets_var = star_targets_rule(p)) // star_targets - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_150[%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_150[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_151: star_targets '=' -static void * -_tmp_151_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; - { // star_targets '=' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); - Token * _literal; - expr_ty star_targets_var; - if ( - (star_targets_var = star_targets_rule(p)) // star_targets - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_151[%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_151[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_152: param_with_default -static asdl_seq * -_loop1_152_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_152[%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 - ) - { - _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) { - 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_152[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_152_type, _seq); - p->level--; - return _seq; -} - -// _loop1_153: lambda_param_with_default -static asdl_seq * -_loop1_153_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; - } - ssize_t _children_capacity = 1; - ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_153[%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) { - 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_153[%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 = _Py_asdl_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(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_153_type, _seq); - p->level--; - return _seq; -} - -// _tmp_154: ')' | '**' -static void * -_tmp_154_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; - { // ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); - _res = _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, "')'")); - } - { // '**' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - ) - { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); - _res = _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, "'**'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_155: ':' | '**' -static void * -_tmp_155_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; - { // ':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - ) - { - D(fprintf(stderr, "%*c+ _tmp_155[%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, "':'")); - } - { // '**' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - ) - { - D(fprintf(stderr, "%*c+ _tmp_155[%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, "'**'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -void * -_PyPegen_parse(Parser *p) -{ - // Initialize keywords - p->keywords = reserved_keywords; - p->n_keyword_lists = n_keyword_lists; - - // Run parser - void *result = NULL; - if (p->start_rule == Py_file_input) { - result = file_rule(p); - } else if (p->start_rule == Py_single_input) { - result = interactive_rule(p); - } else if (p->start_rule == Py_eval_input) { - result = eval_rule(p); - } else if (p->start_rule == Py_func_type_input) { - result = func_type_rule(p); - } else if (p->start_rule == Py_fstring_input) { - result = fstring_rule(p); - } - - return result; -} - -// The end diff --git a/contrib/tools/python3/src/Parser/pegen/parse_string.c b/contrib/tools/python3/src/Parser/pegen/parse_string.c deleted file mode 100644 index 15a132b4e05..00000000000 --- a/contrib/tools/python3/src/Parser/pegen/parse_string.c +++ /dev/null @@ -1,1241 +0,0 @@ -#include - -#include - -#include "../tokenizer.h" -#include "pegen.h" -#include "parse_string.h" - -//// STRING HANDLING FUNCTIONS //// - -// These functions are ported directly from Python/ast.c with some modifications -// to account for the use of "Parser *p", the fact that don't have parser nodes -// to pass around and the usage of some specialized APIs present only in this -// file (like "_PyPegen_raise_syntax_error"). - -static int -warn_invalid_escape_sequence(Parser *p, unsigned char first_invalid_escape_char, Token *t) -{ - PyObject *msg = - PyUnicode_FromFormat("invalid escape sequence \\%c", first_invalid_escape_char); - if (msg == NULL) { - return -1; - } - if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg, p->tok->filename, - t->lineno, NULL, NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { - /* Replace the DeprecationWarning exception with a SyntaxError - to get a more accurate error report */ - PyErr_Clear(); - - /* This is needed, in order for the SyntaxError to point to the token t, - since _PyPegen_raise_error uses p->tokens[p->fill - 1] for the - error location, if p->known_err_token is not set. */ - p->known_err_token = t; - RAISE_SYNTAX_ERROR("invalid escape sequence \\%c", first_invalid_escape_char); - } - Py_DECREF(msg); - return -1; - } - Py_DECREF(msg); - return 0; -} - -static PyObject * -decode_utf8(const char **sPtr, const char *end) -{ - const char *s; - const char *t; - t = s = *sPtr; - while (s < end && (*s & 0x80)) { - s++; - } - *sPtr = s; - return PyUnicode_DecodeUTF8(t, s - t, NULL); -} - -static PyObject * -decode_unicode_with_escapes(Parser *parser, const char *s, size_t len, Token *t) -{ - PyObject *v; - PyObject *u; - char *buf; - char *p; - const char *end; - - /* check for integer overflow */ - if (len > SIZE_MAX / 6) { - return NULL; - } - /* "ä" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5 - "\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */ - u = PyBytes_FromStringAndSize((char *)NULL, len * 6); - if (u == NULL) { - return NULL; - } - p = buf = PyBytes_AsString(u); - if (p == NULL) { - return NULL; - } - end = s + len; - while (s < end) { - if (*s == '\\') { - *p++ = *s++; - if (s >= end || *s & 0x80) { - strcpy(p, "u005c"); - p += 5; - if (s >= end) { - break; - } - } - } - if (*s & 0x80) { - PyObject *w; - int kind; - void *data; - Py_ssize_t w_len; - Py_ssize_t i; - w = decode_utf8(&s, end); - if (w == NULL) { - Py_DECREF(u); - return NULL; - } - kind = PyUnicode_KIND(w); - data = PyUnicode_DATA(w); - w_len = PyUnicode_GET_LENGTH(w); - for (i = 0; i < w_len; i++) { - Py_UCS4 chr = PyUnicode_READ(kind, data, i); - sprintf(p, "\\U%08x", chr); - p += 10; - } - /* Should be impossible to overflow */ - assert(p - buf <= PyBytes_GET_SIZE(u)); - Py_DECREF(w); - } - else { - *p++ = *s++; - } - } - len = p - buf; - s = buf; - - const char *first_invalid_escape; - v = _PyUnicode_DecodeUnicodeEscapeInternal(s, len, NULL, NULL, &first_invalid_escape); - - if (v != NULL && first_invalid_escape != 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. */ - Py_XDECREF(u); - Py_DECREF(v); - return NULL; - } - } - Py_XDECREF(u); - return v; -} - -static PyObject * -decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t) -{ - const char *first_invalid_escape; - PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, &first_invalid_escape); - if (result == NULL) { - return NULL; - } - - if (first_invalid_escape != NULL) { - if (warn_invalid_escape_sequence(p, *first_invalid_escape, t) < 0) { - Py_DECREF(result); - return NULL; - } - } - 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) -{ - const char *s = PyBytes_AsString(t->bytes); - if (s == NULL) { - return -1; - } - - size_t len; - int quote = Py_CHARMASK(*s); - int fmode = 0; - *bytesmode = 0; - *rawmode = 0; - *result = NULL; - *fstr = NULL; - if (Py_ISALPHA(quote)) { - while (!*bytesmode || !*rawmode) { - if (quote == 'b' || quote == 'B') { - quote =(unsigned char)*++s; - *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; - } - else { - break; - } - } - } - - /* 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; - } - /* 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; - } - if (s[--len] != quote) { - /* Last quote char must match the first. */ - PyErr_BadInternalCall(); - return -1; - } - if (len >= 4 && s[0] == quote && s[1] == quote) { - /* A triple quoted string. We've already skipped one quote at - the start and one at the end of the string. Now skip the - two at the start. */ - s += 2; - len -= 2; - /* And check that the last two match. */ - if (s[--len] != quote || s[--len] != quote) { - PyErr_BadInternalCall(); - return -1; - } - } - - 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) { - /* Disallow non-ASCII characters. */ - const char *ch; - for (ch = s; *ch; ch++) { - if (Py_CHARMASK(*ch) >= 0x80) { - RAISE_SYNTAX_ERROR( - "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) { - 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); - } - /* 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) { - 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; - - Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version, - NULL, p->arena); - p2->starting_lineno = t->lineno + lines - 1; - p2->starting_col_offset = 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, ch, 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; - } - - /* 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 = 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_seq * -ExprList_Finish(ExprList *l, PyArena *arena) -{ - asdl_seq *seq; - - ExprList_check_invariants(l); - - /* Allocate the asdl_seq and copy the expressions in to it. */ - seq = _Py_asdl_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 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) { - /* Do nothing. No previous literal. */ - } else { - /* 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_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 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; - } - } - /* This has already been freed. */ - assert(state->last_str == NULL); - - seq = ExprList_Finish(&state->expr_list, p->arena); - if (!seq) { - goto error; - } - - return _Py_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); -} diff --git a/contrib/tools/python3/src/Parser/pegen/parse_string.h b/contrib/tools/python3/src/Parser/pegen/parse_string.h deleted file mode 100644 index cd85bd57d0a..00000000000 --- a/contrib/tools/python3/src/Parser/pegen/parse_string.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef STRINGS_H -#define STRINGS_H - -#include -#include -#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 *); - -#endif diff --git a/contrib/tools/python3/src/Parser/pegen/peg_api.c b/contrib/tools/python3/src/Parser/pegen/peg_api.c deleted file mode 100644 index 5e71ecdb13c..00000000000 --- a/contrib/tools/python3/src/Parser/pegen/peg_api.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "pegen_interface.h" - -#include "../tokenizer.h" -#include "pegen.h" - -mod_ty -PyPegen_ASTFromString(const char *str, const char *filename, int mode, - PyCompilerFlags *flags, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - mod_ty result = PyPegen_ASTFromStringObject(str, filename_ob, mode, flags, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyPegen_ASTFromStringObject(const char *str, PyObject* filename, int mode, - PyCompilerFlags *flags, PyArena *arena) -{ - if (PySys_Audit("compile", "yO", str, filename) < 0) { - return NULL; - } - - mod_ty result = _PyPegen_run_parser_from_string(str, mode, filename, flags, arena); - return result; -} - -mod_ty -PyPegen_ASTFromFilename(const char *filename, int mode, PyCompilerFlags *flags, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - - mod_ty result = _PyPegen_run_parser_from_file(filename, mode, filename_ob, flags, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyPegen_ASTFromFileObject(FILE *fp, PyObject *filename_ob, int mode, - const char *enc, const char *ps1, const char* ps2, - PyCompilerFlags *flags, int *errcode, PyArena *arena) -{ - if (PySys_Audit("compile", "OO", Py_None, filename_ob) < 0) { - return NULL; - } - return _PyPegen_run_parser_from_file_pointer(fp, mode, filename_ob, enc, ps1, ps2, - flags, errcode, arena); -} diff --git a/contrib/tools/python3/src/Parser/pegen/pegen.c b/contrib/tools/python3/src/Parser/pegen/pegen.c deleted file mode 100644 index cdfbc12d16a..00000000000 --- a/contrib/tools/python3/src/Parser/pegen/pegen.c +++ /dev/null @@ -1,2280 +0,0 @@ -#include -#include -#include "../tokenizer.h" - -#include "pegen.h" -#include "parse_string.h" -#include "ast.h" - -PyObject * -_PyPegen_new_type_comment(Parser *p, char *s) -{ - PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL); - if (res == NULL) { - return NULL; - } - if (PyArena_AddPyObject(p->arena, res) < 0) { - Py_DECREF(res); - return NULL; - } - return res; -} - -arg_ty -_PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc) -{ - if (tc == NULL) { - return a; - } - char *bytes = PyBytes_AsString(tc->bytes); - if (bytes == NULL) { - return NULL; - } - PyObject *tco = _PyPegen_new_type_comment(p, bytes); - if (tco == NULL) { - return NULL; - } - return arg(a->arg, a->annotation, tco, - a->lineno, a->col_offset, a->end_lineno, a->end_col_offset, - p->arena); -} - -static int -init_normalization(Parser *p) -{ - if (p->normalize) { - return 1; - } - PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); - if (!m) - { - return 0; - } - p->normalize = PyObject_GetAttrString(m, "normalize"); - Py_DECREF(m); - if (!p->normalize) - { - return 0; - } - return 1; -} - -/* Checks if the NOTEQUAL token is valid given the current parser flags -0 indicates success and nonzero indicates failure (an exception may be set) */ -int -_PyPegen_check_barry_as_flufl(Parser *p, Token* t) { - assert(t->bytes != NULL); - assert(t->type == NOTEQUAL); - - char* tok_str = PyBytes_AS_STRING(t->bytes); - if (p->flags & PyPARSE_BARRY_AS_BDFL && strcmp(tok_str, "<>") != 0) { - RAISE_SYNTAX_ERROR("with Barry as BDFL, use '<>' instead of '!='"); - return -1; - } - if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) { - return strcmp(tok_str, "!="); - } - return 0; -} - -PyObject * -_PyPegen_new_identifier(Parser *p, char *n) -{ - PyObject *id = PyUnicode_DecodeUTF8(n, strlen(n), NULL); - if (!id) { - goto error; - } - /* PyUnicode_DecodeUTF8 should always return a ready string. */ - assert(PyUnicode_IS_READY(id)); - /* Check whether there are non-ASCII characters in the - identifier; if so, normalize to NFKC. */ - if (!PyUnicode_IS_ASCII(id)) - { - PyObject *id2; - if (!init_normalization(p)) - { - Py_DECREF(id); - goto error; - } - PyObject *form = PyUnicode_InternFromString("NFKC"); - if (form == NULL) - { - Py_DECREF(id); - goto error; - } - PyObject *args[2] = {form, id}; - id2 = _PyObject_FastCall(p->normalize, args, 2); - Py_DECREF(id); - Py_DECREF(form); - if (!id2) { - goto error; - } - if (!PyUnicode_Check(id2)) - { - PyErr_Format(PyExc_TypeError, - "unicodedata.normalize() must return a string, not " - "%.200s", - _PyType_Name(Py_TYPE(id2))); - Py_DECREF(id2); - goto error; - } - id = id2; - } - PyUnicode_InternInPlace(&id); - if (PyArena_AddPyObject(p->arena, id) < 0) - { - Py_DECREF(id); - goto error; - } - return id; - -error: - p->error_indicator = 1; - return NULL; -} - -static PyObject * -_create_dummy_identifier(Parser *p) -{ - return _PyPegen_new_identifier(p, ""); -} - -static inline Py_ssize_t -byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) -{ - const char *str = PyUnicode_AsUTF8(line); - if (!str) { - return 0; - } - assert(col_offset >= 0 && (unsigned long)col_offset <= strlen(str)); - PyObject *text = PyUnicode_DecodeUTF8(str, col_offset, "replace"); - if (!text) { - return 0; - } - Py_ssize_t size = PyUnicode_GET_LENGTH(text); - Py_DECREF(text); - return size; -} - -const char * -_PyPegen_get_expr_name(expr_ty e) -{ - assert(e != NULL); - switch (e->kind) { - case Attribute_kind: - return "attribute"; - case Subscript_kind: - return "subscript"; - case Starred_kind: - return "starred"; - case Name_kind: - return "name"; - case List_kind: - return "list"; - case Tuple_kind: - return "tuple"; - case Lambda_kind: - return "lambda"; - case Call_kind: - return "function call"; - case BoolOp_kind: - case BinOp_kind: - case UnaryOp_kind: - return "operator"; - case GeneratorExp_kind: - return "generator expression"; - case Yield_kind: - case YieldFrom_kind: - return "yield expression"; - case Await_kind: - return "await expression"; - case ListComp_kind: - return "list comprehension"; - case SetComp_kind: - return "set comprehension"; - case DictComp_kind: - return "dict comprehension"; - case Dict_kind: - return "dict display"; - case Set_kind: - return "set display"; - case JoinedStr_kind: - case FormattedValue_kind: - return "f-string expression"; - case Constant_kind: { - PyObject *value = e->v.Constant.value; - if (value == Py_None) { - return "None"; - } - if (value == Py_False) { - return "False"; - } - if (value == Py_True) { - return "True"; - } - if (value == Py_Ellipsis) { - return "Ellipsis"; - } - return "literal"; - } - case Compare_kind: - return "comparison"; - case IfExp_kind: - return "conditional expression"; - case NamedExpr_kind: - return "named expression"; - default: - PyErr_Format(PyExc_SystemError, - "unexpected expression in assignment %d (line %d)", - e->kind, e->lineno); - return NULL; - } -} - -static int -raise_decode_error(Parser *p) -{ - assert(PyErr_Occurred()); - const char *errtype = NULL; - if (PyErr_ExceptionMatches(PyExc_UnicodeError)) { - errtype = "unicode error"; - } - else if (PyErr_ExceptionMatches(PyExc_ValueError)) { - errtype = "value error"; - } - if (errtype) { - PyObject *type; - PyObject *value; - PyObject *tback; - PyObject *errstr; - PyErr_Fetch(&type, &value, &tback); - errstr = PyObject_Str(value); - if (errstr) { - RAISE_SYNTAX_ERROR("(%s) %U", errtype, errstr); - Py_DECREF(errstr); - } - else { - PyErr_Clear(); - RAISE_SYNTAX_ERROR("(%s) unknown error", errtype); - } - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(tback); - } - - return -1; -} - -static void -raise_tokenizer_init_error(PyObject *filename) -{ - if (!(PyErr_ExceptionMatches(PyExc_LookupError) - || PyErr_ExceptionMatches(PyExc_SyntaxError) - || PyErr_ExceptionMatches(PyExc_ValueError) - || PyErr_ExceptionMatches(PyExc_UnicodeDecodeError))) { - return; - } - PyObject *errstr = NULL; - PyObject *tuple = NULL; - PyObject *type; - PyObject *value; - PyObject *tback; - PyErr_Fetch(&type, &value, &tback); - errstr = PyObject_Str(value); - if (!errstr) { - goto error; - } - - PyObject *tmp = Py_BuildValue("(OiiO)", filename, 0, -1, Py_None); - if (!tmp) { - goto error; - } - - tuple = PyTuple_Pack(2, errstr, tmp); - Py_DECREF(tmp); - if (!value) { - goto error; - } - PyErr_SetObject(PyExc_SyntaxError, tuple); - -error: - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(tback); - Py_XDECREF(errstr); - Py_XDECREF(tuple); -} - -static int -tokenizer_error(Parser *p) -{ - if (PyErr_Occurred()) { - return -1; - } - - const char *msg = NULL; - PyObject* errtype = PyExc_SyntaxError; - Py_ssize_t col_offset = -1; - switch (p->tok->done) { - case E_TOKEN: - msg = "invalid token"; - break; - case E_EOFS: - RAISE_SYNTAX_ERROR("EOF while scanning triple-quoted string literal"); - return -1; - case E_EOLS: - RAISE_SYNTAX_ERROR("EOL while scanning string literal"); - return -1; - case E_EOF: - RAISE_SYNTAX_ERROR("unexpected EOF while parsing"); - return -1; - case E_DEDENT: - RAISE_INDENTATION_ERROR("unindent does not match any outer indentation level"); - return -1; - 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: { - col_offset = p->tok->cur - p->tok->buf - 1; - msg = "unexpected character after line continuation character"; - break; - } - default: - msg = "unknown parsing error"; - } - - RAISE_ERROR_KNOWN_LOCATION(p, errtype, p->tok->lineno, - col_offset >= 0 ? col_offset : 0, msg); - return -1; -} - -void * -_PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...) -{ - if (p->fill == 0) { - va_list va; - va_start(va, errmsg); - _PyPegen_raise_error_known_location(p, errtype, 0, 0, errmsg, va); - va_end(va); - return NULL; - } - - Token *t = p->known_err_token != NULL ? p->known_err_token : p->tokens[p->fill - 1]; - Py_ssize_t col_offset; - if (t->col_offset == -1) { - col_offset = Py_SAFE_DOWNCAST(p->tok->cur - p->tok->buf, - intptr_t, int); - } else { - col_offset = t->col_offset + 1; - } - - va_list va; - va_start(va, errmsg); - _PyPegen_raise_error_known_location(p, errtype, t->lineno, - col_offset, errmsg, va); - va_end(va); - - return NULL; -} - -void * -_PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, - Py_ssize_t lineno, Py_ssize_t col_offset, - const char *errmsg, va_list va) -{ - PyObject *value = NULL; - PyObject *errstr = NULL; - PyObject *error_line = NULL; - PyObject *tmp = NULL; - p->error_indicator = 1; - - if (p->start_rule == Py_fstring_input) { - const char *fstring_msg = "f-string: "; - Py_ssize_t len = strlen(fstring_msg) + strlen(errmsg); - - char *new_errmsg = PyMem_RawMalloc(len + 1); // Lengths of both strings plus NULL character - if (!new_errmsg) { - return (void *) PyErr_NoMemory(); - } - - // Copy both strings into new buffer - memcpy(new_errmsg, fstring_msg, strlen(fstring_msg)); - memcpy(new_errmsg + strlen(fstring_msg), errmsg, strlen(errmsg)); - new_errmsg[len] = 0; - errmsg = new_errmsg; - } - errstr = PyUnicode_FromFormatV(errmsg, va); - if (!errstr) { - goto error; - } - - if (p->start_rule == Py_file_input) { - error_line = PyErr_ProgramTextObject(p->tok->filename, (int) lineno); - } - - if (!error_line) { - Py_ssize_t size = p->tok->inp - p->tok->buf; - error_line = PyUnicode_DecodeUTF8(p->tok->buf, size, "replace"); - if (!error_line) { - goto error; - } - } - - if (p->start_rule == Py_fstring_input) { - col_offset -= p->starting_col_offset; - } - Py_ssize_t col_number = col_offset; - - if (p->tok->encoding != NULL) { - col_number = byte_offset_to_character_offset(error_line, col_offset); - } - - tmp = Py_BuildValue("(OiiN)", p->tok->filename, lineno, col_number, error_line); - if (!tmp) { - goto error; - } - value = PyTuple_Pack(2, errstr, tmp); - Py_DECREF(tmp); - if (!value) { - goto error; - } - PyErr_SetObject(errtype, value); - - Py_DECREF(errstr); - Py_DECREF(value); - if (p->start_rule == Py_fstring_input) { - PyMem_RawFree((void *)errmsg); - } - return NULL; - -error: - Py_XDECREF(errstr); - Py_XDECREF(error_line); - if (p->start_rule == Py_fstring_input) { - PyMem_RawFree((void *)errmsg); - } - return NULL; -} - -#if 0 -static const char * -token_name(int type) -{ - if (0 <= type && type <= N_TOKENS) { - return _PyParser_TokenNames[type]; - } - return ""; -} -#endif - -// Here, mark is the start of the node, while p->mark is the end. -// If node==NULL, they should be the same. -int -_PyPegen_insert_memo(Parser *p, int mark, int type, void *node) -{ - // Insert in front - Memo *m = PyArena_Malloc(p->arena, sizeof(Memo)); - if (m == NULL) { - return -1; - } - m->type = type; - m->node = node; - m->mark = p->mark; - m->next = p->tokens[mark]->memo; - p->tokens[mark]->memo = m; - return 0; -} - -// Like _PyPegen_insert_memo(), but updates an existing node if found. -int -_PyPegen_update_memo(Parser *p, int mark, int type, void *node) -{ - for (Memo *m = p->tokens[mark]->memo; m != NULL; m = m->next) { - if (m->type == type) { - // Update existing node. - m->node = node; - m->mark = p->mark; - return 0; - } - } - // Insert new node. - return _PyPegen_insert_memo(p, mark, type, node); -} - -// Return dummy NAME. -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 = Name(id, Load, 1, 0, 1, 0, p->arena); - return cache; -} - -static int -_get_keyword_or_name_type(Parser *p, const char *name, int name_len) -{ - 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) { - return k->type; - } - } - return NAME; -} - -static int -growable_comment_array_init(growable_comment_array *arr, size_t initial_size) { - assert(initial_size > 0); - arr->items = PyMem_Malloc(initial_size * sizeof(*arr->items)); - arr->size = initial_size; - arr->num_items = 0; - - return arr->items != NULL; -} - -static int -growable_comment_array_add(growable_comment_array *arr, int lineno, char *comment) { - if (arr->num_items >= arr->size) { - size_t new_size = arr->size * 2; - void *new_items_array = PyMem_Realloc(arr->items, new_size * sizeof(*arr->items)); - if (!new_items_array) { - return 0; - } - arr->items = new_items_array; - arr->size = new_size; - } - - arr->items[arr->num_items].lineno = lineno; - arr->items[arr->num_items].comment = comment; // Take ownership - arr->num_items++; - return 1; -} - -static void -growable_comment_array_deallocate(growable_comment_array *arr) { - for (unsigned i = 0; i < arr->num_items; i++) { - PyMem_Free(arr->items[i].comment); - } - PyMem_Free(arr->items); -} - -int -_PyPegen_fill_token(Parser *p) -{ - const char *start; - const char *end; - int type = PyTokenizer_Get(p->tok, &start, &end); - - // Record and skip '# type: ignore' comments - while (type == TYPE_IGNORE) { - Py_ssize_t len = end - start; - char *tag = PyMem_Malloc(len + 1); - if (tag == NULL) { - PyErr_NoMemory(); - return -1; - } - strncpy(tag, 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; - } - type = PyTokenizer_Get(p->tok, &start, &end); - } - - if (type == ENDMARKER && p->start_rule == Py_single_input && p->parsing_started) { - type = NEWLINE; /* Add an extra newline */ - p->parsing_started = 0; - - if (p->tok->indent && !(p->flags & PyPARSE_DONT_IMPLY_DEDENT)) { - p->tok->pendin = -p->tok->indent; - p->tok->indent = 0; - } - } - else { - p->parsing_started = 1; - } - - if (p->fill == p->size) { - int newsize = p->size * 2; - Token **new_tokens = PyMem_Realloc(p->tokens, newsize * sizeof(Token *)); - if (new_tokens == NULL) { - PyErr_NoMemory(); - return -1; - } - p->tokens = new_tokens; - - for (int i = p->size; i < newsize; i++) { - p->tokens[i] = PyMem_Malloc(sizeof(Token)); - if (p->tokens[i] == NULL) { - p->size = i; // Needed, in order to cleanup correctly after parser fails - PyErr_NoMemory(); - return -1; - } - memset(p->tokens[i], '\0', sizeof(Token)); - } - p->size = newsize; - } - - Token *t = p->tokens[p->fill]; - t->type = (type == NAME) ? _get_keyword_or_name_type(p, start, (int)(end - start)) : type; - t->bytes = PyBytes_FromStringAndSize(start, end - start); - if (t->bytes == NULL) { - return -1; - } - if (PyArena_AddPyObject(p->arena, t->bytes) < 0) { - Py_DECREF(t->bytes); - return -1; - } - - int lineno = type == STRING ? p->tok->first_lineno : p->tok->lineno; - const char *line_start = type == STRING ? p->tok->multi_line_start : p->tok->line_start; - int end_lineno = p->tok->lineno; - int col_offset = -1; - int end_col_offset = -1; - if (start != NULL && start >= line_start) { - col_offset = (int)(start - line_start); - } - if (end != NULL && end >= p->tok->line_start) { - end_col_offset = (int)(end - p->tok->line_start); - } - - t->lineno = p->starting_lineno + lineno; - t->col_offset = p->tok->lineno == 1 ? p->starting_col_offset + col_offset : col_offset; - t->end_lineno = p->starting_lineno + end_lineno; - t->end_col_offset = p->tok->lineno == 1 ? p->starting_col_offset + end_col_offset : end_col_offset; - - p->fill += 1; - - if (type == ERRORTOKEN) { - if (p->tok->done == E_DECODE) { - return raise_decode_error(p); - } - return tokenizer_error(p); - - } - - return 0; -} - -// Instrumentation to count the effectiveness of memoization. -// The array counts the number of tokens skipped by memoization, -// indexed by type. - -#define NSTATISTICS 2000 -static long memo_statistics[NSTATISTICS]; - -void -_PyPegen_clear_memo_statistics() -{ - for (int i = 0; i < NSTATISTICS; i++) { - memo_statistics[i] = 0; - } -} - -PyObject * -_PyPegen_get_memo_statistics() -{ - PyObject *ret = PyList_New(NSTATISTICS); - if (ret == NULL) { - return NULL; - } - for (int i = 0; i < NSTATISTICS; i++) { - PyObject *value = PyLong_FromLong(memo_statistics[i]); - if (value == NULL) { - Py_DECREF(ret); - return NULL; - } - // PyList_SetItem borrows a reference to value. - if (PyList_SetItem(ret, i, value) < 0) { - Py_DECREF(ret); - return NULL; - } - } - return ret; -} - -int // bool -_PyPegen_is_memoized(Parser *p, int type, void *pres) -{ - if (p->mark == p->fill) { - if (_PyPegen_fill_token(p) < 0) { - p->error_indicator = 1; - return -1; - } - } - - Token *t = p->tokens[p->mark]; - - for (Memo *m = t->memo; m != NULL; m = m->next) { - if (m->type == type) { - if (0 <= type && type < NSTATISTICS) { - long count = m->mark - p->mark; - // A memoized negative result counts for one. - if (count <= 0) { - count = 1; - } - memo_statistics[type] += count; - } - p->mark = m->mark; - *(void **)(pres) = m->node; - return 1; - } - } - return 0; -} - -int -_PyPegen_lookahead_with_name(int positive, expr_ty (func)(Parser *), Parser *p) -{ - int mark = p->mark; - void *res = func(p); - p->mark = mark; - return (res != NULL) == positive; -} - -int -_PyPegen_lookahead_with_string(int positive, expr_ty (func)(Parser *, const char*), Parser *p, const char* arg) -{ - int mark = p->mark; - void *res = func(p, arg); - p->mark = mark; - return (res != NULL) == positive; -} - -int -_PyPegen_lookahead_with_int(int positive, Token *(func)(Parser *, int), Parser *p, int arg) -{ - int mark = p->mark; - void *res = func(p, arg); - p->mark = mark; - return (res != NULL) == positive; -} - -int -_PyPegen_lookahead(int positive, void *(func)(Parser *), Parser *p) -{ - int mark = p->mark; - void *res = (void*)func(p); - p->mark = mark; - return (res != NULL) == positive; -} - -Token * -_PyPegen_expect_token(Parser *p, int type) -{ - if (p->mark == p->fill) { - if (_PyPegen_fill_token(p) < 0) { - p->error_indicator = 1; - return NULL; - } - } - Token *t = p->tokens[p->mark]; - if (t->type != type) { - return NULL; - } - p->mark += 1; - return t; -} - -expr_ty -_PyPegen_expect_soft_keyword(Parser *p, const char *keyword) -{ - if (p->mark == p->fill) { - if (_PyPegen_fill_token(p) < 0) { - p->error_indicator = 1; - return NULL; - } - } - Token *t = p->tokens[p->mark]; - if (t->type != NAME) { - return NULL; - } - char* s = PyBytes_AsString(t->bytes); - if (!s) { - p->error_indicator = 1; - return NULL; - } - if (strcmp(s, keyword) != 0) { - return NULL; - } - return _PyPegen_name_token(p); -} - -Token * -_PyPegen_get_last_nonnwhitespace_token(Parser *p) -{ - assert(p->mark >= 0); - Token *token = NULL; - for (int m = p->mark - 1; m >= 0; m--) { - token = p->tokens[m]; - if (token->type != ENDMARKER && (token->type < NEWLINE || token->type > DEDENT)) { - break; - } - } - return token; -} - -expr_ty -_PyPegen_name_token(Parser *p) -{ - Token *t = _PyPegen_expect_token(p, NAME); - if (t == NULL) { - return NULL; - } - char* s = PyBytes_AsString(t->bytes); - if (!s) { - p->error_indicator = 1; - return NULL; - } - PyObject *id = _PyPegen_new_identifier(p, s); - if (id == NULL) { - p->error_indicator = 1; - return NULL; - } - return Name(id, Load, t->lineno, t->col_offset, t->end_lineno, t->end_col_offset, - p->arena); -} - -void * -_PyPegen_string_token(Parser *p) -{ - return _PyPegen_expect_token(p, STRING); -} - -static PyObject * -parsenumber_raw(const char *s) -{ - const char *end; - long x; - double dx; - Py_complex compl; - int imflag; - - assert(s != NULL); - errno = 0; - end = s + strlen(s) - 1; - imflag = *end == 'j' || *end == 'J'; - if (s[0] == '0') { - x = (long)PyOS_strtoul(s, (char **)&end, 0); - if (x < 0 && errno == 0) { - return PyLong_FromString(s, (char **)0, 0); - } - } - else { - x = PyOS_strtol(s, (char **)&end, 0); - } - if (*end == '\0') { - if (errno != 0) { - return PyLong_FromString(s, (char **)0, 0); - } - return PyLong_FromLong(x); - } - /* XXX Huge floats may silently fail */ - if (imflag) { - compl.real = 0.; - compl.imag = PyOS_string_to_double(s, (char **)&end, NULL); - if (compl.imag == -1.0 && PyErr_Occurred()) { - return NULL; - } - return PyComplex_FromCComplex(compl); - } - dx = PyOS_string_to_double(s, NULL, NULL); - if (dx == -1.0 && PyErr_Occurred()) { - return NULL; - } - return PyFloat_FromDouble(dx); -} - -static PyObject * -parsenumber(const char *s) -{ - char *dup; - char *end; - PyObject *res = NULL; - - assert(s != NULL); - - if (strchr(s, '_') == NULL) { - return parsenumber_raw(s); - } - /* Create a duplicate without underscores. */ - dup = PyMem_Malloc(strlen(s) + 1); - if (dup == NULL) { - return PyErr_NoMemory(); - } - end = dup; - for (; *s; s++) { - if (*s != '_') { - *end++ = *s; - } - } - *end = '\0'; - res = parsenumber_raw(dup); - PyMem_Free(dup); - return res; -} - -expr_ty -_PyPegen_number_token(Parser *p) -{ - Token *t = _PyPegen_expect_token(p, NUMBER); - if (t == NULL) { - return NULL; - } - - char *num_raw = PyBytes_AsString(t->bytes); - if (num_raw == NULL) { - p->error_indicator = 1; - return NULL; - } - - if (p->feature_version < 6 && strchr(num_raw, '_') != NULL) { - p->error_indicator = 1; - return RAISE_SYNTAX_ERROR("Underscores in numeric literals are only supported " - "in Python 3.6 and greater"); - } - - PyObject *c = parsenumber(num_raw); - - if (c == NULL) { - p->error_indicator = 1; - return NULL; - } - - if (PyArena_AddPyObject(p->arena, c) < 0) { - Py_DECREF(c); - p->error_indicator = 1; - return NULL; - } - - return Constant(c, NULL, t->lineno, t->col_offset, t->end_lineno, t->end_col_offset, - p->arena); -} - -static int // bool -newline_in_string(Parser *p, const char *cur) -{ - for (const char *c = cur; c >= p->tok->buf; c--) { - if (*c == '\'' || *c == '"') { - return 1; - } - } - return 0; -} - -/* Check that the source for a single input statement really is a single - statement by looking at what is left in the buffer after parsing. - Trailing whitespace and comments are OK. */ -static int // bool -bad_single_statement(Parser *p) -{ - const char *cur = strchr(p->tok->buf, '\n'); - - /* Newlines are allowed if preceded by a line continuation character - or if they appear inside a string. */ - if (!cur || (cur != p->tok->buf && *(cur - 1) == '\\') - || newline_in_string(p, cur)) { - return 0; - } - char c = *cur; - - for (;;) { - while (c == ' ' || c == '\t' || c == '\n' || c == '\014') { - c = *++cur; - } - - if (!c) { - return 0; - } - - if (c != '#') { - return 1; - } - - /* Suck up comment. */ - while (c && c != '\n') { - c = *++cur; - } - } -} - -void -_PyPegen_Parser_Free(Parser *p) -{ - Py_XDECREF(p->normalize); - for (int i = 0; i < p->size; i++) { - PyMem_Free(p->tokens[i]); - } - PyMem_Free(p->tokens); - growable_comment_array_deallocate(&p->type_ignore_comments); - PyMem_Free(p); -} - -static int -compute_parser_flags(PyCompilerFlags *flags) -{ - int parser_flags = 0; - if (!flags) { - return 0; - } - if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT) { - parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; - } - if (flags->cf_flags & PyCF_IGNORE_COOKIE) { - parser_flags |= PyPARSE_IGNORE_COOKIE; - } - if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) { - parser_flags |= PyPARSE_BARRY_AS_BDFL; - } - if (flags->cf_flags & PyCF_TYPE_COMMENTS) { - parser_flags |= PyPARSE_TYPE_COMMENTS; - } - if ((flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7) { - parser_flags |= PyPARSE_ASYNC_HACKS; - } - return parser_flags; -} - -Parser * -_PyPegen_Parser_New(struct tok_state *tok, int start_rule, int flags, - int feature_version, int *errcode, PyArena *arena) -{ - Parser *p = PyMem_Malloc(sizeof(Parser)); - if (p == NULL) { - return (Parser *) PyErr_NoMemory(); - } - assert(tok != NULL); - tok->type_comments = (flags & PyPARSE_TYPE_COMMENTS) > 0; - tok->async_hacks = (flags & PyPARSE_ASYNC_HACKS) > 0; - p->tok = tok; - p->keywords = NULL; - p->n_keyword_lists = -1; - p->tokens = PyMem_Malloc(sizeof(Token *)); - if (!p->tokens) { - PyMem_Free(p); - return (Parser *) PyErr_NoMemory(); - } - p->tokens[0] = PyMem_Calloc(1, sizeof(Token)); - if (!p->tokens) { - PyMem_Free(p->tokens); - PyMem_Free(p); - return (Parser *) PyErr_NoMemory(); - } - if (!growable_comment_array_init(&p->type_ignore_comments, 10)) { - PyMem_Free(p->tokens[0]); - PyMem_Free(p->tokens); - PyMem_Free(p); - return (Parser *) PyErr_NoMemory(); - } - - p->mark = 0; - p->fill = 0; - p->size = 1; - - p->errcode = errcode; - p->arena = arena; - p->start_rule = start_rule; - p->parsing_started = 0; - p->normalize = NULL; - p->error_indicator = 0; - - p->starting_lineno = 0; - p->starting_col_offset = 0; - p->flags = flags; - p->feature_version = feature_version; - p->known_err_token = NULL; - p->level = 0; - p->call_invalid_rules = 0; - - return p; -} - -static void -reset_parser_state(Parser *p) -{ - for (int i = 0; i < p->fill; i++) { - p->tokens[i]->memo = NULL; - } - p->mark = 0; - p->call_invalid_rules = 1; -} - -void * -_PyPegen_run_parser(Parser *p) -{ - void *res = _PyPegen_parse(p); - if (res == NULL) { - reset_parser_state(p); - _PyPegen_parse(p); - if (PyErr_Occurred()) { - return NULL; - } - if (p->fill == 0) { - RAISE_SYNTAX_ERROR("error at start before reading any input"); - } - else if (p->tok->done == E_EOF) { - RAISE_SYNTAX_ERROR("unexpected EOF while parsing"); - } - else { - if (p->tokens[p->fill-1]->type == INDENT) { - RAISE_INDENTATION_ERROR("unexpected indent"); - } - else if (p->tokens[p->fill-1]->type == DEDENT) { - RAISE_INDENTATION_ERROR("unexpected unindent"); - } - else { - RAISE_SYNTAX_ERROR("invalid syntax"); - } - } - return NULL; - } - - if (p->start_rule == Py_single_input && bad_single_statement(p)) { - p->tok->done = E_BADSINGLE; // This is not necessary for now, but might be in the future - return RAISE_SYNTAX_ERROR("multiple statements found while compiling a single statement"); - } - -#if defined(Py_DEBUG) && defined(Py_BUILD_CORE) - if (p->start_rule == Py_single_input || - p->start_rule == Py_file_input || - p->start_rule == Py_eval_input) - { - assert(PyAST_Validate(res)); - } -#endif - return res; -} - -mod_ty -_PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filename_ob, - const char *enc, const char *ps1, const char *ps2, - PyCompilerFlags *flags, int *errcode, PyArena *arena) -{ - struct tok_state *tok = PyTokenizer_FromFile(fp, enc, ps1, ps2); - if (tok == NULL) { - if (PyErr_Occurred()) { - raise_tokenizer_init_error(filename_ob); - return NULL; - } - return NULL; - } - // This transfers the ownership to the tokenizer - tok->filename = filename_ob; - Py_INCREF(filename_ob); - - // From here on we need to clean up even if there's an error - mod_ty result = NULL; - - int parser_flags = compute_parser_flags(flags); - Parser *p = _PyPegen_Parser_New(tok, start_rule, parser_flags, PY_MINOR_VERSION, - errcode, arena); - if (p == NULL) { - goto error; - } - - result = _PyPegen_run_parser(p); - _PyPegen_Parser_Free(p); - -error: - PyTokenizer_Free(tok); - return result; -} - -mod_ty -_PyPegen_run_parser_from_file(const char *filename, int start_rule, - PyObject *filename_ob, PyCompilerFlags *flags, PyArena *arena) -{ - FILE *fp = fopen(filename, "rb"); - if (fp == NULL) { - PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); - return NULL; - } - - mod_ty result = _PyPegen_run_parser_from_file_pointer(fp, start_rule, filename_ob, - NULL, NULL, NULL, flags, NULL, arena); - - fclose(fp); - return result; -} - -mod_ty -_PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filename_ob, - PyCompilerFlags *flags, PyArena *arena) -{ - int exec_input = start_rule == Py_file_input; - - struct tok_state *tok; - if (flags != NULL && flags->cf_flags & PyCF_IGNORE_COOKIE) { - tok = PyTokenizer_FromUTF8(str, exec_input); - } else { - tok = PyTokenizer_FromString(str, exec_input); - } - if (tok == NULL) { - if (PyErr_Occurred()) { - raise_tokenizer_init_error(filename_ob); - } - return NULL; - } - // This transfers the ownership to the tokenizer - tok->filename = filename_ob; - Py_INCREF(filename_ob); - - // We need to clear up from here on - mod_ty result = NULL; - - int parser_flags = compute_parser_flags(flags); - int feature_version = flags && (flags->cf_flags & PyCF_ONLY_AST) ? - flags->cf_feature_version : PY_MINOR_VERSION; - Parser *p = _PyPegen_Parser_New(tok, start_rule, parser_flags, feature_version, - NULL, arena); - if (p == NULL) { - goto error; - } - - result = _PyPegen_run_parser(p); - _PyPegen_Parser_Free(p); - -error: - PyTokenizer_Free(tok); - return result; -} - -void * -_PyPegen_interactive_exit(Parser *p) -{ - if (p->errcode) { - *(p->errcode) = E_EOF; - } - return NULL; -} - -/* Creates a single-element asdl_seq* that contains a */ -asdl_seq * -_PyPegen_singleton_seq(Parser *p, void *a) -{ - assert(a != NULL); - asdl_seq *seq = _Py_asdl_seq_new(1, p->arena); - if (!seq) { - return NULL; - } - asdl_seq_SET(seq, 0, a); - return seq; -} - -/* Creates a copy of seq and prepends a to it */ -asdl_seq * -_PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq) -{ - assert(a != NULL); - if (!seq) { - return _PyPegen_singleton_seq(p, a); - } - - asdl_seq *new_seq = _Py_asdl_seq_new(asdl_seq_LEN(seq) + 1, p->arena); - if (!new_seq) { - return NULL; - } - - asdl_seq_SET(new_seq, 0, a); - for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) { - asdl_seq_SET(new_seq, i, asdl_seq_GET(seq, i - 1)); - } - return new_seq; -} - -/* Creates a copy of seq and appends a to it */ -asdl_seq * -_PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a) -{ - assert(a != NULL); - if (!seq) { - return _PyPegen_singleton_seq(p, a); - } - - asdl_seq *new_seq = _Py_asdl_seq_new(asdl_seq_LEN(seq) + 1, p->arena); - if (!new_seq) { - return NULL; - } - - for (Py_ssize_t i = 0, l = asdl_seq_LEN(new_seq); i + 1 < l; i++) { - asdl_seq_SET(new_seq, i, asdl_seq_GET(seq, i)); - } - asdl_seq_SET(new_seq, asdl_seq_LEN(new_seq) - 1, a); - return new_seq; -} - -static Py_ssize_t -_get_flattened_seq_size(asdl_seq *seqs) -{ - Py_ssize_t size = 0; - for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) { - asdl_seq *inner_seq = asdl_seq_GET(seqs, i); - size += asdl_seq_LEN(inner_seq); - } - return size; -} - -/* Flattens an asdl_seq* of asdl_seq*s */ -asdl_seq * -_PyPegen_seq_flatten(Parser *p, asdl_seq *seqs) -{ - Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs); - assert(flattened_seq_size > 0); - - asdl_seq *flattened_seq = _Py_asdl_seq_new(flattened_seq_size, p->arena); - if (!flattened_seq) { - return NULL; - } - - int flattened_seq_idx = 0; - for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) { - asdl_seq *inner_seq = asdl_seq_GET(seqs, i); - for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) { - asdl_seq_SET(flattened_seq, flattened_seq_idx++, asdl_seq_GET(inner_seq, j)); - } - } - assert(flattened_seq_idx == flattened_seq_size); - - return flattened_seq; -} - -/* Creates a new name of the form . */ -expr_ty -_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name) -{ - assert(first_name != NULL && second_name != NULL); - PyObject *first_identifier = first_name->v.Name.id; - PyObject *second_identifier = second_name->v.Name.id; - - if (PyUnicode_READY(first_identifier) == -1) { - return NULL; - } - if (PyUnicode_READY(second_identifier) == -1) { - return NULL; - } - const char *first_str = PyUnicode_AsUTF8(first_identifier); - if (!first_str) { - return NULL; - } - const char *second_str = PyUnicode_AsUTF8(second_identifier); - if (!second_str) { - return NULL; - } - Py_ssize_t len = strlen(first_str) + strlen(second_str) + 1; // +1 for the dot - - PyObject *str = PyBytes_FromStringAndSize(NULL, len); - if (!str) { - return NULL; - } - - char *s = PyBytes_AS_STRING(str); - if (!s) { - return NULL; - } - - strcpy(s, first_str); - s += strlen(first_str); - *s++ = '.'; - strcpy(s, second_str); - s += strlen(second_str); - *s = '\0'; - - PyObject *uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), PyBytes_GET_SIZE(str), NULL); - Py_DECREF(str); - if (!uni) { - return NULL; - } - PyUnicode_InternInPlace(&uni); - if (PyArena_AddPyObject(p->arena, uni) < 0) { - Py_DECREF(uni); - return NULL; - } - - return _Py_Name(uni, Load, EXTRA_EXPR(first_name, second_name)); -} - -/* Counts the total number of dots in seq's tokens */ -int -_PyPegen_seq_count_dots(asdl_seq *seq) -{ - int number_of_dots = 0; - for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) { - Token *current_expr = asdl_seq_GET(seq, i); - switch (current_expr->type) { - case ELLIPSIS: - number_of_dots += 3; - break; - case DOT: - number_of_dots += 1; - break; - default: - Py_UNREACHABLE(); - } - } - - return number_of_dots; -} - -/* Creates an alias with '*' as the identifier name */ -alias_ty -_PyPegen_alias_for_star(Parser *p) -{ - PyObject *str = PyUnicode_InternFromString("*"); - if (!str) { - return NULL; - } - if (PyArena_AddPyObject(p->arena, str) < 0) { - Py_DECREF(str); - return NULL; - } - return alias(str, NULL, p->arena); -} - -/* Creates a new asdl_seq* with the identifiers of all the names in seq */ -asdl_seq * -_PyPegen_map_names_to_ids(Parser *p, asdl_seq *seq) -{ - Py_ssize_t len = asdl_seq_LEN(seq); - assert(len > 0); - - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); - if (!new_seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - expr_ty e = asdl_seq_GET(seq, i); - asdl_seq_SET(new_seq, i, e->v.Name.id); - } - return new_seq; -} - -/* Constructs a CmpopExprPair */ -CmpopExprPair * -_PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr) -{ - assert(expr != NULL); - CmpopExprPair *a = PyArena_Malloc(p->arena, sizeof(CmpopExprPair)); - if (!a) { - return NULL; - } - a->cmpop = cmpop; - a->expr = expr; - return a; -} - -asdl_int_seq * -_PyPegen_get_cmpops(Parser *p, asdl_seq *seq) -{ - Py_ssize_t len = asdl_seq_LEN(seq); - assert(len > 0); - - asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena); - if (!new_seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - CmpopExprPair *pair = asdl_seq_GET(seq, i); - asdl_seq_SET(new_seq, i, pair->cmpop); - } - return new_seq; -} - -asdl_seq * -_PyPegen_get_exprs(Parser *p, asdl_seq *seq) -{ - Py_ssize_t len = asdl_seq_LEN(seq); - assert(len > 0); - - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); - if (!new_seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - CmpopExprPair *pair = asdl_seq_GET(seq, i); - asdl_seq_SET(new_seq, i, pair->expr); - } - return new_seq; -} - -/* Creates an asdl_seq* where all the elements have been changed to have ctx as context */ -static asdl_seq * -_set_seq_context(Parser *p, asdl_seq *seq, expr_context_ty ctx) -{ - Py_ssize_t len = asdl_seq_LEN(seq); - if (len == 0) { - return NULL; - } - - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); - if (!new_seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - expr_ty e = asdl_seq_GET(seq, i); - asdl_seq_SET(new_seq, i, _PyPegen_set_expr_context(p, e, ctx)); - } - return new_seq; -} - -static expr_ty -_set_name_context(Parser *p, expr_ty e, expr_context_ty ctx) -{ - return _Py_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e)); -} - -static expr_ty -_set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx) -{ - return _Py_Tuple(_set_seq_context(p, e->v.Tuple.elts, ctx), ctx, EXTRA_EXPR(e, e)); -} - -static expr_ty -_set_list_context(Parser *p, expr_ty e, expr_context_ty ctx) -{ - return _Py_List(_set_seq_context(p, e->v.List.elts, ctx), ctx, EXTRA_EXPR(e, e)); -} - -static expr_ty -_set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx) -{ - return _Py_Subscript(e->v.Subscript.value, e->v.Subscript.slice, ctx, EXTRA_EXPR(e, e)); -} - -static expr_ty -_set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx) -{ - return _Py_Attribute(e->v.Attribute.value, e->v.Attribute.attr, ctx, EXTRA_EXPR(e, e)); -} - -static expr_ty -_set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx) -{ - return _Py_Starred(_PyPegen_set_expr_context(p, e->v.Starred.value, ctx), ctx, EXTRA_EXPR(e, e)); -} - -/* Creates an `expr_ty` equivalent to `expr` but with `ctx` as context */ -expr_ty -_PyPegen_set_expr_context(Parser *p, expr_ty expr, expr_context_ty ctx) -{ - assert(expr != NULL); - - expr_ty new = NULL; - switch (expr->kind) { - case Name_kind: - new = _set_name_context(p, expr, ctx); - break; - case Tuple_kind: - new = _set_tuple_context(p, expr, ctx); - break; - case List_kind: - new = _set_list_context(p, expr, ctx); - break; - case Subscript_kind: - new = _set_subscript_context(p, expr, ctx); - break; - case Attribute_kind: - new = _set_attribute_context(p, expr, ctx); - break; - case Starred_kind: - new = _set_starred_context(p, expr, ctx); - break; - default: - new = expr; - } - return new; -} - -/* Constructs a KeyValuePair that is used when parsing a dict's key value pairs */ -KeyValuePair * -_PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value) -{ - KeyValuePair *a = PyArena_Malloc(p->arena, sizeof(KeyValuePair)); - if (!a) { - return NULL; - } - a->key = key; - a->value = value; - return a; -} - -/* Extracts all keys from an asdl_seq* of KeyValuePair*'s */ -asdl_seq * -_PyPegen_get_keys(Parser *p, asdl_seq *seq) -{ - Py_ssize_t len = asdl_seq_LEN(seq); - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); - if (!new_seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - KeyValuePair *pair = asdl_seq_GET(seq, i); - asdl_seq_SET(new_seq, i, pair->key); - } - return new_seq; -} - -/* Extracts all values from an asdl_seq* of KeyValuePair*'s */ -asdl_seq * -_PyPegen_get_values(Parser *p, asdl_seq *seq) -{ - Py_ssize_t len = asdl_seq_LEN(seq); - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); - if (!new_seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - KeyValuePair *pair = asdl_seq_GET(seq, i); - asdl_seq_SET(new_seq, i, pair->value); - } - return new_seq; -} - -/* Constructs a NameDefaultPair */ -NameDefaultPair * -_PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc) -{ - NameDefaultPair *a = PyArena_Malloc(p->arena, sizeof(NameDefaultPair)); - if (!a) { - return NULL; - } - a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc); - a->value = value; - return a; -} - -/* Constructs a SlashWithDefault */ -SlashWithDefault * -_PyPegen_slash_with_default(Parser *p, asdl_seq *plain_names, asdl_seq *names_with_defaults) -{ - SlashWithDefault *a = PyArena_Malloc(p->arena, sizeof(SlashWithDefault)); - if (!a) { - return NULL; - } - a->plain_names = plain_names; - a->names_with_defaults = names_with_defaults; - return a; -} - -/* Constructs a StarEtc */ -StarEtc * -_PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg) -{ - StarEtc *a = PyArena_Malloc(p->arena, sizeof(StarEtc)); - if (!a) { - return NULL; - } - a->vararg = vararg; - a->kwonlyargs = kwonlyargs; - a->kwarg = kwarg; - return a; -} - -asdl_seq * -_PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b) -{ - Py_ssize_t first_len = asdl_seq_LEN(a); - Py_ssize_t second_len = asdl_seq_LEN(b); - asdl_seq *new_seq = _Py_asdl_seq_new(first_len + second_len, p->arena); - if (!new_seq) { - return NULL; - } - - int k = 0; - for (Py_ssize_t i = 0; i < first_len; i++) { - asdl_seq_SET(new_seq, k++, asdl_seq_GET(a, i)); - } - for (Py_ssize_t i = 0; i < second_len; i++) { - asdl_seq_SET(new_seq, k++, asdl_seq_GET(b, i)); - } - - return new_seq; -} - -static asdl_seq * -_get_names(Parser *p, asdl_seq *names_with_defaults) -{ - Py_ssize_t len = asdl_seq_LEN(names_with_defaults); - asdl_seq *seq = _Py_asdl_seq_new(len, p->arena); - if (!seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - NameDefaultPair *pair = asdl_seq_GET(names_with_defaults, i); - asdl_seq_SET(seq, i, pair->arg); - } - return seq; -} - -static asdl_seq * -_get_defaults(Parser *p, asdl_seq *names_with_defaults) -{ - Py_ssize_t len = asdl_seq_LEN(names_with_defaults); - asdl_seq *seq = _Py_asdl_seq_new(len, p->arena); - if (!seq) { - return NULL; - } - for (Py_ssize_t i = 0; i < len; i++) { - NameDefaultPair *pair = asdl_seq_GET(names_with_defaults, i); - asdl_seq_SET(seq, i, pair->value); - } - return seq; -} - -/* Constructs an arguments_ty object out of all the parsed constructs in the parameters rule */ -arguments_ty -_PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, - SlashWithDefault *slash_with_default, asdl_seq *plain_names, - asdl_seq *names_with_default, StarEtc *star_etc) -{ - asdl_seq *posonlyargs; - if (slash_without_default != NULL) { - posonlyargs = slash_without_default; - } - else if (slash_with_default != NULL) { - asdl_seq *slash_with_default_names = - _get_names(p, slash_with_default->names_with_defaults); - if (!slash_with_default_names) { - return NULL; - } - posonlyargs = _PyPegen_join_sequences(p, slash_with_default->plain_names, slash_with_default_names); - if (!posonlyargs) { - return NULL; - } - } - else { - posonlyargs = _Py_asdl_seq_new(0, p->arena); - if (!posonlyargs) { - return NULL; - } - } - - asdl_seq *posargs; - if (plain_names != NULL && names_with_default != NULL) { - asdl_seq *names_with_default_names = _get_names(p, names_with_default); - if (!names_with_default_names) { - return NULL; - } - posargs = _PyPegen_join_sequences(p, plain_names, names_with_default_names); - if (!posargs) { - return NULL; - } - } - else if (plain_names == NULL && names_with_default != NULL) { - posargs = _get_names(p, names_with_default); - if (!posargs) { - return NULL; - } - } - else if (plain_names != NULL && names_with_default == NULL) { - posargs = plain_names; - } - else { - posargs = _Py_asdl_seq_new(0, p->arena); - if (!posargs) { - return NULL; - } - } - - asdl_seq *posdefaults; - if (slash_with_default != NULL && names_with_default != NULL) { - asdl_seq *slash_with_default_values = - _get_defaults(p, slash_with_default->names_with_defaults); - if (!slash_with_default_values) { - return NULL; - } - asdl_seq *names_with_default_values = _get_defaults(p, names_with_default); - if (!names_with_default_values) { - return NULL; - } - posdefaults = _PyPegen_join_sequences(p, slash_with_default_values, names_with_default_values); - if (!posdefaults) { - return NULL; - } - } - else if (slash_with_default == NULL && names_with_default != NULL) { - posdefaults = _get_defaults(p, names_with_default); - if (!posdefaults) { - return NULL; - } - } - else if (slash_with_default != NULL && names_with_default == NULL) { - posdefaults = _get_defaults(p, slash_with_default->names_with_defaults); - if (!posdefaults) { - return NULL; - } - } - else { - posdefaults = _Py_asdl_seq_new(0, p->arena); - if (!posdefaults) { - return NULL; - } - } - - arg_ty vararg = NULL; - if (star_etc != NULL && star_etc->vararg != NULL) { - vararg = star_etc->vararg; - } - - asdl_seq *kwonlyargs; - if (star_etc != NULL && star_etc->kwonlyargs != NULL) { - kwonlyargs = _get_names(p, star_etc->kwonlyargs); - if (!kwonlyargs) { - return NULL; - } - } - else { - kwonlyargs = _Py_asdl_seq_new(0, p->arena); - if (!kwonlyargs) { - return NULL; - } - } - - asdl_seq *kwdefaults; - if (star_etc != NULL && star_etc->kwonlyargs != NULL) { - kwdefaults = _get_defaults(p, star_etc->kwonlyargs); - if (!kwdefaults) { - return NULL; - } - } - else { - kwdefaults = _Py_asdl_seq_new(0, p->arena); - if (!kwdefaults) { - return NULL; - } - } - - arg_ty kwarg = NULL; - if (star_etc != NULL && star_etc->kwarg != NULL) { - kwarg = star_etc->kwarg; - } - - return _Py_arguments(posonlyargs, posargs, vararg, kwonlyargs, kwdefaults, kwarg, - posdefaults, p->arena); -} - -/* Constructs an empty arguments_ty object, that gets used when a function accepts no - * arguments. */ -arguments_ty -_PyPegen_empty_arguments(Parser *p) -{ - asdl_seq *posonlyargs = _Py_asdl_seq_new(0, p->arena); - if (!posonlyargs) { - return NULL; - } - asdl_seq *posargs = _Py_asdl_seq_new(0, p->arena); - if (!posargs) { - return NULL; - } - asdl_seq *posdefaults = _Py_asdl_seq_new(0, p->arena); - if (!posdefaults) { - return NULL; - } - asdl_seq *kwonlyargs = _Py_asdl_seq_new(0, p->arena); - if (!kwonlyargs) { - return NULL; - } - asdl_seq *kwdefaults = _Py_asdl_seq_new(0, p->arena); - if (!kwdefaults) { - return NULL; - } - - return _Py_arguments(posonlyargs, posargs, NULL, kwonlyargs, kwdefaults, NULL, kwdefaults, - p->arena); -} - -/* Encapsulates the value of an operator_ty into an AugOperator struct */ -AugOperator * -_PyPegen_augoperator(Parser *p, operator_ty kind) -{ - AugOperator *a = PyArena_Malloc(p->arena, sizeof(AugOperator)); - if (!a) { - return NULL; - } - a->kind = kind; - return a; -} - -/* Construct a FunctionDef equivalent to function_def, but with decorators */ -stmt_ty -_PyPegen_function_def_decorators(Parser *p, asdl_seq *decorators, stmt_ty function_def) -{ - assert(function_def != NULL); - if (function_def->kind == AsyncFunctionDef_kind) { - return _Py_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); - } - - return _Py_FunctionDef(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); -} - -/* Construct a ClassDef equivalent to class_def, but with decorators */ -stmt_ty -_PyPegen_class_def_decorators(Parser *p, asdl_seq *decorators, stmt_ty class_def) -{ - assert(class_def != NULL); - return _Py_ClassDef(class_def->v.ClassDef.name, class_def->v.ClassDef.bases, - class_def->v.ClassDef.keywords, class_def->v.ClassDef.body, decorators, - class_def->lineno, class_def->col_offset, class_def->end_lineno, - class_def->end_col_offset, p->arena); -} - -/* Construct a KeywordOrStarred */ -KeywordOrStarred * -_PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword) -{ - KeywordOrStarred *a = PyArena_Malloc(p->arena, sizeof(KeywordOrStarred)); - if (!a) { - return NULL; - } - a->element = element; - a->is_keyword = is_keyword; - return a; -} - -/* Get the number of starred expressions in an asdl_seq* of KeywordOrStarred*s */ -static int -_seq_number_of_starred_exprs(asdl_seq *seq) -{ - int n = 0; - for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) { - KeywordOrStarred *k = asdl_seq_GET(seq, i); - if (!k->is_keyword) { - n++; - } - } - return n; -} - -/* Extract the starred expressions of an asdl_seq* of KeywordOrStarred*s */ -asdl_seq * -_PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs) -{ - int new_len = _seq_number_of_starred_exprs(kwargs); - if (new_len == 0) { - return NULL; - } - asdl_seq *new_seq = _Py_asdl_seq_new(new_len, p->arena); - if (!new_seq) { - return NULL; - } - - int idx = 0; - for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) { - KeywordOrStarred *k = asdl_seq_GET(kwargs, i); - if (!k->is_keyword) { - asdl_seq_SET(new_seq, idx++, k->element); - } - } - return new_seq; -} - -/* Return a new asdl_seq* with only the keywords in kwargs */ -asdl_seq * -_PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs) -{ - Py_ssize_t len = asdl_seq_LEN(kwargs); - Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs); - if (new_len == 0) { - return NULL; - } - asdl_seq *new_seq = _Py_asdl_seq_new(new_len, p->arena); - if (!new_seq) { - return NULL; - } - - int idx = 0; - for (Py_ssize_t i = 0; i < len; i++) { - KeywordOrStarred *k = asdl_seq_GET(kwargs, i); - if (k->is_keyword) { - asdl_seq_SET(new_seq, idx++, k->element); - } - } - 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(strings, 0); - Token *last = asdl_seq_GET(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(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 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()) { - raise_decode_error(p); - } - return NULL; -} - -mod_ty -_PyPegen_make_module(Parser *p, asdl_seq *a) { - asdl_seq *type_ignores = NULL; - Py_ssize_t num = p->type_ignore_comments.num_items; - if (num > 0) { - // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena - type_ignores = _Py_asdl_seq_new(num, p->arena); - if (type_ignores == NULL) { - return NULL; - } - for (int i = 0; i < num; i++) { - PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment); - if (tag == NULL) { - return NULL; - } - type_ignore_ty ti = TypeIgnore(p->type_ignore_comments.items[i].lineno, tag, p->arena); - if (ti == NULL) { - return NULL; - } - asdl_seq_SET(type_ignores, i, ti); - } - } - return Module(a, type_ignores, p->arena); -} - -// Error reporting helpers - -expr_ty -_PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type) -{ - if (e == NULL) { - return NULL; - } - -#define VISIT_CONTAINER(CONTAINER, TYPE) do { \ - Py_ssize_t len = asdl_seq_LEN(CONTAINER->v.TYPE.elts);\ - for (Py_ssize_t i = 0; i < len; i++) {\ - expr_ty other = asdl_seq_GET(CONTAINER->v.TYPE.elts, i);\ - expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\ - if (child != NULL) {\ - return child;\ - }\ - }\ - } while (0) - - // We only need to visit List and Tuple nodes recursively as those - // are the only ones that can contain valid names in targets when - // they are parsed as expressions. Any other kind of expression - // that is a container (like Sets or Dicts) is directly invalid and - // we don't need to visit it recursively. - - switch (e->kind) { - case List_kind: - VISIT_CONTAINER(e, List); - return NULL; - case Tuple_kind: - VISIT_CONTAINER(e, Tuple); - return NULL; - case Starred_kind: - if (targets_type == DEL_TARGETS) { - return e; - } - return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type); - case Compare_kind: - // This is needed, because the `a in b` in `for a in b` gets parsed - // as a comparison, and so we need to search the left side of the comparison - // for invalid targets. - if (targets_type == FOR_TARGETS) { - cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0); - if (cmpop == In) { - return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type); - } - return NULL; - } - return e; - case Name_kind: - case Subscript_kind: - case Attribute_kind: - return NULL; - default: - return e; - } -} - -void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) { - int kwarg_unpacking = 0; - for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) { - keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i); - if (!keyword->arg) { - kwarg_unpacking = 1; - } - } - - const char *msg = NULL; - if (kwarg_unpacking) { - msg = "positional argument follows keyword argument unpacking"; - } else { - msg = "positional argument follows keyword argument"; - } - - return RAISE_SYNTAX_ERROR(msg); -} - -void * -_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args) -{ - /* The rule that calls this function is 'args for_if_clauses'. - For the input f(L, x for x in y), L and x are in args and - the for is parsed as a for_if_clause. We have to check if - len <= 1, so that input like dict((a, b) for a, b in x) - gets successfully parsed and then we pass the last - argument (x in the above example) as the location of the - error */ - Py_ssize_t len = asdl_seq_LEN(args->v.Call.args); - if (len <= 1) { - return NULL; - } - - return RAISE_SYNTAX_ERROR_KNOWN_LOCATION( - (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1), - "Generator expression must be parenthesized" - ); -} - - -expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b, - int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) { - Py_ssize_t args_len = asdl_seq_LEN(a); - Py_ssize_t total_len = args_len; - - if (b == NULL) { - return _Py_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset, - end_lineno, end_col_offset, arena); - - } - - asdl_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b); - asdl_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b); - - if (starreds) { - total_len += asdl_seq_LEN(starreds); - } - - asdl_seq *args = _Py_asdl_seq_new(total_len, arena); - - Py_ssize_t i = 0; - for (i = 0; i < args_len; i++) { - asdl_seq_SET(args, i, asdl_seq_GET(a, i)); - } - for (; i < total_len; i++) { - asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len)); - } - - return _Py_Call(_PyPegen_dummy_name(p), args, keywords, lineno, - col_offset, end_lineno, end_col_offset, arena); - - -} diff --git a/contrib/tools/python3/src/Parser/pegen/pegen.h b/contrib/tools/python3/src/Parser/pegen/pegen.h deleted file mode 100644 index 224c5cbea63..00000000000 --- a/contrib/tools/python3/src/Parser/pegen/pegen.h +++ /dev/null @@ -1,307 +0,0 @@ -#ifndef PEGEN_H -#define PEGEN_H - -#define PY_SSIZE_T_CLEAN -#include -#include -#include -#include - -#if 0 -#define PyPARSE_YIELD_IS_KEYWORD 0x0001 -#endif - -#define PyPARSE_DONT_IMPLY_DEDENT 0x0002 - -#if 0 -#define PyPARSE_WITH_IS_KEYWORD 0x0003 -#define PyPARSE_PRINT_IS_FUNCTION 0x0004 -#define PyPARSE_UNICODE_LITERALS 0x0008 -#endif - -#define PyPARSE_IGNORE_COOKIE 0x0010 -#define PyPARSE_BARRY_AS_BDFL 0x0020 -#define PyPARSE_TYPE_COMMENTS 0x0040 -#define PyPARSE_ASYNC_HACKS 0x0080 - -typedef struct _memo { - int type; - void *node; - int mark; - struct _memo *next; -} Memo; - -typedef struct { - int type; - PyObject *bytes; - int lineno, col_offset, end_lineno, end_col_offset; - Memo *memo; -} Token; - -typedef struct { - char *str; - int type; -} KeywordToken; - - -typedef struct { - struct { - int lineno; - char *comment; // The " " in "# type: ignore " - } *items; - size_t size; - size_t num_items; -} growable_comment_array; - -typedef struct { - struct tok_state *tok; - Token **tokens; - int mark; - int fill, size; - PyArena *arena; - KeywordToken **keywords; - int n_keyword_lists; - int start_rule; - int *errcode; - int parsing_started; - PyObject* normalize; - int starting_lineno; - int starting_col_offset; - int error_indicator; - int flags; - int feature_version; - growable_comment_array type_ignore_comments; - Token *known_err_token; - int level; - int call_invalid_rules; -} Parser; - -typedef struct { - cmpop_ty cmpop; - expr_ty expr; -} CmpopExprPair; - -typedef struct { - expr_ty key; - expr_ty value; -} KeyValuePair; - -typedef struct { - arg_ty arg; - expr_ty value; -} NameDefaultPair; - -typedef struct { - asdl_seq *plain_names; - asdl_seq *names_with_defaults; // asdl_seq* of NameDefaultsPair's -} SlashWithDefault; - -typedef struct { - arg_ty vararg; - asdl_seq *kwonlyargs; // asdl_seq* of NameDefaultsPair's - arg_ty kwarg; -} StarEtc; - -typedef struct { - operator_ty kind; -} AugOperator; - -typedef struct { - void *element; - int is_keyword; -} KeywordOrStarred; - -void _PyPegen_clear_memo_statistics(void); -PyObject *_PyPegen_get_memo_statistics(void); - -int _PyPegen_insert_memo(Parser *p, int mark, int type, void *node); -int _PyPegen_update_memo(Parser *p, int mark, int type, void *node); -int _PyPegen_is_memoized(Parser *p, int type, void *pres); - -int _PyPegen_lookahead_with_name(int, expr_ty (func)(Parser *), Parser *); -int _PyPegen_lookahead_with_string(int , expr_ty (func)(Parser *, const char*), Parser *, const char*); -int _PyPegen_lookahead_with_int(int, Token *(func)(Parser *, int), Parser *, int); -int _PyPegen_lookahead(int, void *(func)(Parser *), Parser *); - -Token *_PyPegen_expect_token(Parser *p, int type); -expr_ty _PyPegen_expect_soft_keyword(Parser *p, const char *keyword); -Token *_PyPegen_get_last_nonnwhitespace_token(Parser *); -int _PyPegen_fill_token(Parser *p); -expr_ty _PyPegen_name_token(Parser *p); -expr_ty _PyPegen_number_token(Parser *p); -void *_PyPegen_string_token(Parser *p); -const char *_PyPegen_get_expr_name(expr_ty); -void *_PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...); -void *_PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, - Py_ssize_t lineno, Py_ssize_t col_offset, - const char *errmsg, va_list va); -void *_PyPegen_dummy_name(Parser *p, ...); - -Py_LOCAL_INLINE(void *) -RAISE_ERROR_KNOWN_LOCATION(Parser *p, PyObject *errtype, - Py_ssize_t lineno, Py_ssize_t col_offset, - const char *errmsg, ...) -{ - va_list va; - va_start(va, errmsg); - _PyPegen_raise_error_known_location(p, errtype, lineno, col_offset + 1, - errmsg, va); - va_end(va); - return NULL; -} - - -#define UNUSED(expr) do { (void)(expr); } while (0) -#define EXTRA_EXPR(head, tail) head->lineno, head->col_offset, tail->end_lineno, tail->end_col_offset, p->arena -#define EXTRA _start_lineno, _start_col_offset, _end_lineno, _end_col_offset, p->arena -#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_KNOWN_LOCATION(a, msg, ...) \ - RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, (a)->lineno, (a)->col_offset, msg, ##__VA_ARGS__) - -Py_LOCAL_INLINE(void *) -CHECK_CALL(Parser *p, void *result) -{ - if (result == NULL) { - assert(PyErr_Occurred()); - p->error_indicator = 1; - } - return result; -} - -/* This is needed for helper functions that are allowed to - return NULL without an error. Example: _PyPegen_seq_extract_starred_exprs */ -Py_LOCAL_INLINE(void *) -CHECK_CALL_NULL_ALLOWED(Parser *p, void *result) -{ - if (result == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - } - return result; -} - -#define CHECK(result) CHECK_CALL(p, result) -#define CHECK_NULL_ALLOWED(result) CHECK_CALL_NULL_ALLOWED(p, result) - -PyObject *_PyPegen_new_type_comment(Parser *, char *); - -Py_LOCAL_INLINE(PyObject *) -NEW_TYPE_COMMENT(Parser *p, Token *tc) -{ - if (tc == NULL) { - return NULL; - } - char *bytes = PyBytes_AsString(tc->bytes); - if (bytes == NULL) { - goto error; - } - PyObject *tco = _PyPegen_new_type_comment(p, bytes); - if (tco == NULL) { - goto error; - } - return tco; - error: - p->error_indicator = 1; // Inline CHECK_CALL - return NULL; -} - -Py_LOCAL_INLINE(void *) -INVALID_VERSION_CHECK(Parser *p, int version, char *msg, void *node) -{ - if (node == NULL) { - p->error_indicator = 1; // Inline CHECK_CALL - return NULL; - } - if (p->feature_version < version) { - p->error_indicator = 1; - return RAISE_SYNTAX_ERROR("%s only supported in Python 3.%i and greater", - msg, version); - } - return node; -} - -#define CHECK_VERSION(version, msg, node) INVALID_VERSION_CHECK(p, version, msg, node) - -arg_ty _PyPegen_add_type_comment_to_arg(Parser *, arg_ty, Token *); -PyObject *_PyPegen_new_identifier(Parser *, char *); -Parser *_PyPegen_Parser_New(struct tok_state *, int, int, int, int *, PyArena *); -void _PyPegen_Parser_Free(Parser *); -mod_ty _PyPegen_run_parser_from_file_pointer(FILE *, int, PyObject *, const char *, - const char *, const char *, PyCompilerFlags *, int *, PyArena *); -void *_PyPegen_run_parser(Parser *); -mod_ty _PyPegen_run_parser_from_file(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); -mod_ty _PyPegen_run_parser_from_string(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); -void *_PyPegen_interactive_exit(Parser *); -asdl_seq *_PyPegen_singleton_seq(Parser *, void *); -asdl_seq *_PyPegen_seq_insert_in_front(Parser *, void *, asdl_seq *); -asdl_seq *_PyPegen_seq_append_to_end(Parser *, asdl_seq *, void *); -asdl_seq *_PyPegen_seq_flatten(Parser *, asdl_seq *); -expr_ty _PyPegen_join_names_with_dot(Parser *, expr_ty, expr_ty); -int _PyPegen_seq_count_dots(asdl_seq *); -alias_ty _PyPegen_alias_for_star(Parser *); -asdl_seq *_PyPegen_map_names_to_ids(Parser *, asdl_seq *); -CmpopExprPair *_PyPegen_cmpop_expr_pair(Parser *, cmpop_ty, expr_ty); -asdl_int_seq *_PyPegen_get_cmpops(Parser *p, asdl_seq *); -asdl_seq *_PyPegen_get_exprs(Parser *, asdl_seq *); -expr_ty _PyPegen_set_expr_context(Parser *, expr_ty, expr_context_ty); -KeyValuePair *_PyPegen_key_value_pair(Parser *, expr_ty, expr_ty); -asdl_seq *_PyPegen_get_keys(Parser *, asdl_seq *); -asdl_seq *_PyPegen_get_values(Parser *, asdl_seq *); -NameDefaultPair *_PyPegen_name_default_pair(Parser *, arg_ty, expr_ty, Token *); -SlashWithDefault *_PyPegen_slash_with_default(Parser *, asdl_seq *, asdl_seq *); -StarEtc *_PyPegen_star_etc(Parser *, arg_ty, asdl_seq *, arg_ty); -arguments_ty _PyPegen_make_arguments(Parser *, asdl_seq *, SlashWithDefault *, - asdl_seq *, asdl_seq *, StarEtc *); -arguments_ty _PyPegen_empty_arguments(Parser *); -AugOperator *_PyPegen_augoperator(Parser*, operator_ty type); -stmt_ty _PyPegen_function_def_decorators(Parser *, asdl_seq *, stmt_ty); -stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_seq *, stmt_ty); -KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int); -asdl_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *); -asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *); -expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_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 *); -asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *); -int _PyPegen_check_barry_as_flufl(Parser *, Token *); -mod_ty _PyPegen_make_module(Parser *, asdl_seq *); - -// Error reporting helpers -typedef enum { - STAR_TARGETS, - DEL_TARGETS, - FOR_TARGETS -} TARGETS_TYPE; -expr_ty _PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type); -#define RAISE_SYNTAX_ERROR_INVALID_TARGET(type, e) _RAISE_SYNTAX_ERROR_INVALID_TARGET(p, type, e) - -Py_LOCAL_INLINE(void *) -_RAISE_SYNTAX_ERROR_INVALID_TARGET(Parser *p, TARGETS_TYPE type, void *e) -{ - expr_ty invalid_target = CHECK_NULL_ALLOWED(_PyPegen_get_invalid_target(e, type)); - if (invalid_target != NULL) { - const char *msg; - if (type == STAR_TARGETS || type == FOR_TARGETS) { - msg = "cannot assign to %s"; - } - else { - msg = "cannot delete %s"; - } - return RAISE_SYNTAX_ERROR_KNOWN_LOCATION( - invalid_target, - msg, - _PyPegen_get_expr_name(invalid_target) - ); - } - return RAISE_SYNTAX_ERROR("invalid syntax"); -} - -void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); -void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args); - - -// Generated function in parse.c - function definition in python.gram -void *_PyPegen_parse(Parser *); - -#endif diff --git a/contrib/tools/python3/src/Parser/string_parser.c b/contrib/tools/python3/src/Parser/string_parser.c new file mode 100644 index 00000000000..dac8dbb8464 --- /dev/null +++ b/contrib/tools/python3/src/Parser/string_parser.c @@ -0,0 +1,1242 @@ +#include + +#include + +#include "tokenizer.h" +#include "pegen.h" +#include "string_parser.h" + +//// STRING HANDLING FUNCTIONS //// + +static int +warn_invalid_escape_sequence(Parser *p, unsigned char first_invalid_escape_char, Token *t) +{ + PyObject *msg = + PyUnicode_FromFormat("invalid escape sequence '\\%c'", first_invalid_escape_char); + if (msg == NULL) { + return -1; + } + if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg, p->tok->filename, + t->lineno, NULL, NULL) < 0) { + if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + /* Replace the DeprecationWarning exception with a SyntaxError + to get a more accurate error report */ + PyErr_Clear(); + + /* This is needed, in order for the SyntaxError to point to the token t, + since _PyPegen_raise_error uses p->tokens[p->fill - 1] for the + error location, if p->known_err_token is not set. */ + p->known_err_token = t; + RAISE_SYNTAX_ERROR("invalid escape sequence '\\%c'", first_invalid_escape_char); + } + Py_DECREF(msg); + return -1; + } + Py_DECREF(msg); + return 0; +} + +static PyObject * +decode_utf8(const char **sPtr, const char *end) +{ + const char *s; + const char *t; + t = s = *sPtr; + while (s < end && (*s & 0x80)) { + s++; + } + *sPtr = s; + return PyUnicode_DecodeUTF8(t, s - t, NULL); +} + +static PyObject * +decode_unicode_with_escapes(Parser *parser, const char *s, size_t len, Token *t) +{ + PyObject *v; + PyObject *u; + char *buf; + char *p; + const char *end; + + /* check for integer overflow */ + if (len > SIZE_MAX / 6) { + return NULL; + } + /* "ä" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5 + "\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */ + u = PyBytes_FromStringAndSize((char *)NULL, len * 6); + if (u == NULL) { + return NULL; + } + p = buf = PyBytes_AsString(u); + if (p == NULL) { + return NULL; + } + end = s + len; + while (s < end) { + if (*s == '\\') { + *p++ = *s++; + if (s >= end || *s & 0x80) { + strcpy(p, "u005c"); + p += 5; + if (s >= end) { + break; + } + } + } + if (*s & 0x80) { + PyObject *w; + int kind; + const void *data; + Py_ssize_t w_len; + Py_ssize_t i; + w = decode_utf8(&s, end); + if (w == NULL) { + Py_DECREF(u); + return NULL; + } + kind = PyUnicode_KIND(w); + data = PyUnicode_DATA(w); + w_len = PyUnicode_GET_LENGTH(w); + for (i = 0; i < w_len; i++) { + Py_UCS4 chr = PyUnicode_READ(kind, data, i); + sprintf(p, "\\U%08x", chr); + p += 10; + } + /* Should be impossible to overflow */ + assert(p - buf <= PyBytes_GET_SIZE(u)); + Py_DECREF(w); + } + else { + *p++ = *s++; + } + } + len = p - buf; + s = buf; + + const char *first_invalid_escape; + v = _PyUnicode_DecodeUnicodeEscapeInternal(s, len, NULL, NULL, &first_invalid_escape); + + if (v != NULL && first_invalid_escape != 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. */ + Py_XDECREF(u); + Py_DECREF(v); + return NULL; + } + } + Py_XDECREF(u); + return v; +} + +static PyObject * +decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t) +{ + const char *first_invalid_escape; + PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, &first_invalid_escape); + if (result == NULL) { + return NULL; + } + + if (first_invalid_escape != NULL) { + if (warn_invalid_escape_sequence(p, *first_invalid_escape, t) < 0) { + Py_DECREF(result); + return NULL; + } + } + 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) +{ + const char *s = PyBytes_AsString(t->bytes); + if (s == NULL) { + return -1; + } + + size_t len; + int quote = Py_CHARMASK(*s); + int fmode = 0; + *bytesmode = 0; + *rawmode = 0; + *result = NULL; + *fstr = NULL; + if (Py_ISALPHA(quote)) { + while (!*bytesmode || !*rawmode) { + if (quote == 'b' || quote == 'B') { + quote =(unsigned char)*++s; + *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; + } + else { + break; + } + } + } + + /* 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; + } + /* 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; + } + if (s[--len] != quote) { + /* Last quote char must match the first. */ + PyErr_BadInternalCall(); + return -1; + } + if (len >= 4 && s[0] == quote && s[1] == quote) { + /* A triple quoted string. We've already skipped one quote at + the start and one at the end of the string. Now skip the + two at the start. */ + s += 2; + len -= 2; + /* And check that the last two match. */ + if (s[--len] != quote || s[--len] != quote) { + PyErr_BadInternalCall(); + return -1; + } + } + + 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) { + /* Disallow non-ASCII characters. */ + const char *ch; + for (ch = s; *ch; ch++) { + if (Py_CHARMASK(*ch) >= 0x80) { + RAISE_SYNTAX_ERROR( + "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); + } + /* 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) { + 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 = 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, ch, 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; + } + + /* 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) { + /* Do nothing. No previous literal. */ + } else { + /* 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 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; + } + } + /* 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); +} diff --git a/contrib/tools/python3/src/Parser/string_parser.h b/contrib/tools/python3/src/Parser/string_parser.h new file mode 100644 index 00000000000..4a22f3d3086 --- /dev/null +++ b/contrib/tools/python3/src/Parser/string_parser.h @@ -0,0 +1,46 @@ +#ifndef STRINGS_H +#define STRINGS_H + +#include +#include +#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 *); + +#endif diff --git a/contrib/tools/python3/src/Parser/token.c b/contrib/tools/python3/src/Parser/token.c index a4896689009..74bca0eff65 100644 --- a/contrib/tools/python3/src/Parser/token.c +++ b/contrib/tools/python3/src/Parser/token.c @@ -65,6 +65,7 @@ const char * const _PyParser_TokenNames[] = { "ASYNC", "TYPE_IGNORE", "TYPE_COMMENT", + "SOFT_KEYWORD", "", "", "", diff --git a/contrib/tools/python3/src/Parser/tokenizer.c b/contrib/tools/python3/src/Parser/tokenizer.c index 41bfdb853c7..267ccec33fd 100644 --- a/contrib/tools/python3/src/Parser/tokenizer.c +++ b/contrib/tools/python3/src/Parser/tokenizer.c @@ -13,7 +13,6 @@ #include "unicodeobject.h" #include "bytesobject.h" #include "fileobject.h" -#include "codecs.h" #include "abstract.h" /* Alternate tab spacing */ @@ -40,7 +39,7 @@ static struct tok_state *tok_new(void); static int tok_nextc(struct tok_state *tok); static void tok_backup(struct tok_state *tok, int c); - +static int syntaxerror(struct tok_state *tok, const char *format, ...); /* Spaces in this constant are treated as "zero or more spaces or tabs" when tokenizing. */ @@ -51,11 +50,14 @@ static const char* type_comment_prefix = "# type: "; static struct tok_state * tok_new(void) { - struct tok_state *tok = (struct tok_state *)PyMem_MALLOC( + struct tok_state *tok = (struct tok_state *)PyMem_Malloc( sizeof(struct tok_state)); if (tok == NULL) return NULL; tok->buf = tok->cur = tok->inp = NULL; + tok->fp_interactive = 0; + tok->interactive_src_start = NULL; + tok->interactive_src_end = NULL; tok->start = NULL; tok->end = NULL; tok->done = E_OK; @@ -64,7 +66,6 @@ tok_new(void) tok->tabsize = TABSIZE; tok->indent = 0; tok->indstack[0] = 0; - tok->atbol = 1; tok->pendin = 0; tok->prompt = tok->nextprompt = NULL; @@ -73,7 +74,6 @@ tok_new(void) tok->altindstack[0] = 0; tok->decoding_state = STATE_INIT; tok->decoding_erred = 0; - tok->read_coding_spec = 0; tok->enc = NULL; tok->encoding = NULL; tok->cont_line = 0; @@ -81,19 +81,19 @@ tok_new(void) tok->decoding_readline = NULL; tok->decoding_buffer = NULL; tok->type_comments = 0; - tok->async_hacks = 0; tok->async_def = 0; tok->async_def_indent = 0; tok->async_def_nl = 0; - + tok->interactive_underflow = IUNDERFLOW_NORMAL; + tok->str = NULL; return tok; } static char * new_string(const char *s, Py_ssize_t len, struct tok_state *tok) { - char* result = (char *)PyMem_MALLOC(len + 1); + char* result = (char *)PyMem_Malloc(len + 1); if (!result) { tok->done = E_NOMEM; return NULL; @@ -108,7 +108,7 @@ error_ret(struct tok_state *tok) /* XXX */ { tok->decoding_erred = 1; if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */ - PyMem_FREE(tok->buf); + PyMem_Free(tok->buf); tok->buf = tok->cur = tok->inp = NULL; tok->start = NULL; tok->end = NULL; @@ -163,14 +163,14 @@ get_coding_spec(const char *s, char **spec, Py_ssize_t size, struct tok_state *t } for (; i < size - 6; i++) { /* XXX inefficient search */ const char* t = s + i; - if (strncmp(t, "coding", 6) == 0) { + if (memcmp(t, "coding", 6) == 0) { const char* begin = NULL; t += 6; if (t[0] != ':' && t[0] != '=') continue; do { t++; - } while (t[0] == '\x20' || t[0] == '\t'); + } while (t[0] == ' ' || t[0] == '\t'); begin = t; while (Py_ISALNUM(t[0]) || @@ -184,7 +184,7 @@ get_coding_spec(const char *s, char **spec, Py_ssize_t size, struct tok_state *t return 0; q = get_normal_name(r); if (r != q) { - PyMem_FREE(r); + PyMem_Free(r); r = new_string(q, strlen(q), tok); if (!r) return 0; @@ -207,15 +207,14 @@ check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, int set_readline(struct tok_state *, const char *)) { char *cs; - int r = 1; - if (tok->cont_line) { /* It's a continuation line, so it can't be a coding spec. */ - tok->read_coding_spec = 1; + tok->decoding_state = STATE_NORMAL; return 1; } - if (!get_coding_spec(line, &cs, size, tok)) + if (!get_coding_spec(line, &cs, size, tok)) { return 0; + } if (!cs) { Py_ssize_t i; for (i = 0; i < size; i++) { @@ -224,37 +223,33 @@ check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, if (line[i] != ' ' && line[i] != '\t' && line[i] != '\014') { /* Stop checking coding spec after a line containing * anything except a comment. */ - tok->read_coding_spec = 1; + tok->decoding_state = STATE_NORMAL; break; } } return 1; } - tok->read_coding_spec = 1; + tok->decoding_state = STATE_NORMAL; if (tok->encoding == NULL) { - assert(tok->decoding_state == STATE_RAW); - if (strcmp(cs, "utf-8") == 0) { - tok->encoding = cs; - } else { - r = set_readline(tok, cs); - if (r) { - tok->encoding = cs; - tok->decoding_state = STATE_NORMAL; - } - else { - PyErr_Format(PyExc_SyntaxError, - "encoding problem: %s", cs); - PyMem_FREE(cs); - } + assert(tok->decoding_readline == NULL); + if (strcmp(cs, "utf-8") != 0 && !set_readline(tok, cs)) { + error_ret(tok); + PyErr_Format(PyExc_SyntaxError, "encoding problem: %s", cs); + PyMem_Free(cs); + return 0; } + tok->encoding = cs; } else { /* then, compare cs with BOM */ - r = (strcmp(tok->encoding, cs) == 0); - if (!r) + if (strcmp(tok->encoding, cs) != 0) { + error_ret(tok); PyErr_Format(PyExc_SyntaxError, "encoding problem: %s with BOM", cs); - PyMem_FREE(cs); + PyMem_Free(cs); + return 0; + } + PyMem_Free(cs); } - return r; + return 1; } /* See whether the file starts with a BOM. If it does, @@ -269,7 +264,7 @@ check_bom(int get_char(struct tok_state *), { int ch1, ch2, ch3; ch1 = get_char(tok); - tok->decoding_state = STATE_RAW; + tok->decoding_state = STATE_SEEK_CODING; if (ch1 == EOF) { return 1; } else if (ch1 == 0xEF) { @@ -315,7 +310,7 @@ check_bom(int get_char(struct tok_state *), return 1; } if (tok->encoding != NULL) - PyMem_FREE(tok->encoding); + PyMem_Free(tok->encoding); tok->encoding = new_string("utf-8", 5, tok); if (!tok->encoding) return 0; @@ -323,6 +318,36 @@ check_bom(int get_char(struct tok_state *), return 1; } +static int +tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) { + assert(tok->fp_interactive); + + if (!line) { + return 0; + } + + Py_ssize_t current_size = tok->interactive_src_end - tok->interactive_src_start; + Py_ssize_t line_size = strlen(line); + char* new_str = tok->interactive_src_start; + + new_str = PyMem_Realloc(new_str, current_size + line_size + 1); + if (!new_str) { + if (tok->interactive_src_start) { + PyMem_Free(tok->interactive_src_start); + } + tok->interactive_src_start = NULL; + tok->interactive_src_end = NULL; + tok->done = E_NOMEM; + return -1; + } + strcpy(new_str + current_size, line); + + tok->interactive_src_start = new_str; + tok->interactive_src_end = new_str + current_size + line_size; + return 0; +} + + /* Read a line of text from TOK into S, using the stream in TOK. Return NULL on failure, else S. @@ -330,73 +355,77 @@ check_bom(int get_char(struct tok_state *), 1) NULL: need to call tok->decoding_readline to get a new line 2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and stored the result in tok->decoding_buffer - 3) PyByteArrayObject *: previous call to fp_readl did not have enough room + 3) PyByteArrayObject *: previous call to tok_readline_recode did not have enough room (in the s buffer) to copy entire contents of the line read by tok->decoding_readline. tok->decoding_buffer has the overflow. - In this case, fp_readl is called in a loop (with an expanded buffer) + In this case, tok_readline_recode is called in a loop (with an expanded buffer) until the buffer ends with a '\n' (or until the end of the file is - reached): see tok_nextc and its calls to decoding_fgets. + reached): see tok_nextc and its calls to tok_reserve_buf. */ -static char * -fp_readl(char *s, int size, struct tok_state *tok) +static int +tok_reserve_buf(struct tok_state *tok, Py_ssize_t size) { - PyObject* bufobj; - const char *buf; - Py_ssize_t buflen; - - /* Ask for one less byte so we can terminate it */ - assert(size > 0); - size--; - - if (tok->decoding_buffer) { - bufobj = tok->decoding_buffer; - Py_INCREF(bufobj); - } - else - { - bufobj = _PyObject_CallNoArg(tok->decoding_readline); - if (bufobj == NULL) - goto error; - } - if (PyUnicode_CheckExact(bufobj)) - { - buf = PyUnicode_AsUTF8AndSize(bufobj, &buflen); - if (buf == NULL) { - goto error; - } - } - else - { - buf = PyByteArray_AsString(bufobj); - if (buf == NULL) { - goto error; + Py_ssize_t cur = tok->cur - tok->buf; + Py_ssize_t oldsize = tok->inp - tok->buf; + Py_ssize_t newsize = oldsize + Py_MAX(size, oldsize >> 1); + if (newsize > tok->end - tok->buf) { + char *newbuf = tok->buf; + 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; + newbuf = (char *)PyMem_Realloc(newbuf, newsize); + if (newbuf == NULL) { + tok->done = E_NOMEM; + return 0; } - buflen = PyByteArray_GET_SIZE(bufobj); + tok->buf = newbuf; + tok->cur = tok->buf + cur; + tok->inp = tok->buf + oldsize; + tok->end = tok->buf + newsize; + 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; } + return 1; +} - Py_XDECREF(tok->decoding_buffer); - if (buflen > size) { - /* Too many chars, the rest goes into tok->decoding_buffer */ - tok->decoding_buffer = PyByteArray_FromStringAndSize(buf+size, - buflen-size); - if (tok->decoding_buffer == NULL) +static int +tok_readline_recode(struct tok_state *tok) { + PyObject *line; + const char *buf; + Py_ssize_t buflen; + line = tok->decoding_buffer; + if (line == NULL) { + line = PyObject_CallNoArgs(tok->decoding_readline); + if (line == NULL) { + error_ret(tok); goto error; - buflen = size; + } } - else + else { tok->decoding_buffer = NULL; - - memcpy(s, buf, buflen); - s[buflen] = '\0'; - if (buflen == 0) /* EOF */ - s = NULL; - Py_DECREF(bufobj); - return s; - + } + buf = PyUnicode_AsUTF8AndSize(line, &buflen); + if (buf == NULL) { + error_ret(tok); + goto error; + } + if (!tok_reserve_buf(tok, buflen + 1)) { + goto error; + } + memcpy(tok->inp, buf, buflen); + tok->inp += buflen; + *tok->inp = '\0'; + if (tok->fp_interactive && + tok_concatenate_interactive_new_line(tok, buf) == -1) { + goto error; + } + Py_DECREF(line); + return 1; error: - Py_XDECREF(bufobj); - return error_ret(tok); + Py_XDECREF(line); + return 0; } /* Set the readline function for TOK to a StreamReader's @@ -497,82 +526,30 @@ static int valid_utf8(const unsigned char* s) return length; } -/* Read a line of input from TOK. Determine encoding - if necessary. */ - -static char * -decoding_fgets(char *s, int size, struct tok_state *tok) +static int +ensure_utf8(char *line, struct tok_state *tok) { - char *line = NULL; int badchar = 0; - for (;;) { - if (tok->decoding_state == STATE_NORMAL) { - /* We already have a codec associated with - this input. */ - line = fp_readl(s, size, tok); - break; - } else if (tok->decoding_state == STATE_RAW) { - /* We want a 'raw' read. */ - line = Py_UniversalNewlineFgets(s, size, - tok->fp, NULL); + unsigned char *c; + int length; + for (c = (unsigned char *)line; *c; c += length) { + if (!(length = valid_utf8(c))) { + badchar = *c; break; - } else { - /* We have not yet determined the encoding. - If an encoding is found, use the file-pointer - reader functions from now on. */ - if (!check_bom(fp_getc, fp_ungetc, fp_setreadl, tok)) - return error_ret(tok); - assert(tok->decoding_state != STATE_INIT); - } - } - if (line != NULL && tok->lineno < 2 && !tok->read_coding_spec) { - if (!check_coding_spec(line, strlen(line), tok, fp_setreadl)) { - return error_ret(tok); } } - /* The default encoding is UTF-8, so make sure we don't have any - non-UTF-8 sequences in it. */ - if (line && !tok->encoding) { - unsigned char *c; - int length; - for (c = (unsigned char *)line; *c; c += length) - if (!(length = valid_utf8(c))) { - badchar = *c; - break; - } - } if (badchar) { /* Need to add 1 to the line number, since this line - has not been counted, yet. */ + has not been counted, yet. */ PyErr_Format(PyExc_SyntaxError, - "Non-UTF-8 code starting with '\\x%.2x' " - "in file %U on line %i, " - "but no encoding declared; " - "see https://python.org/dev/peps/pep-0263/ for details", - badchar, tok->filename, tok->lineno + 1); - return error_ret(tok); - } - return line; -} - -static int -decoding_feof(struct tok_state *tok) -{ - if (tok->decoding_state != STATE_NORMAL) { - return feof(tok->fp); - } else { - PyObject* buf = tok->decoding_buffer; - if (buf == NULL) { - buf = _PyObject_CallNoArg(tok->decoding_readline); - if (buf == NULL) { - error_ret(tok); - return 1; - } else { - tok->decoding_buffer = buf; - } - } - return PyObject_Length(buf) == 0; + "Non-UTF-8 code starting with '\\x%.2x' " + "in file %U on line %i, " + "but no encoding declared; " + "see https://python.org/dev/peps/pep-0263/ for details", + badchar, tok->filename, tok->lineno + 1); + return 0; } + return 1; } /* Fetch a byte from TOK, using the string buffer. */ @@ -620,7 +597,7 @@ translate_newlines(const char *s, int exec_input, struct tok_state *tok) { size_t needed_length = strlen(s) + 2, final_length; char *buf, *current; char c = '\0'; - buf = PyMem_MALLOC(needed_length); + buf = PyMem_Malloc(needed_length); if (buf == NULL) { tok->done = E_NOMEM; return NULL; @@ -651,9 +628,9 @@ translate_newlines(const char *s, int exec_input, struct tok_state *tok) { final_length = current - buf + 1; if (final_length < needed_length && final_length) { /* should never fail */ - char* result = PyMem_REALLOC(buf, final_length); + char* result = PyMem_Realloc(buf, final_length); if (result == NULL) { - PyMem_FREE(buf); + PyMem_Free(buf); } buf = result; } @@ -700,12 +677,13 @@ decode_str(const char *input, int single, struct tok_state *tok) /* need to check line 1 and 2 separately since check_coding_spec assumes a single line as input */ if (newl[0]) { - if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) - return error_ret(tok); - if (tok->enc == NULL && !tok->read_coding_spec && newl[1]) { + if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) { + return NULL; + } + if (tok->enc == NULL && tok->decoding_state != STATE_NORMAL && newl[1]) { if (!check_coding_spec(newl[0]+1, newl[1] - newl[0], tok, buf_setreadl)) - return error_ret(tok); + return NULL; } } if (tok->enc != NULL) { @@ -741,6 +719,8 @@ PyTokenizer_FromString(const char *str, int exec_input) return tok; } +/* Set up tokenizer for UTF-8 string */ + struct tok_state * PyTokenizer_FromUTF8(const char *str, int exec_input) { @@ -753,16 +733,14 @@ PyTokenizer_FromUTF8(const char *str, int exec_input) PyTokenizer_Free(tok); return NULL; } - tok->decoding_state = STATE_RAW; - tok->read_coding_spec = 1; + tok->decoding_state = STATE_NORMAL; tok->enc = NULL; tok->str = translated; - tok->encoding = (char *)PyMem_MALLOC(6); + tok->encoding = new_string("utf-8", 5, tok); if (!tok->encoding) { PyTokenizer_Free(tok); return NULL; } - strcpy(tok->encoding, "utf-8"); tok->buf = tok->cur = tok->inp = translated; tok->end = translated; @@ -778,7 +756,7 @@ PyTokenizer_FromFile(FILE *fp, const char* enc, struct tok_state *tok = tok_new(); if (tok == NULL) return NULL; - if ((tok->buf = (char *)PyMem_MALLOC(BUFSIZ)) == NULL) { + if ((tok->buf = (char *)PyMem_Malloc(BUFSIZ)) == NULL) { PyTokenizer_Free(tok); return NULL; } @@ -790,237 +768,296 @@ PyTokenizer_FromFile(FILE *fp, const char* enc, if (enc != NULL) { /* Must copy encoding declaration since it gets copied into the parse tree. */ - tok->encoding = PyMem_MALLOC(strlen(enc)+1); + tok->encoding = new_string(enc, strlen(enc), tok); if (!tok->encoding) { PyTokenizer_Free(tok); return NULL; } - strcpy(tok->encoding, enc); tok->decoding_state = STATE_NORMAL; } return tok; } - /* Free a tok_state structure */ void PyTokenizer_Free(struct tok_state *tok) { - if (tok->encoding != NULL) - PyMem_FREE(tok->encoding); + if (tok->encoding != NULL) { + PyMem_Free(tok->encoding); + } Py_XDECREF(tok->decoding_readline); Py_XDECREF(tok->decoding_buffer); Py_XDECREF(tok->filename); - if (tok->fp != NULL && tok->buf != NULL) - PyMem_FREE(tok->buf); - if (tok->input) - PyMem_FREE(tok->input); - PyMem_FREE(tok); + if (tok->fp != NULL && tok->buf != NULL) { + PyMem_Free(tok->buf); + } + if (tok->input) { + PyMem_Free(tok->input); + } + if (tok->interactive_src_start != NULL) { + PyMem_Free(tok->interactive_src_start); + } + PyMem_Free(tok); +} + +static int +tok_readline_raw(struct tok_state *tok) +{ + do { + if (!tok_reserve_buf(tok, BUFSIZ)) { + return 0; + } + char *line = Py_UniversalNewlineFgets(tok->inp, + (int)(tok->end - tok->inp), + tok->fp, NULL); + if (line == NULL) { + return 1; + } + if (tok->fp_interactive && + tok_concatenate_interactive_new_line(tok, line) == -1) { + return 0; + } + tok->inp = strchr(tok->inp, '\0'); + if (tok->inp == tok->buf) { + return 0; + } + } while (tok->inp[-1] != '\n'); + return 1; +} + +static int +tok_underflow_string(struct tok_state *tok) { + char *end = strchr(tok->inp, '\n'); + if (end != NULL) { + end++; + } + else { + end = strchr(tok->inp, '\0'); + if (end == tok->inp) { + tok->done = E_EOF; + return 0; + } + } + if (tok->start == NULL) { + tok->buf = tok->cur; + } + tok->line_start = tok->cur; + tok->lineno++; + tok->inp = end; + return 1; +} + +static int +tok_underflow_interactive(struct tok_state *tok) { + if (tok->interactive_underflow == IUNDERFLOW_STOP) { + tok->done = E_INTERACT_STOP; + return 1; + } + char *newtok = PyOS_Readline(tok->fp ? tok->fp : stdin, stdout, tok->prompt); + if (newtok != NULL) { + char *translated = translate_newlines(newtok, 0, tok); + PyMem_Free(newtok); + if (translated == NULL) { + return 0; + } + newtok = translated; + } + if (tok->encoding && newtok && *newtok) { + /* Recode to UTF-8 */ + Py_ssize_t buflen; + const char* buf; + PyObject *u = translate_into_utf8(newtok, tok->encoding); + PyMem_Free(newtok); + if (u == NULL) { + tok->done = E_DECODE; + return 0; + } + buflen = PyBytes_GET_SIZE(u); + buf = PyBytes_AS_STRING(u); + newtok = PyMem_Malloc(buflen+1); + if (newtok == NULL) { + Py_DECREF(u); + tok->done = E_NOMEM; + return 0; + } + strcpy(newtok, buf); + Py_DECREF(u); + } + if (tok->fp_interactive && + tok_concatenate_interactive_new_line(tok, newtok) == -1) { + PyMem_Free(newtok); + return 0; + } + if (tok->nextprompt != NULL) { + tok->prompt = tok->nextprompt; + } + if (newtok == NULL) { + tok->done = E_INTR; + } + else if (*newtok == '\0') { + PyMem_Free(newtok); + tok->done = E_EOF; + } + else if (tok->start != NULL) { + Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; + size_t size = strlen(newtok); + tok->lineno++; + if (!tok_reserve_buf(tok, size + 1)) { + PyMem_Free(tok->buf); + tok->buf = NULL; + PyMem_Free(newtok); + return 0; + } + memcpy(tok->cur, newtok, size + 1); + PyMem_Free(newtok); + tok->inp += size; + tok->multi_line_start = tok->buf + cur_multi_line_start; + } + else { + tok->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; + } + if (tok->done != E_OK) { + if (tok->prompt != NULL) { + PySys_WriteStderr("\n"); + } + return 0; + } + return 1; +} + +static int +tok_underflow_file(struct tok_state *tok) { + if (tok->start == NULL) { + tok->cur = tok->inp = tok->buf; + } + if (tok->decoding_state == STATE_INIT) { + /* We have not yet determined the encoding. + If an encoding is found, use the file-pointer + reader functions from now on. */ + if (!check_bom(fp_getc, fp_ungetc, fp_setreadl, tok)) { + error_ret(tok); + return 0; + } + assert(tok->decoding_state != STATE_INIT); + } + /* Read until '\n' or EOF */ + if (tok->decoding_readline != NULL) { + /* We already have a codec associated with this input. */ + if (!tok_readline_recode(tok)) { + return 0; + } + } + else { + /* We want a 'raw' read. */ + if (!tok_readline_raw(tok)) { + return 0; + } + } + if (tok->inp == tok->cur) { + tok->done = E_EOF; + return 0; + } + if (tok->inp[-1] != '\n') { + /* Last line does not end in \n, fake one */ + *tok->inp++ = '\n'; + *tok->inp = '\0'; + } + + tok->lineno++; + if (tok->decoding_state != STATE_NORMAL) { + if (tok->lineno > 2) { + tok->decoding_state = STATE_NORMAL; + } + else if (!check_coding_spec(tok->cur, strlen(tok->cur), + tok, fp_setreadl)) + { + return 0; + } + } + /* 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) +{ + if (s == NULL) { + fputs("NULL", f); + return; + } + putc('"', f); + while (size-- > 0) { + unsigned char c = *s++; + switch (c) { + case '\n': fputs("\\n", f); break; + case '\r': fputs("\\r", f); break; + case '\t': fputs("\\t", f); break; + case '\f': fputs("\\f", f); break; + case '\'': fputs("\\'", f); break; + case '"': fputs("\\\"", f); break; + default: + if (0x20 <= c && c <= 0x7f) + putc(c, f); + else + fprintf(f, "\\x%02x", c); + } + } + putc('"', f); } +#endif /* Get next char, updating state; error code goes into tok->done */ static int tok_nextc(struct tok_state *tok) { + int rc; for (;;) { if (tok->cur != tok->inp) { return Py_CHARMASK(*tok->cur++); /* Fast path */ } - if (tok->done != E_OK) - return EOF; + if (tok->done != E_OK) { + return EOF; + } if (tok->fp == NULL) { - char *end = strchr(tok->inp, '\n'); - if (end != NULL) - end++; - else { - end = strchr(tok->inp, '\0'); - if (end == tok->inp) { - tok->done = E_EOF; - return EOF; - } - } - if (tok->start == NULL) - tok->buf = tok->cur; - tok->line_start = tok->cur; - tok->lineno++; - tok->inp = end; - return Py_CHARMASK(*tok->cur++); + rc = tok_underflow_string(tok); } - if (tok->prompt != NULL) { - char *newtok = PyOS_Readline(stdin, stdout, tok->prompt); - if (newtok != NULL) { - char *translated = translate_newlines(newtok, 0, tok); - PyMem_FREE(newtok); - if (translated == NULL) - return EOF; - newtok = translated; - } - if (tok->encoding && newtok && *newtok) { - /* Recode to UTF-8 */ - Py_ssize_t buflen; - const char* buf; - PyObject *u = translate_into_utf8(newtok, tok->encoding); - PyMem_FREE(newtok); - if (!u) { - tok->done = E_DECODE; - return EOF; - } - buflen = PyBytes_GET_SIZE(u); - buf = PyBytes_AS_STRING(u); - newtok = PyMem_MALLOC(buflen+1); - if (newtok == NULL) { - Py_DECREF(u); - tok->done = E_NOMEM; - return EOF; - } - strcpy(newtok, buf); - Py_DECREF(u); - } - if (tok->nextprompt != NULL) - tok->prompt = tok->nextprompt; - if (newtok == NULL) - tok->done = E_INTR; - else if (*newtok == '\0') { - PyMem_FREE(newtok); - tok->done = E_EOF; - } - else if (tok->start != NULL) { - size_t start = tok->start - tok->buf; - size_t oldlen = tok->cur - tok->buf; - size_t newlen = oldlen + strlen(newtok); - Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; - char *buf = tok->buf; - buf = (char *)PyMem_REALLOC(buf, newlen+1); - tok->lineno++; - if (buf == NULL) { - PyMem_FREE(tok->buf); - tok->buf = NULL; - PyMem_FREE(newtok); - tok->done = E_NOMEM; - return EOF; - } - tok->buf = buf; - tok->cur = tok->buf + oldlen; - tok->multi_line_start = tok->buf + cur_multi_line_start; - tok->line_start = tok->cur; - strcpy(tok->buf + oldlen, newtok); - PyMem_FREE(newtok); - tok->inp = tok->buf + newlen; - tok->end = tok->inp + 1; - tok->start = tok->buf + start; - } - else { - tok->lineno++; - if (tok->buf != NULL) - 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; - } + else if (tok->prompt != NULL) { + rc = tok_underflow_interactive(tok); } else { - int done = 0; - Py_ssize_t cur = 0; - char *pt; - if (tok->start == NULL) { - if (tok->buf == NULL) { - tok->buf = (char *) - PyMem_MALLOC(BUFSIZ); - if (tok->buf == NULL) { - tok->done = E_NOMEM; - return EOF; - } - tok->end = tok->buf + BUFSIZ; - } - if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf), - tok) == NULL) { - if (!tok->decoding_erred) - tok->done = E_EOF; - done = 1; - } - else { - tok->done = E_OK; - tok->inp = strchr(tok->buf, '\0'); - done = tok->inp == tok->buf || tok->inp[-1] == '\n'; - } - } - else { - cur = tok->cur - tok->buf; - if (decoding_feof(tok)) { - tok->done = E_EOF; - done = 1; - } - else - tok->done = E_OK; - } - tok->lineno++; - /* Read until '\n' or EOF */ - while (!done) { - Py_ssize_t curstart = tok->start == NULL ? -1 : - tok->start - tok->buf; - Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; - Py_ssize_t curvalid = tok->inp - tok->buf; - Py_ssize_t newsize = curvalid + BUFSIZ; - char *newbuf = tok->buf; - newbuf = (char *)PyMem_REALLOC(newbuf, - newsize); - if (newbuf == NULL) { - tok->done = E_NOMEM; - tok->cur = tok->inp; - return EOF; - } - tok->buf = newbuf; - tok->cur = tok->buf + cur; - tok->multi_line_start = tok->buf + cur_multi_line_start; - tok->line_start = tok->cur; - tok->inp = tok->buf + curvalid; - tok->end = tok->buf + newsize; - tok->start = curstart < 0 ? NULL : - tok->buf + curstart; - if (decoding_fgets(tok->inp, - (int)(tok->end - tok->inp), - tok) == NULL) { - /* Break out early on decoding - errors, as tok->buf will be NULL - */ - if (tok->decoding_erred) - return EOF; - /* Last line does not end in \n, - fake one */ - if (tok->inp[-1] != '\n') - strcpy(tok->inp, "\n"); - } - tok->inp = strchr(tok->inp, '\0'); - done = tok->inp[-1] == '\n'; - } - if (tok->buf != NULL) { - tok->cur = tok->buf + cur; - tok->line_start = tok->cur; - /* replace "\r\n" with "\n" */ - /* For Mac leave the \r, giving a syntax error */ - pt = tok->inp - 2; - if (pt >= tok->buf && *pt == '\r') { - *pt++ = '\n'; - *pt = '\0'; - tok->inp = pt; - } - } + rc = tok_underflow_file(tok); } - if (tok->done != E_OK) { - if (tok->prompt != NULL) - PySys_WriteStderr("\n"); +#if defined(Py_DEBUG) + if (Py_DebugFlag) { + fprintf(stderr, "line[%d] = ", tok->lineno); + print_escape(stderr, tok->cur, tok->inp - tok->cur); + fprintf(stderr, " tok->done = %d\n", tok->done); + } +#endif + if (!rc) { tok->cur = tok->inp; return EOF; } + tok->line_start = tok->cur; } - /*NOTREACHED*/ + Py_UNREACHABLE(); } - /* Back-up one character */ static void @@ -1030,25 +1067,19 @@ tok_backup(struct tok_state *tok, int c) if (--tok->cur < tok->buf) { Py_FatalError("tokenizer beginning of buffer"); } - if (*tok->cur != c) { - *tok->cur = c; + if ((int)(unsigned char)*tok->cur != c) { + Py_FatalError("tok_backup: wrong character"); } } } - static int -syntaxerror(struct tok_state *tok, const char *format, ...) +_syntaxerror_range(struct tok_state *tok, const char *format, + int col_offset, int end_col_offset, + va_list vargs) { PyObject *errmsg, *errtext, *args; - 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) { goto error; } @@ -1058,7 +1089,14 @@ syntaxerror(struct tok_state *tok, const char *format, ...) if (!errtext) { goto error; } - int offset = (int)PyUnicode_GET_LENGTH(errtext); + + if (col_offset == -1) { + col_offset = (int)PyUnicode_GET_LENGTH(errtext); + } + if (end_col_offset == -1) { + end_col_offset = col_offset; + } + Py_ssize_t line_len = strcspn(tok->line_start, "\n"); if (line_len != tok->cur - tok->line_start) { Py_DECREF(errtext); @@ -1069,8 +1107,8 @@ syntaxerror(struct tok_state *tok, const char *format, ...) goto error; } - args = Py_BuildValue("(O(OiiN))", errmsg, - tok->filename, tok->lineno, offset, errtext); + args = Py_BuildValue("(O(OiiNii))", errmsg, tok->filename, tok->lineno, + col_offset, errtext, tok->lineno, end_col_offset); if (args) { PyErr_SetObject(PyExc_SyntaxError, args); Py_DECREF(args); @@ -1082,6 +1120,38 @@ error: return ERRORTOKEN; } +static int +syntaxerror(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, -1, -1, vargs); + va_end(vargs); + return ret; +} + +static int +syntaxerror_known_range(struct tok_state *tok, + int col_offset, int end_col_offset, + 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) { @@ -1090,6 +1160,116 @@ indenterror(struct tok_state *tok) return ERRORTOKEN; } +static int +parser_warn(struct tok_state *tok, 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) { + goto error; + } + + if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, errmsg, tok->filename, + tok->lineno, NULL, NULL) < 0) { + if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + /* Replace the DeprecationWarning exception with a SyntaxError + to get a more accurate error report */ + PyErr_Clear(); + syntaxerror(tok, "%U", errmsg); + } + goto error; + } + Py_DECREF(errmsg); + return 0; + +error: + Py_XDECREF(errmsg); + tok->done = E_ERROR; + return -1; +} + +static int +lookahead(struct tok_state *tok, const char *test) +{ + const char *s = test; + int res = 0; + while (1) { + int c = tok_nextc(tok); + if (*s == 0) { + res = !is_potential_identifier_char(c); + } + else if (c == *s) { + s++; + continue; + } + + tok_backup(tok, c); + while (s != test) { + tok_backup(tok, *--s); + } + return res; + } +} + +static int +verify_end_of_number(struct tok_state *tok, int c, const char *kind) +{ + /* Emit a deprecation warning only if the numeric literal is immediately + * followed by one of keywords which can occurr after a numeric literal + * in valid code: "and", "else", "for", "if", "in", "is" and "or". + * It allows to gradually deprecate existing valid code without adding + * warning before error in most cases of invalid numeric literal (which + * would be confusiong and break existing tests). + * Raise a syntax error with slighly better message than plain + * "invalid syntax" if the numeric literal is immediately followed by + * other keyword or identifier. + */ + int r = 0; + if (c == 'a') { + r = lookahead(tok, "nd"); + } + else if (c == 'e') { + r = lookahead(tok, "lse"); + } + else if (c == 'f') { + r = lookahead(tok, "or"); + } + else if (c == 'i') { + int c2 = tok_nextc(tok); + if (c2 == 'f' || c2 == 'n' || c2 == 's') { + r = 1; + } + tok_backup(tok, c2); + } + else if (c == 'o') { + r = lookahead(tok, "r"); + } + else if (c == 'n') { + r = lookahead(tok, "ot"); + } + if (r) { + tok_backup(tok, c); + if (parser_warn(tok, "invalid %s literal", kind)) { + return 0; + } + tok_nextc(tok); + } + else /* In future releases, only error will remain. */ + if (is_potential_identifier_char(c)) { + tok_backup(tok, c); + syntaxerror(tok, "invalid %s literal", kind); + return 0; + } + return 1; +} + /* Verify that the identifier follows PEP 3131. All identifier strings are guaranteed to be "ready" unicode objects. */ @@ -1170,6 +1350,24 @@ tok_decimal_tail(struct tok_state *tok) /* Get next token, after space stripping etc. */ +static inline int +tok_continuation_line(struct tok_state *tok) { + int c = tok_nextc(tok); + if (c != '\n') { + tok->done = E_LINECONT; + return -1; + } + c = tok_nextc(tok); + if (c == EOF) { + tok->done = E_EOF; + tok->cur = tok->inp; + return -1; + } else { + tok_backup(tok, c); + } + return c; +} + static int tok_get(struct tok_state *tok, const char **p_start, const char **p_end) { @@ -1186,6 +1384,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) int col = 0; int altcol = 0; tok->atbol = 0; + int cont_line_col = 0; for (;;) { c = tok_nextc(tok); if (c == ' ') { @@ -1198,14 +1397,23 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else if (c == '\014') {/* Control-L (formfeed) */ col = altcol = 0; /* For Emacs users */ } + else if (c == '\\') { + // Indentation cannot be split over multiple physical lines + // using backslashes. This means that if we found a backslash + // preceded by whitespace, **the first one we find** determines + // 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; + } + } else { break; } } tok_backup(tok, c); - if (c == '#' || c == '\n' || c == '\\') { + if (c == '#' || c == '\n') { /* Lines with only whitespace and/or comments - and/or a line continuation character shouldn't affect the indentation and are not passed to the parser as NEWLINE tokens, except *totally* empty lines in interactive @@ -1226,6 +1434,8 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) may need to skip to the end of a comment */ } if (!blankline && tok->level == 0) { + col = cont_line_col ? cont_line_col : col; + altcol = cont_line_col ? cont_line_col : altcol; if (col == tok->indstack[tok->indent]) { /* No change */ if (altcol != tok->altindstack[tok->indent]) { @@ -1373,8 +1583,15 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } } + if (tok->done == E_INTERACT_STOP) { + return ENDMARKER; + } + /* Check for EOF and errors now */ if (c == EOF) { + if (tok->level) { + return ERRORTOKEN; + } return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN; } @@ -1531,6 +1748,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) c = tok_nextc(tok); } while (isxdigit(c)); } while (c == '_'); + if (!verify_end_of_number(tok, c, "hexadecimal")) { + return ERRORTOKEN; + } } else if (c == 'o' || c == 'O') { /* Octal */ @@ -1540,12 +1760,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) c = tok_nextc(tok); } if (c < '0' || c >= '8') { - tok_backup(tok, c); if (isdigit(c)) { return syntaxerror(tok, "invalid digit '%c' in octal literal", c); } else { + tok_backup(tok, c); return syntaxerror(tok, "invalid octal literal"); } } @@ -1557,6 +1777,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) return syntaxerror(tok, "invalid digit '%c' in octal literal", c); } + if (!verify_end_of_number(tok, c, "octal")) { + return ERRORTOKEN; + } } else if (c == 'b' || c == 'B') { /* Binary */ @@ -1566,12 +1789,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) c = tok_nextc(tok); } if (c != '0' && c != '1') { - tok_backup(tok, c); if (isdigit(c)) { return syntaxerror(tok, "invalid digit '%c' in binary literal", c); } else { + tok_backup(tok, c); return syntaxerror(tok, "invalid binary literal"); } } @@ -1583,6 +1806,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) return syntaxerror(tok, "invalid digit '%c' in binary literal", c); } + if (!verify_end_of_number(tok, c, "binary")) { + return ERRORTOKEN; + } } else { int nonzero = 0; @@ -1601,6 +1827,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } c = tok_nextc(tok); } + char* zeros_end = tok->cur; if (isdigit(c)) { nonzero = 1; c = tok_decimal_tail(tok); @@ -1621,10 +1848,15 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else if (nonzero) { /* Old-style octal: now disallowed. */ tok_backup(tok, c); - return syntaxerror(tok, - "leading zeros in decimal integer " - "literals are not permitted; " - "use an 0o prefix for octal integers"); + return 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"); + } + if (!verify_end_of_number(tok, c, "decimal")) { + return ERRORTOKEN; } } } @@ -1661,6 +1893,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } } else if (!isdigit(c)) { tok_backup(tok, c); + if (!verify_end_of_number(tok, e, "decimal")) { + return ERRORTOKEN; + } tok_backup(tok, e); *p_start = tok->start; *p_end = tok->cur; @@ -1675,6 +1910,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Imaginary part */ imaginary: c = tok_nextc(tok); + if (!verify_end_of_number(tok, c, "imaginary")) { + return ERRORTOKEN; + } + } + else if (!verify_end_of_number(tok, c, "decimal")) { + return ERRORTOKEN; } } } @@ -1716,20 +1957,32 @@ 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 (c == EOF) { + if (c == EOF || (quote_size == 1 && c == '\n')) { + 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 *)tok->start; + tok->cur++; + tok->line_start = tok->multi_line_start; + int start = tok->lineno; + tok->lineno = tok->first_lineno; if (quote_size == 3) { - tok->done = E_EOFS; + syntaxerror(tok, "unterminated triple-quoted string literal" + " (detected at line %d)", start); + if (c != '\n') { + tok->done = E_EOFS; + } + return ERRORTOKEN; } else { - tok->done = E_EOLS; + syntaxerror(tok, "unterminated string literal (detected at" + " line %d)", start); + if (c != '\n') { + tok->done = E_EOLS; + } + return ERRORTOKEN; } - tok->cur = tok->inp; - return ERRORTOKEN; - } - if (quote_size == 1 && c == '\n') { - tok->done = E_EOLS; - tok->cur = tok->inp; - return ERRORTOKEN; } if (c == quote) { end_quote_size += 1; @@ -1749,19 +2002,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Line continuation */ if (c == '\\') { - c = tok_nextc(tok); - if (c != '\n') { - tok->done = E_LINECONT; + if ((c = tok_continuation_line(tok)) == -1) { return ERRORTOKEN; } - c = tok_nextc(tok); - if (c == EOF) { - tok->done = E_EOF; - tok->cur = tok->inp; - return ERRORTOKEN; - } else { - tok_backup(tok, c); - } tok->cont_line = 1; goto again; /* Read next line */ } @@ -1796,6 +2039,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } tok->parenstack[tok->level] = c; tok->parenlinenostack[tok->level] = tok->lineno; + tok->parencolstack[tok->level] = (int)(tok->start - tok->line_start); tok->level++; break; case ')': @@ -1850,7 +2094,7 @@ PyTokenizer_Get(struct tok_state *tok, const char **p_start, const char **p_end) encoding in the first or second line of the file (in which case the encoding should be assumed to be UTF-8). - The char* returned is malloc'ed via PyMem_MALLOC() and thus must be freed + The char* returned is malloc'ed via PyMem_Malloc() and thus must be freed by the caller. */ char * @@ -1893,9 +2137,10 @@ PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) } fclose(fp); if (tok->encoding) { - encoding = (char *)PyMem_MALLOC(strlen(tok->encoding) + 1); - if (encoding) + encoding = (char *)PyMem_Malloc(strlen(tok->encoding) + 1); + if (encoding) { strcpy(encoding, tok->encoding); + } } PyTokenizer_Free(tok); return encoding; @@ -1912,9 +2157,9 @@ PyTokenizer_FindEncoding(int fd) void tok_dump(int type, char *start, char *end) { - printf("%s", _PyParser_TokenNames[type]); + fprintf(stderr, "%s", _PyParser_TokenNames[type]); if (type == NAME || type == NUMBER || type == STRING || type == OP) - printf("(%.*s)", (int)(end - start), start); + fprintf(stderr, "(%.*s)", (int)(end - start), start); } #endif diff --git a/contrib/tools/python3/src/Parser/tokenizer.h b/contrib/tools/python3/src/Parser/tokenizer.h index 5660ea38e94..61f0a6138f6 100644 --- a/contrib/tools/python3/src/Parser/tokenizer.h +++ b/contrib/tools/python3/src/Parser/tokenizer.h @@ -15,8 +15,16 @@ extern "C" { enum decoding_state { STATE_INIT, - STATE_RAW, - STATE_NORMAL /* have a codec associated with input */ + STATE_SEEK_CODING, + STATE_NORMAL +}; + +enum interactive_underflow_t { + /* Normal mode of operation: return a new token when asked in interactie 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, }; /* Tokenizer state */ @@ -26,6 +34,9 @@ struct tok_state { char *buf; /* Input buffer, or NULL; malloc'ed if fp != NULL */ char *cur; /* Next character in buffer */ char *inp; /* End of data in buffer */ + int fp_interactive; /* If the file descriptor is interactive */ + char *interactive_src_start; /* The start of the source parsed so far in interactive mode */ + char *interactive_src_end; /* The end of the source parsed so far in interactive mode */ const char *end; /* End of input buffer if buf != NULL */ const char *start; /* Start of current token if not NULL */ int done; /* E_OK normally, E_EOF at EOF, otherwise error code */ @@ -44,13 +55,13 @@ struct tok_state { /* Used to allow free continuations inside them */ char parenstack[MAXLEVEL]; int parenlinenostack[MAXLEVEL]; + int parencolstack[MAXLEVEL]; PyObject *filename; /* Stuff for checking on different tab sizes */ int altindstack[MAXINDENT]; /* Stack of alternate indents */ /* Stuff for PEP 0263 */ enum decoding_state decoding_state; int decoding_erred; /* whether erred in decoding */ - int read_coding_spec; /* whether 'coding:...' has been read */ char *encoding; /* Source encoding. */ int cont_line; /* whether we are in a continuation line. */ const char* line_start; /* pointer to start of current line */ @@ -60,7 +71,7 @@ struct tok_state { PyObject *decoding_readline; /* open(...).readline */ PyObject *decoding_buffer; const char* enc; /* Encoding for the current str. */ - char* str; + char* str; /* Source string being tokenized (if tokenizing from a string)*/ char* input; /* Tokenizer's newline translated copy of the string. */ int type_comments; /* Whether to look for type comments */ @@ -71,6 +82,8 @@ struct tok_state { int async_def_indent; /* Indentation level of the outermost 'async def'. */ int async_def_nl; /* =1 if the outermost 'async def' had at least one NEWLINE token after it. */ + /* How to proceed when asked for a new token in interactive mode */ + enum interactive_underflow_t interactive_underflow; }; extern struct tok_state *PyTokenizer_FromString(const char *, int); diff --git a/contrib/tools/python3/src/Python/Python-ast.c b/contrib/tools/python3/src/Python/Python-ast.c index 8b1c594a878..2f84cad7749 100644 --- a/contrib/tools/python3/src/Python/Python-ast.c +++ b/contrib/tools/python3/src/Python/Python-ast.c @@ -1,258 +1,31 @@ -/* File automatically generated by Parser/asdl_c.py. */ - -#include +// File automatically generated by Parser/asdl_c.py. #include "Python.h" -#include "Python-ast.h" -#include "structmember.h" // PyMemberDef - -typedef struct { - int initialized; - PyObject *AST_type; - PyObject *Add_singleton; - PyObject *Add_type; - PyObject *And_singleton; - PyObject *And_type; - PyObject *AnnAssign_type; - PyObject *Assert_type; - PyObject *Assign_type; - PyObject *AsyncFor_type; - PyObject *AsyncFunctionDef_type; - PyObject *AsyncWith_type; - PyObject *Attribute_type; - PyObject *AugAssign_type; - PyObject *Await_type; - PyObject *BinOp_type; - PyObject *BitAnd_singleton; - PyObject *BitAnd_type; - PyObject *BitOr_singleton; - PyObject *BitOr_type; - PyObject *BitXor_singleton; - PyObject *BitXor_type; - PyObject *BoolOp_type; - PyObject *Break_type; - PyObject *Call_type; - PyObject *ClassDef_type; - PyObject *Compare_type; - PyObject *Constant_type; - PyObject *Continue_type; - PyObject *Del_singleton; - PyObject *Del_type; - PyObject *Delete_type; - PyObject *DictComp_type; - PyObject *Dict_type; - PyObject *Div_singleton; - PyObject *Div_type; - PyObject *Eq_singleton; - PyObject *Eq_type; - PyObject *ExceptHandler_type; - PyObject *Expr_type; - PyObject *Expression_type; - PyObject *FloorDiv_singleton; - PyObject *FloorDiv_type; - PyObject *For_type; - PyObject *FormattedValue_type; - PyObject *FunctionDef_type; - PyObject *FunctionType_type; - PyObject *GeneratorExp_type; - PyObject *Global_type; - PyObject *GtE_singleton; - PyObject *GtE_type; - PyObject *Gt_singleton; - PyObject *Gt_type; - PyObject *IfExp_type; - PyObject *If_type; - PyObject *ImportFrom_type; - PyObject *Import_type; - PyObject *In_singleton; - PyObject *In_type; - PyObject *Interactive_type; - PyObject *Invert_singleton; - PyObject *Invert_type; - PyObject *IsNot_singleton; - PyObject *IsNot_type; - PyObject *Is_singleton; - PyObject *Is_type; - PyObject *JoinedStr_type; - PyObject *LShift_singleton; - PyObject *LShift_type; - PyObject *Lambda_type; - PyObject *ListComp_type; - PyObject *List_type; - PyObject *Load_singleton; - PyObject *Load_type; - PyObject *LtE_singleton; - PyObject *LtE_type; - PyObject *Lt_singleton; - PyObject *Lt_type; - PyObject *MatMult_singleton; - PyObject *MatMult_type; - PyObject *Mod_singleton; - PyObject *Mod_type; - PyObject *Module_type; - PyObject *Mult_singleton; - PyObject *Mult_type; - PyObject *Name_type; - PyObject *NamedExpr_type; - PyObject *Nonlocal_type; - PyObject *NotEq_singleton; - PyObject *NotEq_type; - PyObject *NotIn_singleton; - PyObject *NotIn_type; - PyObject *Not_singleton; - PyObject *Not_type; - PyObject *Or_singleton; - PyObject *Or_type; - PyObject *Pass_type; - PyObject *Pow_singleton; - PyObject *Pow_type; - PyObject *RShift_singleton; - PyObject *RShift_type; - PyObject *Raise_type; - PyObject *Return_type; - PyObject *SetComp_type; - PyObject *Set_type; - PyObject *Slice_type; - PyObject *Starred_type; - PyObject *Store_singleton; - PyObject *Store_type; - PyObject *Sub_singleton; - PyObject *Sub_type; - PyObject *Subscript_type; - PyObject *Try_type; - PyObject *Tuple_type; - PyObject *TypeIgnore_type; - PyObject *UAdd_singleton; - PyObject *UAdd_type; - PyObject *USub_singleton; - PyObject *USub_type; - PyObject *UnaryOp_type; - PyObject *While_type; - PyObject *With_type; - PyObject *YieldFrom_type; - PyObject *Yield_type; - PyObject *__dict__; - PyObject *__doc__; - PyObject *__module__; - PyObject *_attributes; - PyObject *_fields; - PyObject *alias_type; - PyObject *annotation; - PyObject *arg; - PyObject *arg_type; - PyObject *args; - PyObject *argtypes; - PyObject *arguments_type; - PyObject *asname; - PyObject *ast; - PyObject *attr; - PyObject *bases; - PyObject *body; - PyObject *boolop_type; - PyObject *cause; - PyObject *cmpop_type; - PyObject *col_offset; - PyObject *comparators; - PyObject *comprehension_type; - PyObject *context_expr; - PyObject *conversion; - PyObject *ctx; - PyObject *decorator_list; - PyObject *defaults; - PyObject *elt; - PyObject *elts; - PyObject *end_col_offset; - PyObject *end_lineno; - PyObject *exc; - PyObject *excepthandler_type; - PyObject *expr_context_type; - PyObject *expr_type; - PyObject *finalbody; - PyObject *format_spec; - PyObject *func; - PyObject *generators; - PyObject *handlers; - PyObject *id; - PyObject *ifs; - PyObject *is_async; - PyObject *items; - PyObject *iter; - PyObject *key; - PyObject *keys; - PyObject *keyword_type; - PyObject *keywords; - PyObject *kind; - PyObject *kw_defaults; - PyObject *kwarg; - PyObject *kwonlyargs; - PyObject *left; - PyObject *level; - PyObject *lineno; - PyObject *lower; - PyObject *mod_type; - PyObject *module; - PyObject *msg; - PyObject *name; - PyObject *names; - PyObject *op; - PyObject *operand; - PyObject *operator_type; - PyObject *ops; - PyObject *optional_vars; - PyObject *orelse; - PyObject *posonlyargs; - PyObject *returns; - PyObject *right; - PyObject *simple; - PyObject *slice; - PyObject *step; - PyObject *stmt_type; - PyObject *tag; - PyObject *target; - PyObject *targets; - PyObject *test; - PyObject *type; - PyObject *type_comment; - PyObject *type_ignore_type; - PyObject *type_ignores; - PyObject *unaryop_type; - PyObject *upper; - PyObject *value; - PyObject *values; - PyObject *vararg; - PyObject *withitem_type; -} astmodulestate; - +#include "pycore_ast.h" +#include "pycore_ast_state.h" // struct ast_state +#include "pycore_interp.h" // _PyInterpreterState.ast +#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "structmember.h" +#include // Forward declaration -static int init_types(astmodulestate *state); - -// bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state. -static astmodulestate global_ast_state = {0}; +static int init_types(struct ast_state *state); -static astmodulestate* -get_global_ast_state(void) +static struct ast_state* +get_ast_state(void) { - astmodulestate* state = &global_ast_state; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct ast_state *state = &interp->ast; if (!init_types(state)) { return NULL; } return state; } -static astmodulestate* -get_ast_state(PyObject* Py_UNUSED(module)) +void _PyAST_Fini(PyInterpreterState *interp) { - astmodulestate* state = get_global_ast_state(); - // get_ast_state() must only be called after _ast module is imported, - // and astmodule_exec() calls init_types() - assert(state != NULL); - return state; -} + struct ast_state *state = &interp->ast; -void _PyAST_Fini() -{ - astmodulestate* state = &global_ast_state; Py_CLEAR(state->AST_type); Py_CLEAR(state->Add_singleton); Py_CLEAR(state->Add_type); @@ -332,6 +105,15 @@ void _PyAST_Fini() Py_CLEAR(state->Lt_type); Py_CLEAR(state->MatMult_singleton); Py_CLEAR(state->MatMult_type); + Py_CLEAR(state->MatchAs_type); + Py_CLEAR(state->MatchClass_type); + Py_CLEAR(state->MatchMapping_type); + Py_CLEAR(state->MatchOr_type); + Py_CLEAR(state->MatchSequence_type); + Py_CLEAR(state->MatchSingleton_type); + Py_CLEAR(state->MatchStar_type); + Py_CLEAR(state->MatchValue_type); + Py_CLEAR(state->Match_type); Py_CLEAR(state->Mod_singleton); Py_CLEAR(state->Mod_type); Py_CLEAR(state->Module_type); @@ -378,6 +160,7 @@ void _PyAST_Fini() Py_CLEAR(state->Yield_type); Py_CLEAR(state->__dict__); Py_CLEAR(state->__doc__); + Py_CLEAR(state->__match_args__); Py_CLEAR(state->__module__); Py_CLEAR(state->_attributes); Py_CLEAR(state->_fields); @@ -394,7 +177,9 @@ void _PyAST_Fini() Py_CLEAR(state->bases); Py_CLEAR(state->body); Py_CLEAR(state->boolop_type); + Py_CLEAR(state->cases); Py_CLEAR(state->cause); + Py_CLEAR(state->cls); Py_CLEAR(state->cmpop_type); Py_CLEAR(state->col_offset); Py_CLEAR(state->comparators); @@ -416,6 +201,7 @@ void _PyAST_Fini() Py_CLEAR(state->format_spec); Py_CLEAR(state->func); Py_CLEAR(state->generators); + Py_CLEAR(state->guard); Py_CLEAR(state->handlers); Py_CLEAR(state->id); Py_CLEAR(state->ifs); @@ -429,11 +215,14 @@ void _PyAST_Fini() Py_CLEAR(state->kind); Py_CLEAR(state->kw_defaults); Py_CLEAR(state->kwarg); + Py_CLEAR(state->kwd_attrs); + Py_CLEAR(state->kwd_patterns); Py_CLEAR(state->kwonlyargs); Py_CLEAR(state->left); Py_CLEAR(state->level); Py_CLEAR(state->lineno); Py_CLEAR(state->lower); + Py_CLEAR(state->match_case_type); Py_CLEAR(state->mod_type); Py_CLEAR(state->module); Py_CLEAR(state->msg); @@ -445,13 +234,18 @@ void _PyAST_Fini() Py_CLEAR(state->ops); Py_CLEAR(state->optional_vars); Py_CLEAR(state->orelse); + Py_CLEAR(state->pattern); + Py_CLEAR(state->pattern_type); + Py_CLEAR(state->patterns); Py_CLEAR(state->posonlyargs); + Py_CLEAR(state->rest); Py_CLEAR(state->returns); Py_CLEAR(state->right); Py_CLEAR(state->simple); Py_CLEAR(state->slice); Py_CLEAR(state->step); Py_CLEAR(state->stmt_type); + Py_CLEAR(state->subject); Py_CLEAR(state->tag); Py_CLEAR(state->target); Py_CLEAR(state->targets); @@ -467,13 +261,18 @@ void _PyAST_Fini() Py_CLEAR(state->vararg); Py_CLEAR(state->withitem_type); +#if !defined(NDEBUG) + state->initialized = -1; +#else state->initialized = 0; +#endif } -static int init_identifiers(astmodulestate *state) +static int init_identifiers(struct ast_state *state) { if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0; if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0; + if ((state->__match_args__ = PyUnicode_InternFromString("__match_args__")) == NULL) return 0; if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0; if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0; if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0; @@ -486,7 +285,9 @@ static int init_identifiers(astmodulestate *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->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; if ((state->col_offset = PyUnicode_InternFromString("col_offset")) == NULL) return 0; if ((state->comparators = PyUnicode_InternFromString("comparators")) == NULL) return 0; if ((state->context_expr = PyUnicode_InternFromString("context_expr")) == NULL) return 0; @@ -503,6 +304,7 @@ static int init_identifiers(astmodulestate *state) if ((state->format_spec = PyUnicode_InternFromString("format_spec")) == NULL) return 0; if ((state->func = PyUnicode_InternFromString("func")) == NULL) return 0; if ((state->generators = PyUnicode_InternFromString("generators")) == NULL) return 0; + if ((state->guard = PyUnicode_InternFromString("guard")) == NULL) return 0; if ((state->handlers = PyUnicode_InternFromString("handlers")) == NULL) return 0; if ((state->id = PyUnicode_InternFromString("id")) == NULL) return 0; if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return 0; @@ -515,6 +317,8 @@ static int init_identifiers(astmodulestate *state) if ((state->kind = PyUnicode_InternFromString("kind")) == NULL) return 0; if ((state->kw_defaults = PyUnicode_InternFromString("kw_defaults")) == NULL) return 0; if ((state->kwarg = PyUnicode_InternFromString("kwarg")) == NULL) return 0; + if ((state->kwd_attrs = PyUnicode_InternFromString("kwd_attrs")) == NULL) return 0; + if ((state->kwd_patterns = PyUnicode_InternFromString("kwd_patterns")) == NULL) return 0; if ((state->kwonlyargs = PyUnicode_InternFromString("kwonlyargs")) == NULL) return 0; if ((state->left = PyUnicode_InternFromString("left")) == NULL) return 0; if ((state->level = PyUnicode_InternFromString("level")) == NULL) return 0; @@ -529,12 +333,16 @@ static int init_identifiers(astmodulestate *state) if ((state->ops = PyUnicode_InternFromString("ops")) == NULL) return 0; if ((state->optional_vars = PyUnicode_InternFromString("optional_vars")) == NULL) return 0; if ((state->orelse = PyUnicode_InternFromString("orelse")) == NULL) return 0; + if ((state->pattern = PyUnicode_InternFromString("pattern")) == NULL) return 0; + if ((state->patterns = PyUnicode_InternFromString("patterns")) == NULL) return 0; if ((state->posonlyargs = PyUnicode_InternFromString("posonlyargs")) == NULL) return 0; + if ((state->rest = PyUnicode_InternFromString("rest")) == NULL) return 0; if ((state->returns = PyUnicode_InternFromString("returns")) == NULL) return 0; if ((state->right = PyUnicode_InternFromString("right")) == NULL) return 0; if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return 0; if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return 0; if ((state->step = PyUnicode_InternFromString("step")) == NULL) return 0; + if ((state->subject = PyUnicode_InternFromString("subject")) == NULL) return 0; if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return 0; if ((state->target = PyUnicode_InternFromString("target")) == NULL) return 0; if ((state->targets = PyUnicode_InternFromString("targets")) == NULL) return 0; @@ -549,7 +357,21 @@ static int init_identifiers(astmodulestate *state) return 1; }; -static PyObject* ast2obj_mod(astmodulestate *state, void*); +GENERATE_ASDL_SEQ_CONSTRUCTOR(mod, mod_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(stmt, stmt_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(expr, expr_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(comprehension, comprehension_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(excepthandler, excepthandler_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(arguments, arguments_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(arg, arg_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(keyword, keyword_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(alias, alias_ty) +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) + +static PyObject* ast2obj_mod(struct ast_state *state, void*); static const char * const Module_fields[]={ "body", "type_ignores", @@ -570,7 +392,7 @@ static const char * const stmt_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_stmt(astmodulestate *state, void*); +static PyObject* ast2obj_stmt(struct ast_state *state, void*); static const char * const FunctionDef_fields[]={ "name", "args", @@ -650,6 +472,10 @@ static const char * const AsyncWith_fields[]={ "body", "type_comment", }; +static const char * const Match_fields[]={ + "subject", + "cases", +}; static const char * const Raise_fields[]={ "exc", "cause", @@ -687,7 +513,7 @@ static const char * const expr_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_expr(astmodulestate *state, void*); +static PyObject* ast2obj_expr(struct ast_state *state, void*); static const char * const BoolOp_fields[]={ "op", "values", @@ -800,12 +626,12 @@ static const char * const Slice_fields[]={ "upper", "step", }; -static PyObject* ast2obj_expr_context(astmodulestate *state, expr_context_ty); -static PyObject* ast2obj_boolop(astmodulestate *state, boolop_ty); -static PyObject* ast2obj_operator(astmodulestate *state, operator_ty); -static PyObject* ast2obj_unaryop(astmodulestate *state, unaryop_ty); -static PyObject* ast2obj_cmpop(astmodulestate *state, cmpop_ty); -static PyObject* ast2obj_comprehension(astmodulestate *state, void*); +static PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty); +static PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty); +static PyObject* ast2obj_operator(struct ast_state *state, operator_ty); +static PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty); +static PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty); +static PyObject* ast2obj_comprehension(struct ast_state *state, void*); static const char * const comprehension_fields[]={ "target", "iter", @@ -818,13 +644,13 @@ static const char * const excepthandler_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_excepthandler(astmodulestate *state, void*); +static PyObject* ast2obj_excepthandler(struct ast_state *state, void*); static const char * const ExceptHandler_fields[]={ "type", "name", "body", }; -static PyObject* ast2obj_arguments(astmodulestate *state, void*); +static PyObject* ast2obj_arguments(struct ast_state *state, void*); static const char * const arguments_fields[]={ "posonlyargs", "args", @@ -834,7 +660,7 @@ static const char * const arguments_fields[]={ "kwarg", "defaults", }; -static PyObject* ast2obj_arg(astmodulestate *state, void*); +static PyObject* ast2obj_arg(struct ast_state *state, void*); static const char * const arg_attributes[] = { "lineno", "col_offset", @@ -846,7 +672,7 @@ static const char * const arg_fields[]={ "annotation", "type_comment", }; -static PyObject* ast2obj_keyword(astmodulestate *state, void*); +static PyObject* ast2obj_keyword(struct ast_state *state, void*); static const char * const keyword_attributes[] = { "lineno", "col_offset", @@ -857,17 +683,66 @@ static const char * const keyword_fields[]={ "arg", "value", }; -static PyObject* ast2obj_alias(astmodulestate *state, void*); +static PyObject* ast2obj_alias(struct ast_state *state, void*); +static const char * const alias_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; static const char * const alias_fields[]={ "name", "asname", }; -static PyObject* ast2obj_withitem(astmodulestate *state, void*); +static PyObject* ast2obj_withitem(struct ast_state *state, void*); static const char * const withitem_fields[]={ "context_expr", "optional_vars", }; -static PyObject* ast2obj_type_ignore(astmodulestate *state, void*); +static PyObject* ast2obj_match_case(struct ast_state *state, void*); +static const char * const match_case_fields[]={ + "pattern", + "guard", + "body", +}; +static const char * const pattern_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; +static PyObject* ast2obj_pattern(struct ast_state *state, void*); +static const char * const MatchValue_fields[]={ + "value", +}; +static const char * const MatchSingleton_fields[]={ + "value", +}; +static const char * const MatchSequence_fields[]={ + "patterns", +}; +static const char * const MatchMapping_fields[]={ + "keys", + "patterns", + "rest", +}; +static const char * const MatchClass_fields[]={ + "cls", + "patterns", + "kwd_attrs", + "kwd_patterns", +}; +static const char * const MatchStar_fields[]={ + "name", +}; +static const char * const MatchAs_fields[]={ + "pattern", + "name", +}; +static const char * const MatchOr_fields[]={ + "patterns", +}; +static PyObject* ast2obj_type_ignore(struct ast_state *state, void*); static const char * const TypeIgnore_fields[]={ "lineno", "tag", @@ -911,7 +786,7 @@ ast_clear(AST_object *self) static int ast_type_init(PyObject *self, PyObject *args, PyObject *kw) { - astmodulestate *state = get_global_ast_state(); + struct ast_state *state = get_ast_state(); if (state == NULL) { return -1; } @@ -987,7 +862,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw) static PyObject * ast_type_reduce(PyObject *self, PyObject *unused) { - astmodulestate *state = get_global_ast_state(); + struct ast_state *state = get_ast_state(); if (state == NULL) { return NULL; } @@ -1042,7 +917,7 @@ static PyType_Spec AST_type_spec = { }; static PyObject * -make_type(astmodulestate *state, const char *type, PyObject* base, +make_type(struct ast_state *state, const char *type, PyObject* base, const char* const* fields, int num_fields, const char *doc) { PyObject *fnames, *result; @@ -1057,9 +932,10 @@ make_type(astmodulestate *state, const char *type, PyObject* base, } PyTuple_SET_ITEM(fnames, i, field); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOs}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOOOs}", type, base, state->_fields, fnames, + state->__match_args__, fnames, state->__module__, state->ast, state->__doc__, doc); @@ -1068,7 +944,7 @@ make_type(astmodulestate *state, const char *type, PyObject* base, } static int -add_attributes(astmodulestate *state, PyObject *type, const char * const *attrs, int num_fields) +add_attributes(struct ast_state *state, PyObject *type, const char * const *attrs, int num_fields) { int i, result; PyObject *s, *l = PyTuple_New(num_fields); @@ -1089,7 +965,7 @@ add_attributes(astmodulestate *state, PyObject *type, const char * const *attrs, /* Conversion AST -> Python */ -static PyObject* ast2obj_list(astmodulestate *state, asdl_seq *seq, PyObject* (*func)(astmodulestate *state, void*)) +static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, PyObject* (*func)(struct ast_state *state, void*)) { Py_ssize_t i, n = asdl_seq_LEN(seq); PyObject *result = PyList_New(n); @@ -1097,7 +973,7 @@ static PyObject* ast2obj_list(astmodulestate *state, asdl_seq *seq, PyObject* (* if (!result) return NULL; for (i = 0; i < n; i++) { - value = func(state, asdl_seq_GET(seq, i)); + value = func(state, asdl_seq_GET_UNTYPED(seq, i)); if (!value) { Py_DECREF(result); return NULL; @@ -1107,7 +983,7 @@ static PyObject* ast2obj_list(astmodulestate *state, asdl_seq *seq, PyObject* (* return result; } -static PyObject* ast2obj_object(astmodulestate *Py_UNUSED(state), void *o) +static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { if (!o) o = Py_None; @@ -1118,19 +994,19 @@ static PyObject* ast2obj_object(astmodulestate *Py_UNUSED(state), void *o) #define ast2obj_identifier ast2obj_object #define ast2obj_string ast2obj_object -static PyObject* ast2obj_int(astmodulestate *Py_UNUSED(state), long b) +static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), long b) { return PyLong_FromLong(b); } /* Conversion Python -> AST */ -static int obj2ast_object(astmodulestate *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) +static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) { if (obj == Py_None) obj = NULL; if (obj) { - if (PyArena_AddPyObject(arena, obj) < 0) { + if (_PyArena_AddPyObject(arena, obj) < 0) { *out = NULL; return -1; } @@ -1140,9 +1016,9 @@ static int obj2ast_object(astmodulestate *Py_UNUSED(state), PyObject* obj, PyObj return 0; } -static int obj2ast_constant(astmodulestate *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) +static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) { - if (PyArena_AddPyObject(arena, obj) < 0) { + if (_PyArena_AddPyObject(arena, obj) < 0) { *out = NULL; return -1; } @@ -1151,7 +1027,7 @@ static int obj2ast_constant(astmodulestate *Py_UNUSED(state), PyObject* obj, PyO return 0; } -static int obj2ast_identifier(astmodulestate *state, PyObject* obj, PyObject** out, PyArena* arena) +static int obj2ast_identifier(struct ast_state *state, PyObject* obj, PyObject** out, PyArena* arena) { if (!PyUnicode_CheckExact(obj) && obj != Py_None) { PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str"); @@ -1160,7 +1036,7 @@ static int obj2ast_identifier(astmodulestate *state, PyObject* obj, PyObject** o return obj2ast_object(state, obj, out, arena); } -static int obj2ast_string(astmodulestate *state, PyObject* obj, PyObject** out, PyArena* arena) +static int obj2ast_string(struct ast_state *state, PyObject* obj, PyObject** out, PyArena* arena) { if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) { PyErr_SetString(PyExc_TypeError, "AST string must be of type str"); @@ -1169,7 +1045,7 @@ static int obj2ast_string(astmodulestate *state, PyObject* obj, PyObject** out, return obj2ast_object(state, obj, out, arena); } -static int obj2ast_int(astmodulestate* Py_UNUSED(state), PyObject* obj, int* out, PyArena* arena) +static int obj2ast_int(struct ast_state* Py_UNUSED(state), PyObject* obj, int* out, PyArena* arena) { int i; if (!PyLong_Check(obj)) { @@ -1184,12 +1060,13 @@ static int obj2ast_int(astmodulestate* Py_UNUSED(state), PyObject* obj, int* out return 0; } -static int add_ast_fields(astmodulestate *state) +static int add_ast_fields(struct ast_state *state) { PyObject *empty_tuple; empty_tuple = PyTuple_New(0); if (!empty_tuple || PyObject_SetAttrString(state->AST_type, "_fields", empty_tuple) < 0 || + PyObject_SetAttrString(state->AST_type, "__match_args__", empty_tuple) < 0 || PyObject_SetAttrString(state->AST_type, "_attributes", empty_tuple) < 0) { Py_XDECREF(empty_tuple); return -1; @@ -1199,13 +1076,27 @@ static int add_ast_fields(astmodulestate *state) } -static int init_types(astmodulestate *state) + +static int +init_types(struct ast_state *state) { - if (state->initialized) return 1; - if (init_identifiers(state) < 0) return 0; + // init_types() must not be called after _PyAST_Fini() + // has been called + assert(state->initialized >= 0); + + if (state->initialized) { + return 1; + } + if (init_identifiers(state) < 0) { + return 0; + } state->AST_type = PyType_FromSpec(&AST_type_spec); - if (!state->AST_type) return 0; - if (add_ast_fields(state) < 0) return 0; + if (!state->AST_type) { + return 0; + } + if (add_ast_fields(state) < 0) { + return 0; + } state->mod_type = make_type(state, "mod", state->AST_type, NULL, 0, "mod = Module(stmt* body, type_ignore* type_ignores)\n" " | Interactive(stmt* body)\n" @@ -1245,6 +1136,7 @@ static int init_types(astmodulestate *state) " | If(expr test, stmt* body, stmt* orelse)\n" " | With(withitem* items, stmt* body, string? type_comment)\n" " | AsyncWith(withitem* items, stmt* body, string? type_comment)\n" + " | Match(expr subject, match_case* cases)\n" " | Raise(expr? exc, expr? cause)\n" " | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" " | Assert(expr test, expr? msg)\n" @@ -1347,6 +1239,10 @@ static int init_types(astmodulestate *state) if (PyObject_SetAttr(state->AsyncWith_type, state->type_comment, Py_None) == -1) return 0; + state->Match_type = make_type(state, "Match", state->stmt_type, + Match_fields, 2, + "Match(expr subject, match_case* cases)"); + if (!state->Match_type) return 0; state->Raise_type = make_type(state, "Raise", state->stmt_type, Raise_fields, 2, "Raise(expr? exc, expr? cause)"); @@ -1416,7 +1312,7 @@ static int init_types(astmodulestate *state) " | YieldFrom(expr value)\n" " | Compare(expr left, cmpop* ops, expr* comparators)\n" " | Call(expr func, expr* args, keyword* keywords)\n" - " | FormattedValue(expr value, int? conversion, expr? format_spec)\n" + " | FormattedValue(expr value, int conversion, expr? format_spec)\n" " | JoinedStr(expr* values)\n" " | Constant(constant value, string? kind)\n" " | Attribute(expr value, identifier attr, expr_context ctx)\n" @@ -1506,11 +1402,8 @@ static int init_types(astmodulestate *state) state->FormattedValue_type = make_type(state, "FormattedValue", state->expr_type, FormattedValue_fields, 3, - "FormattedValue(expr value, int? conversion, expr? format_spec)"); + "FormattedValue(expr value, int conversion, expr? format_spec)"); if (!state->FormattedValue_type) return 0; - if (PyObject_SetAttr(state->FormattedValue_type, state->conversion, - Py_None) == -1) - return 0; if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec, Py_None) == -1) return 0; @@ -1853,9 +1746,15 @@ static int init_types(astmodulestate *state) alias_fields, 2, "alias(identifier name, identifier? asname)"); if (!state->alias_type) return 0; - if (!add_attributes(state, state->alias_type, NULL, 0)) return 0; + if (!add_attributes(state, state->alias_type, alias_attributes, 4)) return + 0; if (PyObject_SetAttr(state->alias_type, state->asname, Py_None) == -1) return 0; + if (PyObject_SetAttr(state->alias_type, state->end_lineno, Py_None) == -1) + return 0; + if (PyObject_SetAttr(state->alias_type, state->end_col_offset, Py_None) == + -1) + return 0; state->withitem_type = make_type(state, "withitem", state->AST_type, withitem_fields, 2, "withitem(expr context_expr, expr? optional_vars)"); @@ -1864,6 +1763,70 @@ static int init_types(astmodulestate *state) if (PyObject_SetAttr(state->withitem_type, state->optional_vars, Py_None) == -1) return 0; + state->match_case_type = make_type(state, "match_case", state->AST_type, + match_case_fields, 3, + "match_case(pattern pattern, expr? guard, stmt* body)"); + if (!state->match_case_type) return 0; + if (!add_attributes(state, state->match_case_type, NULL, 0)) return 0; + if (PyObject_SetAttr(state->match_case_type, state->guard, Py_None) == -1) + return 0; + state->pattern_type = make_type(state, "pattern", state->AST_type, NULL, 0, + "pattern = MatchValue(expr value)\n" + " | MatchSingleton(constant value)\n" + " | MatchSequence(pattern* patterns)\n" + " | MatchMapping(expr* keys, pattern* patterns, identifier? rest)\n" + " | MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)\n" + " | MatchStar(identifier? name)\n" + " | MatchAs(pattern? pattern, identifier? name)\n" + " | MatchOr(pattern* patterns)"); + if (!state->pattern_type) return 0; + if (!add_attributes(state, state->pattern_type, pattern_attributes, 4)) + return 0; + state->MatchValue_type = make_type(state, "MatchValue", + state->pattern_type, MatchValue_fields, + 1, + "MatchValue(expr value)"); + if (!state->MatchValue_type) return 0; + state->MatchSingleton_type = make_type(state, "MatchSingleton", + state->pattern_type, + MatchSingleton_fields, 1, + "MatchSingleton(constant value)"); + if (!state->MatchSingleton_type) return 0; + state->MatchSequence_type = make_type(state, "MatchSequence", + state->pattern_type, + MatchSequence_fields, 1, + "MatchSequence(pattern* patterns)"); + if (!state->MatchSequence_type) return 0; + state->MatchMapping_type = make_type(state, "MatchMapping", + state->pattern_type, + MatchMapping_fields, 3, + "MatchMapping(expr* keys, pattern* patterns, identifier? rest)"); + if (!state->MatchMapping_type) return 0; + if (PyObject_SetAttr(state->MatchMapping_type, state->rest, Py_None) == -1) + return 0; + state->MatchClass_type = make_type(state, "MatchClass", + state->pattern_type, MatchClass_fields, + 4, + "MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)"); + if (!state->MatchClass_type) return 0; + state->MatchStar_type = make_type(state, "MatchStar", state->pattern_type, + MatchStar_fields, 1, + "MatchStar(identifier? name)"); + if (!state->MatchStar_type) return 0; + if (PyObject_SetAttr(state->MatchStar_type, state->name, Py_None) == -1) + return 0; + state->MatchAs_type = make_type(state, "MatchAs", state->pattern_type, + MatchAs_fields, 2, + "MatchAs(pattern? pattern, identifier? name)"); + if (!state->MatchAs_type) return 0; + if (PyObject_SetAttr(state->MatchAs_type, state->pattern, Py_None) == -1) + return 0; + if (PyObject_SetAttr(state->MatchAs_type, state->name, Py_None) == -1) + return 0; + state->MatchOr_type = make_type(state, "MatchOr", state->pattern_type, + MatchOr_fields, 1, + "MatchOr(pattern* patterns)"); + if (!state->MatchOr_type) return 0; state->type_ignore_type = make_type(state, "type_ignore", state->AST_type, NULL, 0, "type_ignore = TypeIgnore(int lineno, string tag)"); @@ -1874,48 +1837,54 @@ static int init_types(astmodulestate *state) TypeIgnore_fields, 2, "TypeIgnore(int lineno, string tag)"); if (!state->TypeIgnore_type) return 0; + state->initialized = 1; return 1; } -static int obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, +static int obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena); -static int obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, +static int obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* arena); -static int obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, +static int obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* arena); -static int obj2ast_expr_context(astmodulestate *state, PyObject* obj, +static int obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty* out, PyArena* arena); -static int obj2ast_boolop(astmodulestate *state, PyObject* obj, boolop_ty* out, - PyArena* arena); -static int obj2ast_operator(astmodulestate *state, PyObject* obj, operator_ty* - out, PyArena* arena); -static int obj2ast_unaryop(astmodulestate *state, PyObject* obj, unaryop_ty* +static int obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* + out, PyArena* arena); +static int obj2ast_operator(struct ast_state *state, PyObject* obj, + operator_ty* out, PyArena* arena); +static int obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, PyArena* arena); -static int obj2ast_cmpop(astmodulestate *state, PyObject* obj, cmpop_ty* out, +static int obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* arena); -static int obj2ast_comprehension(astmodulestate *state, PyObject* obj, +static int obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* out, PyArena* arena); -static int obj2ast_excepthandler(astmodulestate *state, PyObject* obj, +static int obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* out, PyArena* arena); -static int obj2ast_arguments(astmodulestate *state, PyObject* obj, +static int obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, PyArena* arena); -static int obj2ast_arg(astmodulestate *state, PyObject* obj, arg_ty* out, +static int obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena); -static int obj2ast_keyword(astmodulestate *state, PyObject* obj, keyword_ty* +static int obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, PyArena* arena); -static int obj2ast_alias(astmodulestate *state, PyObject* obj, alias_ty* out, +static int obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* arena); -static int obj2ast_withitem(astmodulestate *state, PyObject* obj, withitem_ty* - out, PyArena* arena); -static int obj2ast_type_ignore(astmodulestate *state, PyObject* obj, +static int obj2ast_withitem(struct ast_state *state, PyObject* obj, + withitem_ty* out, PyArena* arena); +static int obj2ast_match_case(struct ast_state *state, PyObject* obj, + match_case_ty* out, PyArena* arena); +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); mod_ty -Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena) +_PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, + PyArena *arena) { mod_ty p; - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Module_kind; @@ -1925,10 +1894,10 @@ Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena) } mod_ty -Interactive(asdl_seq * body, PyArena *arena) +_PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena) { mod_ty p; - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Interactive_kind; @@ -1937,7 +1906,7 @@ Interactive(asdl_seq * body, PyArena *arena) } mod_ty -Expression(expr_ty body, PyArena *arena) +_PyAST_Expression(expr_ty body, PyArena *arena) { mod_ty p; if (!body) { @@ -1945,7 +1914,7 @@ Expression(expr_ty body, PyArena *arena) "field 'body' is required for Expression"); return NULL; } - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Expression_kind; @@ -1954,7 +1923,7 @@ Expression(expr_ty body, PyArena *arena) } mod_ty -FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena) +_PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena) { mod_ty p; if (!returns) { @@ -1962,7 +1931,7 @@ FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena) "field 'returns' is required for FunctionType"); return NULL; } - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = FunctionType_kind; @@ -1972,9 +1941,10 @@ FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena) } stmt_ty -FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * - decorator_list, expr_ty returns, string type_comment, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_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) { stmt_ty p; if (!name) { @@ -1987,7 +1957,7 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * "field 'args' is required for FunctionDef"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = FunctionDef_kind; @@ -2005,10 +1975,10 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * } stmt_ty -AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq - * decorator_list, expr_ty returns, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) +_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) { stmt_ty p; if (!name) { @@ -2021,7 +1991,7 @@ AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq "field 'args' is required for AsyncFunctionDef"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AsyncFunctionDef_kind; @@ -2039,9 +2009,10 @@ AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq } stmt_ty -ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq * - body, asdl_seq * decorator_list, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_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) { stmt_ty p; if (!name) { @@ -2049,7 +2020,7 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq * "field 'name' is required for ClassDef"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ClassDef_kind; @@ -2066,11 +2037,11 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq * } stmt_ty -Return(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Return(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Return_kind; @@ -2083,11 +2054,11 @@ Return(expr_ty value, int lineno, int col_offset, int end_lineno, int } stmt_ty -Delete(asdl_seq * targets, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Delete_kind; @@ -2100,8 +2071,9 @@ Delete(asdl_seq * targets, int lineno, int col_offset, int end_lineno, int } stmt_ty -Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_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 p; if (!value) { @@ -2109,7 +2081,7 @@ Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int "field 'value' is required for Assign"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Assign_kind; @@ -2124,8 +2096,8 @@ Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int } stmt_ty -AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_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) { stmt_ty p; if (!target) { @@ -2143,7 +2115,7 @@ AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int "field 'value' is required for AugAssign"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AugAssign_kind; @@ -2158,9 +2130,9 @@ AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int } stmt_ty -AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int - lineno, int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) +_PyAST_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; if (!target) { @@ -2173,7 +2145,7 @@ AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int "field 'annotation' is required for AnnAssign"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AnnAssign_kind; @@ -2189,9 +2161,9 @@ AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int } stmt_ty -For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string - type_comment, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, asdl_stmt_seq * + orelse, string type_comment, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!target) { @@ -2204,7 +2176,7 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string "field 'iter' is required for For"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = For_kind; @@ -2221,9 +2193,9 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string } stmt_ty -AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, - string type_comment, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, + asdl_stmt_seq * orelse, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!target) { @@ -2236,7 +2208,7 @@ AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, "field 'iter' is required for AsyncFor"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AsyncFor_kind; @@ -2253,8 +2225,9 @@ AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, } stmt_ty -While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { stmt_ty p; if (!test) { @@ -2262,7 +2235,7 @@ While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int "field 'test' is required for While"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = While_kind; @@ -2277,8 +2250,9 @@ While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int } stmt_ty -If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int + lineno, int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { stmt_ty p; if (!test) { @@ -2286,7 +2260,7 @@ If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int "field 'test' is required for If"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = If_kind; @@ -2301,11 +2275,12 @@ If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int } stmt_ty -With(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string + type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = With_kind; @@ -2320,11 +2295,12 @@ With(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, int } stmt_ty -AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string + type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AsyncWith_kind; @@ -2339,11 +2315,34 @@ AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, } stmt_ty -Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) +_PyAST_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!subject) { + PyErr_SetString(PyExc_ValueError, + "field 'subject' is required for Match"); + return NULL; + } + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Match_kind; + p->v.Match.subject = subject; + p->v.Match.cases = cases; + 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_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Raise_kind; @@ -2357,12 +2356,12 @@ Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno, } stmt_ty -Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq * - finalbody, int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) +_PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, + asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Try_kind; @@ -2378,8 +2377,8 @@ Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq * } stmt_ty -Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) +_PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!test) { @@ -2387,7 +2386,7 @@ Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, "field 'test' is required for Assert"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Assert_kind; @@ -2401,11 +2400,11 @@ Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, } stmt_ty -Import(asdl_seq * names, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Import_kind; @@ -2418,11 +2417,12 @@ Import(asdl_seq * names, int lineno, int col_offset, int end_lineno, int } stmt_ty -ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ImportFrom_kind; @@ -2437,11 +2437,11 @@ ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int } stmt_ty -Global(asdl_seq * names, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Global_kind; @@ -2454,11 +2454,11 @@ Global(asdl_seq * names, int lineno, int col_offset, int end_lineno, int } stmt_ty -Nonlocal(asdl_seq * names, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Nonlocal_kind; @@ -2471,8 +2471,8 @@ Nonlocal(asdl_seq * names, int lineno, int col_offset, int end_lineno, int } stmt_ty -Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; if (!value) { @@ -2480,7 +2480,7 @@ Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int "field 'value' is required for Expr"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Expr_kind; @@ -2493,11 +2493,11 @@ Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int } stmt_ty -Pass(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) +_PyAST_Pass(int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Pass_kind; @@ -2509,11 +2509,11 @@ Pass(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena } stmt_ty -Break(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) +_PyAST_Break(int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Break_kind; @@ -2525,11 +2525,11 @@ Break(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena } stmt_ty -Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) +_PyAST_Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Continue_kind; @@ -2541,8 +2541,8 @@ Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, } expr_ty -BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!op) { @@ -2550,7 +2550,7 @@ BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int "field 'op' is required for BoolOp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = BoolOp_kind; @@ -2564,8 +2564,8 @@ BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int } expr_ty -NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!target) { @@ -2578,7 +2578,7 @@ NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int "field 'value' is required for NamedExpr"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = NamedExpr_kind; @@ -2592,8 +2592,8 @@ NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int } expr_ty -BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!left) { @@ -2611,7 +2611,7 @@ BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset, "field 'right' is required for BinOp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = BinOp_kind; @@ -2626,8 +2626,8 @@ BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset, } expr_ty -UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!op) { @@ -2640,7 +2640,7 @@ UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int "field 'operand' is required for UnaryOp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = UnaryOp_kind; @@ -2654,8 +2654,8 @@ UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int } expr_ty -Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!args) { @@ -2668,7 +2668,7 @@ Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int "field 'body' is required for Lambda"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Lambda_kind; @@ -2682,8 +2682,8 @@ Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int } expr_ty -IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!test) { @@ -2701,7 +2701,7 @@ IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset, "field 'orelse' is required for IfExp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = IfExp_kind; @@ -2716,11 +2716,11 @@ IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset, } expr_ty -Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Dict_kind; @@ -2734,11 +2734,11 @@ Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, int } expr_ty -Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Set(asdl_expr_seq * elts, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Set_kind; @@ -2751,8 +2751,9 @@ Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, int } expr_ty -ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { expr_ty p; if (!elt) { @@ -2760,7 +2761,7 @@ ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int "field 'elt' is required for ListComp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ListComp_kind; @@ -2774,8 +2775,9 @@ ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int } expr_ty -SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { expr_ty p; if (!elt) { @@ -2783,7 +2785,7 @@ SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int "field 'elt' is required for SetComp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = SetComp_kind; @@ -2797,8 +2799,9 @@ SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int } expr_ty -DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * + generators, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { expr_ty p; if (!key) { @@ -2811,7 +2814,7 @@ DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int "field 'value' is required for DictComp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = DictComp_kind; @@ -2826,8 +2829,9 @@ DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int } expr_ty -GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { expr_ty p; if (!elt) { @@ -2835,7 +2839,7 @@ GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, "field 'elt' is required for GeneratorExp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = GeneratorExp_kind; @@ -2849,8 +2853,8 @@ GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, } expr_ty -Await(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Await(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { expr_ty p; if (!value) { @@ -2858,7 +2862,7 @@ Await(expr_ty value, int lineno, int col_offset, int end_lineno, int "field 'value' is required for Await"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Await_kind; @@ -2871,11 +2875,11 @@ Await(expr_ty value, int lineno, int col_offset, int end_lineno, int } expr_ty -Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Yield_kind; @@ -2888,8 +2892,8 @@ Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int } expr_ty -YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { expr_ty p; if (!value) { @@ -2897,7 +2901,7 @@ YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int "field 'value' is required for YieldFrom"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = YieldFrom_kind; @@ -2910,8 +2914,9 @@ YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int } expr_ty -Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * comparators, + int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { expr_ty p; if (!left) { @@ -2919,7 +2924,7 @@ Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, "field 'left' is required for Compare"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Compare_kind; @@ -2934,8 +2939,9 @@ Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, } expr_ty -Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * keywords, + int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { expr_ty p; if (!func) { @@ -2943,7 +2949,7 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int "field 'func' is required for Call"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Call_kind; @@ -2958,9 +2964,9 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int } expr_ty -FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) +_PyAST_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { expr_ty p; if (!value) { @@ -2968,7 +2974,7 @@ FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, "field 'value' is required for FormattedValue"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = FormattedValue_kind; @@ -2983,11 +2989,11 @@ FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, } expr_ty -JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +_PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = JoinedStr_kind; @@ -3000,8 +3006,8 @@ JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int } expr_ty -Constant(constant value, string kind, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Constant(constant value, string kind, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!value) { @@ -3009,7 +3015,7 @@ Constant(constant value, string kind, int lineno, int col_offset, int "field 'value' is required for Constant"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Constant_kind; @@ -3023,8 +3029,9 @@ Constant(constant value, string kind, int lineno, int col_offset, int } expr_ty -Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { expr_ty p; if (!value) { @@ -3042,7 +3049,7 @@ Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int "field 'ctx' is required for Attribute"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Attribute_kind; @@ -3057,8 +3064,9 @@ Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int } expr_ty -Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { expr_ty p; if (!value) { @@ -3076,7 +3084,7 @@ Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int "field 'ctx' is required for Subscript"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Subscript_kind; @@ -3091,8 +3099,8 @@ Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int } expr_ty -Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!value) { @@ -3105,7 +3113,7 @@ Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, int "field 'ctx' is required for Starred"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Starred_kind; @@ -3119,8 +3127,8 @@ Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, int } expr_ty -Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!id) { @@ -3133,7 +3141,7 @@ Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int "field 'ctx' is required for Name"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Name_kind; @@ -3147,8 +3155,8 @@ Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int } expr_ty -List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!ctx) { @@ -3156,7 +3164,7 @@ List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int "field 'ctx' is required for List"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = List_kind; @@ -3170,8 +3178,8 @@ List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int } expr_ty -Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!ctx) { @@ -3179,7 +3187,7 @@ Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int "field 'ctx' is required for Tuple"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Tuple_kind; @@ -3193,11 +3201,11 @@ Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int } expr_ty -Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Slice_kind; @@ -3212,8 +3220,8 @@ Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset, } comprehension_ty -comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async, - PyArena *arena) +_PyAST_comprehension(expr_ty target, expr_ty iter, asdl_expr_seq * ifs, int + is_async, PyArena *arena) { comprehension_ty p; if (!target) { @@ -3226,7 +3234,7 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async, "field 'iter' is required for comprehension"); return NULL; } - p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (comprehension_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->target = target; @@ -3237,11 +3245,12 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async, } excepthandler_ty -ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_ExceptHandler(expr_ty type, identifier name, asdl_stmt_seq * body, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { excepthandler_ty p; - p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (excepthandler_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ExceptHandler_kind; @@ -3256,12 +3265,13 @@ ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int } arguments_ty -arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty vararg, asdl_seq * - kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq * - defaults, PyArena *arena) +_PyAST_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, arg_ty + vararg, asdl_arg_seq * kwonlyargs, asdl_expr_seq * + kw_defaults, arg_ty kwarg, asdl_expr_seq * defaults, PyArena + *arena) { arguments_ty p; - p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (arguments_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->posonlyargs = posonlyargs; @@ -3275,8 +3285,8 @@ arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty vararg, asdl_seq * } arg_ty -arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +_PyAST_arg(identifier arg, expr_ty annotation, string type_comment, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { arg_ty p; if (!arg) { @@ -3284,7 +3294,7 @@ arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int "field 'arg' is required for arg"); return NULL; } - p = (arg_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (arg_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->arg = arg; @@ -3298,8 +3308,8 @@ arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int } keyword_ty -keyword(identifier arg, expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_keyword(identifier arg, expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { keyword_ty p; if (!value) { @@ -3307,7 +3317,7 @@ keyword(identifier arg, expr_ty value, int lineno, int col_offset, int "field 'value' is required for keyword"); return NULL; } - p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (keyword_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->arg = arg; @@ -3320,7 +3330,8 @@ keyword(identifier arg, expr_ty value, int lineno, int col_offset, int } alias_ty -alias(identifier name, identifier asname, PyArena *arena) +_PyAST_alias(identifier name, identifier asname, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { alias_ty p; if (!name) { @@ -3328,16 +3339,20 @@ alias(identifier name, identifier asname, PyArena *arena) "field 'name' is required for alias"); return NULL; } - p = (alias_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (alias_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->name = name; p->asname = asname; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; return p; } withitem_ty -withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) +_PyAST_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) { withitem_ty p; if (!context_expr) { @@ -3345,7 +3360,7 @@ withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) "field 'context_expr' is required for withitem"); return NULL; } - p = (withitem_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (withitem_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->context_expr = context_expr; @@ -3353,8 +3368,187 @@ withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) return p; } +match_case_ty +_PyAST_match_case(pattern_ty pattern, expr_ty guard, asdl_stmt_seq * body, + PyArena *arena) +{ + match_case_ty p; + if (!pattern) { + PyErr_SetString(PyExc_ValueError, + "field 'pattern' is required for match_case"); + return NULL; + } + p = (match_case_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->pattern = pattern; + p->guard = guard; + p->body = body; + return p; +} + +pattern_ty +_PyAST_MatchValue(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) +{ + pattern_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field 'value' is required for MatchValue"); + return NULL; + } + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchValue_kind; + p->v.MatchValue.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +pattern_ty +_PyAST_MatchSingleton(constant value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + pattern_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field 'value' is required for MatchSingleton"); + return NULL; + } + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchSingleton_kind; + p->v.MatchSingleton.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +pattern_ty +_PyAST_MatchSequence(asdl_pattern_seq * patterns, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) +{ + pattern_ty p; + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchSequence_kind; + p->v.MatchSequence.patterns = patterns; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +pattern_ty +_PyAST_MatchMapping(asdl_expr_seq * keys, asdl_pattern_seq * patterns, + identifier rest, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + pattern_ty p; + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchMapping_kind; + p->v.MatchMapping.keys = keys; + p->v.MatchMapping.patterns = patterns; + p->v.MatchMapping.rest = rest; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +pattern_ty +_PyAST_MatchClass(expr_ty cls, asdl_pattern_seq * patterns, asdl_identifier_seq + * kwd_attrs, asdl_pattern_seq * kwd_patterns, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena) +{ + pattern_ty p; + if (!cls) { + PyErr_SetString(PyExc_ValueError, + "field 'cls' is required for MatchClass"); + return NULL; + } + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchClass_kind; + p->v.MatchClass.cls = cls; + p->v.MatchClass.patterns = patterns; + p->v.MatchClass.kwd_attrs = kwd_attrs; + p->v.MatchClass.kwd_patterns = kwd_patterns; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +pattern_ty +_PyAST_MatchStar(identifier name, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) +{ + pattern_ty p; + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchStar_kind; + p->v.MatchStar.name = name; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +pattern_ty +_PyAST_MatchAs(pattern_ty pattern, identifier name, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) +{ + pattern_ty p; + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchAs_kind; + p->v.MatchAs.pattern = pattern; + p->v.MatchAs.name = name; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +pattern_ty +_PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + pattern_ty p; + p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = MatchOr_kind; + p->v.MatchOr.patterns = patterns; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + type_ignore_ty -TypeIgnore(int lineno, string tag, PyArena *arena) +_PyAST_TypeIgnore(int lineno, string tag, PyArena *arena) { type_ignore_ty p; if (!tag) { @@ -3362,7 +3556,7 @@ TypeIgnore(int lineno, string tag, PyArena *arena) "field 'tag' is required for TypeIgnore"); return NULL; } - p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (type_ignore_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = TypeIgnore_kind; @@ -3373,7 +3567,7 @@ TypeIgnore(int lineno, string tag, PyArena *arena) PyObject* -ast2obj_mod(astmodulestate *state, void* _o) +ast2obj_mod(struct ast_state *state, void* _o) { mod_ty o = (mod_ty)_o; PyObject *result = NULL, *value = NULL; @@ -3386,12 +3580,12 @@ ast2obj_mod(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Module_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Module.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Module.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Module.type_ignores, + value = ast2obj_list(state, (asdl_seq*)o->v.Module.type_ignores, ast2obj_type_ignore); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_ignores, value) == -1) @@ -3402,7 +3596,8 @@ ast2obj_mod(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Interactive_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Interactive.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Interactive.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -3422,7 +3617,8 @@ ast2obj_mod(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->FunctionType_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.FunctionType.argtypes, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionType.argtypes, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->argtypes, value) == -1) goto failed; @@ -3442,7 +3638,7 @@ failed: } PyObject* -ast2obj_stmt(astmodulestate *state, void* _o) +ast2obj_stmt(struct ast_state *state, void* _o) { stmt_ty o = (stmt_ty)_o; PyObject *result = NULL, *value = NULL; @@ -3465,12 +3661,13 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.FunctionDef.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.FunctionDef.decorator_list, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) @@ -3501,12 +3698,14 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFunctionDef.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFunctionDef.decorator_list, + value = ast2obj_list(state, + (asdl_seq*)o->v.AsyncFunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) @@ -3532,22 +3731,26 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.bases, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.bases, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->bases, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.keywords, ast2obj_keyword); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.keywords, + ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.decorator_list, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.decorator_list, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; @@ -3567,7 +3770,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Delete_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Delete.targets, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Delete.targets, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) goto failed; @@ -3577,7 +3781,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Assign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Assign.targets, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Assign.targets, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) goto failed; @@ -3652,12 +3857,12 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.For.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.For.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3682,12 +3887,14 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFor.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFor.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.orelse, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3707,12 +3914,12 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.While.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.While.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3727,12 +3934,12 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.If.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.If.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3742,12 +3949,13 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->With_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.With.items, ast2obj_withitem); + value = ast2obj_list(state, (asdl_seq*)o->v.With.items, + ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.With.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.With.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -3762,12 +3970,14 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->AsyncWith_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.AsyncWith.items, ast2obj_withitem); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.items, + ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncWith.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -3778,6 +3988,22 @@ ast2obj_stmt(astmodulestate *state, void* _o) goto failed; Py_DECREF(value); break; + case Match_kind: + tp = (PyTypeObject *)state->Match_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(state, o->v.Match.subject); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->subject, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.Match.cases, + ast2obj_match_case); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->cases, value) == -1) + goto failed; + Py_DECREF(value); + break; case Raise_kind: tp = (PyTypeObject *)state->Raise_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -3797,22 +4023,24 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Try_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Try.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Try.handlers, ast2obj_excepthandler); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.handlers, + ast2obj_excepthandler); if (!value) goto failed; if (PyObject_SetAttr(result, state->handlers, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Try.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Try.finalbody, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.finalbody, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->finalbody, value) == -1) goto failed; @@ -3837,7 +4065,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Import_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Import.names, ast2obj_alias); + value = ast2obj_list(state, (asdl_seq*)o->v.Import.names, + ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3852,7 +4081,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->module, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ImportFrom.names, ast2obj_alias); + value = ast2obj_list(state, (asdl_seq*)o->v.ImportFrom.names, + ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3867,7 +4097,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Global_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Global.names, ast2obj_identifier); + value = ast2obj_list(state, (asdl_seq*)o->v.Global.names, + ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3877,7 +4108,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Nonlocal_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Nonlocal.names, ast2obj_identifier); + value = ast2obj_list(state, (asdl_seq*)o->v.Nonlocal.names, + ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3937,7 +4169,7 @@ failed: } PyObject* -ast2obj_expr(astmodulestate *state, void* _o) +ast2obj_expr(struct ast_state *state, void* _o) { expr_ty o = (expr_ty)_o; PyObject *result = NULL, *value = NULL; @@ -3955,7 +4187,8 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.BoolOp.values, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.BoolOp.values, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -4050,12 +4283,12 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Dict_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Dict.keys, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.keys, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->keys, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Dict.values, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -4065,7 +4298,7 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Set_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Set.elts, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Set.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -4080,7 +4313,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ListComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.ListComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4096,7 +4329,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.SetComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.SetComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4117,7 +4350,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.DictComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.DictComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4133,7 +4366,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.GeneratorExp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.GeneratorExp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4190,7 +4423,8 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->ops, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Compare.comparators, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Compare.comparators, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->comparators, value) == -1) goto failed; @@ -4205,12 +4439,13 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->func, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Call.args, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Call.args, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Call.keywords, ast2obj_keyword); + value = ast2obj_list(state, (asdl_seq*)o->v.Call.keywords, + ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) goto failed; @@ -4240,7 +4475,8 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->JoinedStr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.JoinedStr.values, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.JoinedStr.values, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -4335,7 +4571,7 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->List_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.List.elts, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.List.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -4350,7 +4586,7 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Tuple_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Tuple.elts, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Tuple.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -4409,7 +4645,7 @@ failed: return NULL; } -PyObject* ast2obj_expr_context(astmodulestate *state, expr_context_ty o) +PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty o) { switch(o) { case Load: @@ -4424,7 +4660,7 @@ PyObject* ast2obj_expr_context(astmodulestate *state, expr_context_ty o) } Py_UNREACHABLE(); } -PyObject* ast2obj_boolop(astmodulestate *state, boolop_ty o) +PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty o) { switch(o) { case And: @@ -4436,7 +4672,7 @@ PyObject* ast2obj_boolop(astmodulestate *state, boolop_ty o) } Py_UNREACHABLE(); } -PyObject* ast2obj_operator(astmodulestate *state, operator_ty o) +PyObject* ast2obj_operator(struct ast_state *state, operator_ty o) { switch(o) { case Add: @@ -4481,7 +4717,7 @@ PyObject* ast2obj_operator(astmodulestate *state, operator_ty o) } Py_UNREACHABLE(); } -PyObject* ast2obj_unaryop(astmodulestate *state, unaryop_ty o) +PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty o) { switch(o) { case Invert: @@ -4499,7 +4735,7 @@ PyObject* ast2obj_unaryop(astmodulestate *state, unaryop_ty o) } Py_UNREACHABLE(); } -PyObject* ast2obj_cmpop(astmodulestate *state, cmpop_ty o) +PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty o) { switch(o) { case Eq: @@ -4536,7 +4772,7 @@ PyObject* ast2obj_cmpop(astmodulestate *state, cmpop_ty o) Py_UNREACHABLE(); } PyObject* -ast2obj_comprehension(astmodulestate *state, void* _o) +ast2obj_comprehension(struct ast_state *state, void* _o) { comprehension_ty o = (comprehension_ty)_o; PyObject *result = NULL, *value = NULL; @@ -4557,7 +4793,7 @@ ast2obj_comprehension(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->ifs, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->ifs, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->ifs, value) == -1) goto failed; @@ -4575,7 +4811,7 @@ failed: } PyObject* -ast2obj_excepthandler(astmodulestate *state, void* _o) +ast2obj_excepthandler(struct ast_state *state, void* _o) { excepthandler_ty o = (excepthandler_ty)_o; PyObject *result = NULL, *value = NULL; @@ -4598,7 +4834,8 @@ ast2obj_excepthandler(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ExceptHandler.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.ExceptHandler.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -4633,7 +4870,7 @@ failed: } PyObject* -ast2obj_arguments(astmodulestate *state, void* _o) +ast2obj_arguments(struct ast_state *state, void* _o) { arguments_ty o = (arguments_ty)_o; PyObject *result = NULL, *value = NULL; @@ -4644,12 +4881,12 @@ ast2obj_arguments(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->arguments_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_list(state, o->posonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->posonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->posonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->args, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->args, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; @@ -4659,12 +4896,12 @@ ast2obj_arguments(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->vararg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->kwonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->kwonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->kw_defaults, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->kw_defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->kw_defaults, value) == -1) goto failed; @@ -4674,7 +4911,7 @@ ast2obj_arguments(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->kwarg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->defaults, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->defaults, value) == -1) goto failed; @@ -4687,7 +4924,7 @@ failed: } PyObject* -ast2obj_arg(astmodulestate *state, void* _o) +ast2obj_arg(struct ast_state *state, void* _o) { arg_ty o = (arg_ty)_o; PyObject *result = NULL, *value = NULL; @@ -4741,7 +4978,7 @@ failed: } PyObject* -ast2obj_keyword(astmodulestate *state, void* _o) +ast2obj_keyword(struct ast_state *state, void* _o) { keyword_ty o = (keyword_ty)_o; PyObject *result = NULL, *value = NULL; @@ -4790,7 +5027,7 @@ failed: } PyObject* -ast2obj_alias(astmodulestate *state, void* _o) +ast2obj_alias(struct ast_state *state, void* _o) { alias_ty o = (alias_ty)_o; PyObject *result = NULL, *value = NULL; @@ -4811,6 +5048,26 @@ ast2obj_alias(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->asname, value) == -1) goto failed; Py_DECREF(value); + 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); return result; failed: Py_XDECREF(value); @@ -4819,7 +5076,7 @@ failed: } PyObject* -ast2obj_withitem(astmodulestate *state, void* _o) +ast2obj_withitem(struct ast_state *state, void* _o) { withitem_ty o = (withitem_ty)_o; PyObject *result = NULL, *value = NULL; @@ -4848,9 +5105,198 @@ failed: } PyObject* -ast2obj_type_ignore(astmodulestate *state, void* _o) +ast2obj_match_case(struct ast_state *state, void* _o) { - type_ignore_ty o = (type_ignore_ty)_o; + match_case_ty o = (match_case_ty)_o; + PyObject *result = NULL, *value = NULL; + PyTypeObject *tp; + if (!o) { + Py_RETURN_NONE; + } + tp = (PyTypeObject *)state->match_case_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) return NULL; + value = ast2obj_pattern(state, o->pattern); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->pattern, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(state, o->guard); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->guard, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->body, ast2obj_stmt); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->body, value) == -1) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_pattern(struct ast_state *state, void* _o) +{ + pattern_ty o = (pattern_ty)_o; + PyObject *result = NULL, *value = NULL; + PyTypeObject *tp; + if (!o) { + Py_RETURN_NONE; + } + switch (o->kind) { + case MatchValue_kind: + tp = (PyTypeObject *)state->MatchValue_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(state, o->v.MatchValue.value); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case MatchSingleton_kind: + tp = (PyTypeObject *)state->MatchSingleton_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_constant(state, o->v.MatchSingleton.value); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case MatchSequence_kind: + tp = (PyTypeObject *)state->MatchSequence_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(state, (asdl_seq*)o->v.MatchSequence.patterns, + ast2obj_pattern); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->patterns, value) == -1) + goto failed; + Py_DECREF(value); + break; + case MatchMapping_kind: + tp = (PyTypeObject *)state->MatchMapping_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.keys, + ast2obj_expr); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->keys, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.patterns, + ast2obj_pattern); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->patterns, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_identifier(state, o->v.MatchMapping.rest); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->rest, value) == -1) + goto failed; + Py_DECREF(value); + break; + case MatchClass_kind: + tp = (PyTypeObject *)state->MatchClass_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(state, o->v.MatchClass.cls); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->cls, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.patterns, + ast2obj_pattern); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->patterns, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_attrs, + ast2obj_identifier); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->kwd_attrs, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_patterns, + ast2obj_pattern); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->kwd_patterns, value) == -1) + goto failed; + Py_DECREF(value); + break; + case MatchStar_kind: + tp = (PyTypeObject *)state->MatchStar_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(state, o->v.MatchStar.name); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->name, value) == -1) + goto failed; + Py_DECREF(value); + break; + case MatchAs_kind: + tp = (PyTypeObject *)state->MatchAs_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_pattern(state, o->v.MatchAs.pattern); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->pattern, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_identifier(state, o->v.MatchAs.name); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->name, value) == -1) + goto failed; + Py_DECREF(value); + break; + case MatchOr_kind: + tp = (PyTypeObject *)state->MatchOr_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(state, (asdl_seq*)o->v.MatchOr.patterns, + ast2obj_pattern); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->patterns, 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); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_type_ignore(struct ast_state *state, void* _o) +{ + type_ignore_ty o = (type_ignore_ty)_o; PyObject *result = NULL, *value = NULL; PyTypeObject *tp; if (!o) { @@ -4882,7 +5328,7 @@ failed: int -obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) +obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) { int isinstance; @@ -4899,8 +5345,8 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* body; - asdl_seq* type_ignores; + asdl_stmt_seq* body; + asdl_type_ignore_seq* type_ignores; if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { return 1; @@ -4918,7 +5364,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -4955,7 +5401,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - type_ignores = _Py_asdl_seq_new(len, arena); + type_ignores = _Py_asdl_type_ignore_seq_new(len, arena); if (type_ignores == NULL) goto failed; for (i = 0; i < len; i++) { type_ignore_ty val; @@ -4976,7 +5422,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Module(body, type_ignores, arena); + *out = _PyAST_Module(body, type_ignores, arena); if (*out == NULL) goto failed; return 0; } @@ -4986,7 +5432,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* body; + asdl_stmt_seq* body; if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { return 1; @@ -5004,7 +5450,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5025,7 +5471,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Interactive(body, arena); + *out = _PyAST_Interactive(body, arena); if (*out == NULL) goto failed; return 0; } @@ -5054,7 +5500,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Expression(body, arena); + *out = _PyAST_Expression(body, arena); if (*out == NULL) goto failed; return 0; } @@ -5064,7 +5510,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* argtypes; + asdl_expr_seq* argtypes; expr_ty returns; if (_PyObject_LookupAttr(obj, state->argtypes, &tmp) < 0) { @@ -5083,7 +5529,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - argtypes = _Py_asdl_seq_new(len, arena); + argtypes = _Py_asdl_expr_seq_new(len, arena); if (argtypes == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5121,7 +5567,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = FunctionType(argtypes, returns, arena); + *out = _PyAST_FunctionType(argtypes, returns, arena); if (*out == NULL) goto failed; return 0; } @@ -5133,7 +5579,8 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) } int -obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) +obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* + arena) { int isinstance; @@ -5224,8 +5671,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { identifier name; arguments_ty args; - asdl_seq* body; - asdl_seq* decorator_list; + asdl_stmt_seq* body; + asdl_expr_seq* decorator_list; expr_ty returns; string type_comment; @@ -5279,7 +5726,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5316,7 +5763,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_seq_new(len, arena); + decorator_list = _Py_asdl_expr_seq_new(len, arena); if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5371,9 +5818,9 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = FunctionDef(name, args, body, decorator_list, returns, - type_comment, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_FunctionDef(name, args, body, decorator_list, returns, + type_comment, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -5385,8 +5832,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { identifier name; arguments_ty args; - asdl_seq* body; - asdl_seq* decorator_list; + asdl_stmt_seq* body; + asdl_expr_seq* decorator_list; expr_ty returns; string type_comment; @@ -5440,7 +5887,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5477,7 +5924,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_seq_new(len, arena); + decorator_list = _Py_asdl_expr_seq_new(len, arena); if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5532,9 +5979,10 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = AsyncFunctionDef(name, args, body, decorator_list, returns, - type_comment, lineno, col_offset, end_lineno, - end_col_offset, arena); + *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; } @@ -5545,10 +5993,10 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { identifier name; - asdl_seq* bases; - asdl_seq* keywords; - asdl_seq* body; - asdl_seq* decorator_list; + 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) { return 1; @@ -5583,7 +6031,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - bases = _Py_asdl_seq_new(len, arena); + bases = _Py_asdl_expr_seq_new(len, arena); if (bases == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5620,7 +6068,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - keywords = _Py_asdl_seq_new(len, arena); + keywords = _Py_asdl_keyword_seq_new(len, arena); if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; @@ -5657,7 +6105,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5694,7 +6142,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_seq_new(len, arena); + decorator_list = _Py_asdl_expr_seq_new(len, arena); if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5715,8 +6163,9 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = ClassDef(name, bases, keywords, body, decorator_list, lineno, - col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_ClassDef(name, bases, keywords, body, decorator_list, + lineno, col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -5745,8 +6194,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Return(value, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Return(value, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -5756,7 +6205,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* targets; + asdl_expr_seq* targets; if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) { return 1; @@ -5774,7 +6223,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - targets = _Py_asdl_seq_new(len, arena); + targets = _Py_asdl_expr_seq_new(len, arena); if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5795,8 +6244,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Delete(targets, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Delete(targets, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -5806,7 +6255,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* targets; + asdl_expr_seq* targets; expr_ty value; string type_comment; @@ -5826,7 +6275,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - targets = _Py_asdl_seq_new(len, arena); + targets = _Py_asdl_expr_seq_new(len, arena); if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5881,8 +6330,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Assign(targets, value, type_comment, lineno, col_offset, - end_lineno, end_col_offset, arena); + *out = _PyAST_Assign(targets, value, type_comment, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -5947,8 +6396,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = AugAssign(target, op, value, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_AugAssign(target, op, value, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6031,8 +6480,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = AnnAssign(target, annotation, value, simple, lineno, col_offset, - end_lineno, end_col_offset, arena); + *out = _PyAST_AnnAssign(target, annotation, value, simple, lineno, + col_offset, end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6044,8 +6493,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { expr_ty target; expr_ty iter; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; string type_comment; if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { @@ -6098,7 +6547,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6135,7 +6584,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6173,8 +6622,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = For(target, iter, body, orelse, type_comment, lineno, - col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_For(target, iter, body, orelse, type_comment, lineno, + col_offset, end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6186,8 +6635,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { expr_ty target; expr_ty iter; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; string type_comment; if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { @@ -6240,7 +6689,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6277,7 +6726,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6315,8 +6764,9 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = AsyncFor(target, iter, body, orelse, type_comment, lineno, - col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_AsyncFor(target, iter, body, orelse, type_comment, + lineno, col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -6327,8 +6777,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { expr_ty test; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { return 1; @@ -6363,7 +6813,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6400,7 +6850,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6421,8 +6871,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = While(test, body, orelse, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_While(test, body, orelse, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6433,8 +6883,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { expr_ty test; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { return 1; @@ -6469,7 +6919,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6506,7 +6956,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6527,8 +6977,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = If(test, body, orelse, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_If(test, body, orelse, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6538,8 +6988,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* items; - asdl_seq* body; + asdl_withitem_seq* items; + asdl_stmt_seq* body; string type_comment; if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) { @@ -6558,7 +7008,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - items = _Py_asdl_seq_new(len, arena); + items = _Py_asdl_withitem_seq_new(len, arena); if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; @@ -6595,7 +7045,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6633,8 +7083,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = With(items, body, type_comment, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_With(items, body, type_comment, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6644,8 +7094,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* items; - asdl_seq* body; + asdl_withitem_seq* items; + asdl_stmt_seq* body; string type_comment; if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) { @@ -6664,7 +7114,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - items = _Py_asdl_seq_new(len, arena); + items = _Py_asdl_withitem_seq_new(len, arena); if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; @@ -6701,7 +7151,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6739,8 +7189,76 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = AsyncWith(items, body, type_comment, lineno, col_offset, - end_lineno, end_col_offset, arena); + *out = _PyAST_AsyncWith(items, body, type_comment, lineno, col_offset, + end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->Match_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty subject; + asdl_match_case_seq* cases; + + if (_PyObject_LookupAttr(obj, state->subject, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"subject\" missing from Match"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'Match' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &subject, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->cases, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"cases\" missing from Match"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Match field \"cases\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + cases = _Py_asdl_match_case_seq_new(len, arena); + 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); + if (Py_EnterRecursiveCall(" while traversing 'Match' node")) { + goto failed; + } + res = obj2ast_match_case(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Match field \"cases\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(cases, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_Match(subject, cases, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6787,8 +7305,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Raise(exc, cause, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Raise(exc, cause, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6798,10 +7316,10 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* body; - asdl_seq* handlers; - asdl_seq* orelse; - asdl_seq* finalbody; + asdl_stmt_seq* body; + asdl_excepthandler_seq* handlers; + asdl_stmt_seq* orelse; + asdl_stmt_seq* finalbody; if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { return 1; @@ -6819,7 +7337,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6856,7 +7374,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - handlers = _Py_asdl_seq_new(len, arena); + handlers = _Py_asdl_excepthandler_seq_new(len, arena); if (handlers == NULL) goto failed; for (i = 0; i < len; i++) { excepthandler_ty val; @@ -6893,7 +7411,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6930,7 +7448,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - finalbody = _Py_asdl_seq_new(len, arena); + finalbody = _Py_asdl_stmt_seq_new(len, arena); if (finalbody == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6951,8 +7469,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Try(body, handlers, orelse, finalbody, lineno, col_offset, - end_lineno, end_col_offset, arena); + *out = _PyAST_Try(body, handlers, orelse, finalbody, lineno, + col_offset, end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6999,8 +7517,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Assert(test, msg, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Assert(test, msg, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7010,7 +7528,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* names; + asdl_alias_seq* names; if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { return 1; @@ -7028,7 +7546,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_alias_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; @@ -7049,8 +7567,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Import(names, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Import(names, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7061,7 +7579,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { identifier module; - asdl_seq* names; + asdl_alias_seq* names; int level; if (_PyObject_LookupAttr(obj, state->module, &tmp) < 0) { @@ -7097,7 +7615,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_alias_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; @@ -7135,8 +7653,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = ImportFrom(module, names, level, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_ImportFrom(module, names, level, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7146,7 +7664,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* names; + asdl_identifier_seq* names; if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { return 1; @@ -7164,7 +7682,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_identifier_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; @@ -7185,8 +7703,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Global(names, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Global(names, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7196,7 +7714,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* names; + asdl_identifier_seq* names; if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { return 1; @@ -7214,7 +7732,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_identifier_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; @@ -7235,8 +7753,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Nonlocal(names, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Nonlocal(names, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7265,8 +7783,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Expr(value, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Expr(value, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7277,7 +7795,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { - *out = Pass(lineno, col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_Pass(lineno, col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -7288,7 +7807,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { - *out = Break(lineno, col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_Break(lineno, col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -7299,7 +7819,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { - *out = Continue(lineno, col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_Continue(lineno, col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -7311,7 +7832,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } int -obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) +obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* + arena) { int isinstance; @@ -7401,7 +7923,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { boolop_ty op; - asdl_seq* values; + asdl_expr_seq* values; if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) { return 1; @@ -7436,7 +7958,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - values = _Py_asdl_seq_new(len, arena); + values = _Py_asdl_expr_seq_new(len, arena); if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7457,8 +7979,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = BoolOp(op, values, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_BoolOp(op, values, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7505,8 +8027,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = NamedExpr(target, value, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_NamedExpr(target, value, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7571,8 +8093,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = BinOp(left, op, right, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_BinOp(left, op, right, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7619,8 +8141,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = UnaryOp(op, operand, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_UnaryOp(op, operand, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7667,8 +8189,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Lambda(args, body, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Lambda(args, body, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7733,8 +8255,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = IfExp(test, body, orelse, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_IfExp(test, body, orelse, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7744,8 +8266,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* keys; - asdl_seq* values; + asdl_expr_seq* keys; + asdl_expr_seq* values; if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) { return 1; @@ -7763,7 +8285,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - keys = _Py_asdl_seq_new(len, arena); + keys = _Py_asdl_expr_seq_new(len, arena); if (keys == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7800,7 +8322,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - values = _Py_asdl_seq_new(len, arena); + values = _Py_asdl_expr_seq_new(len, arena); if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7821,8 +8343,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Dict(keys, values, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Dict(keys, values, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7832,7 +8354,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* elts; + asdl_expr_seq* elts; if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { return 1; @@ -7850,7 +8372,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_seq_new(len, arena); + elts = _Py_asdl_expr_seq_new(len, arena); if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7871,7 +8393,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Set(elts, lineno, col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_Set(elts, lineno, col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -7882,7 +8405,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty elt; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { return 1; @@ -7917,7 +8440,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -7938,8 +8461,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = ListComp(elt, generators, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_ListComp(elt, generators, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -7950,7 +8473,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty elt; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { return 1; @@ -7985,7 +8508,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -8006,8 +8529,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = SetComp(elt, generators, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_SetComp(elt, generators, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8019,7 +8542,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (isinstance) { expr_ty key; expr_ty value; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->key, &tmp) < 0) { return 1; @@ -8071,7 +8594,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -8092,8 +8615,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = DictComp(key, value, generators, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_DictComp(key, value, generators, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8104,7 +8627,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty elt; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { return 1; @@ -8139,7 +8662,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -8160,8 +8683,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = GeneratorExp(elt, generators, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_GeneratorExp(elt, generators, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8190,8 +8713,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Await(value, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Await(value, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8220,8 +8743,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Yield(value, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Yield(value, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8250,8 +8773,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = YieldFrom(value, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_YieldFrom(value, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8263,7 +8786,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (isinstance) { expr_ty left; asdl_int_seq* ops; - asdl_seq* comparators; + asdl_expr_seq* comparators; if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) { return 1; @@ -8335,7 +8858,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - comparators = _Py_asdl_seq_new(len, arena); + comparators = _Py_asdl_expr_seq_new(len, arena); if (comparators == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8356,8 +8879,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Compare(left, ops, comparators, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Compare(left, ops, comparators, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8368,8 +8891,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty func; - asdl_seq* args; - asdl_seq* keywords; + asdl_expr_seq* args; + asdl_keyword_seq* keywords; if (_PyObject_LookupAttr(obj, state->func, &tmp) < 0) { return 1; @@ -8404,7 +8927,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - args = _Py_asdl_seq_new(len, arena); + args = _Py_asdl_expr_seq_new(len, arena); if (args == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8441,7 +8964,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - keywords = _Py_asdl_seq_new(len, arena); + keywords = _Py_asdl_keyword_seq_new(len, arena); if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; @@ -8462,8 +8985,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = Call(func, args, keywords, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Call(func, args, keywords, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8497,9 +9020,9 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (_PyObject_LookupAttr(obj, state->conversion, &tmp) < 0) { return 1; } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - conversion = 0; + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"conversion\" missing from FormattedValue"); + return 1; } else { int res; @@ -8528,8 +9051,9 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = FormattedValue(value, conversion, format_spec, lineno, - col_offset, end_lineno, end_col_offset, arena); + *out = _PyAST_FormattedValue(value, conversion, format_spec, lineno, + col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -8539,7 +9063,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* values; + asdl_expr_seq* values; if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) { return 1; @@ -8557,7 +9081,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - values = _Py_asdl_seq_new(len, arena); + values = _Py_asdl_expr_seq_new(len, arena); if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8578,8 +9102,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = JoinedStr(values, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8626,8 +9150,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Constant(value, kind, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Constant(value, kind, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8692,8 +9216,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Attribute(value, attr, ctx, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Attribute(value, attr, ctx, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8758,8 +9282,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Subscript(value, slice, ctx, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Subscript(value, slice, ctx, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8806,8 +9330,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Starred(value, ctx, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Starred(value, ctx, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8854,8 +9378,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Name(id, ctx, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Name(id, ctx, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8865,7 +9389,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* elts; + asdl_expr_seq* elts; expr_context_ty ctx; if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { @@ -8884,7 +9408,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_seq_new(len, arena); + elts = _Py_asdl_expr_seq_new(len, arena); if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8922,8 +9446,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = List(elts, ctx, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_List(elts, ctx, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -8933,7 +9457,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* elts; + asdl_expr_seq* elts; expr_context_ty ctx; if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { @@ -8952,7 +9476,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_seq_new(len, arena); + elts = _Py_asdl_expr_seq_new(len, arena); if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8990,8 +9514,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Tuple(elts, ctx, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_Tuple(elts, ctx, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -9056,8 +9580,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Slice(lower, upper, step, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_Slice(lower, upper, step, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -9069,7 +9593,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } int -obj2ast_expr_context(astmodulestate *state, PyObject* obj, expr_context_ty* +obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty* out, PyArena* arena) { int isinstance; @@ -9104,7 +9628,7 @@ obj2ast_expr_context(astmodulestate *state, PyObject* obj, expr_context_ty* } int -obj2ast_boolop(astmodulestate *state, PyObject* obj, boolop_ty* out, PyArena* +obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* out, PyArena* arena) { int isinstance; @@ -9131,7 +9655,7 @@ obj2ast_boolop(astmodulestate *state, PyObject* obj, boolop_ty* out, PyArena* } int -obj2ast_operator(astmodulestate *state, PyObject* obj, operator_ty* out, +obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, PyArena* arena) { int isinstance; @@ -9246,8 +9770,8 @@ obj2ast_operator(astmodulestate *state, PyObject* obj, operator_ty* out, } int -obj2ast_unaryop(astmodulestate *state, PyObject* obj, unaryop_ty* out, PyArena* - arena) +obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, + PyArena* arena) { int isinstance; @@ -9289,7 +9813,7 @@ obj2ast_unaryop(astmodulestate *state, PyObject* obj, unaryop_ty* out, PyArena* } int -obj2ast_cmpop(astmodulestate *state, PyObject* obj, cmpop_ty* out, PyArena* +obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* arena) { int isinstance; @@ -9380,13 +9904,13 @@ obj2ast_cmpop(astmodulestate *state, PyObject* obj, cmpop_ty* out, PyArena* } int -obj2ast_comprehension(astmodulestate *state, PyObject* obj, comprehension_ty* +obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* out, PyArena* arena) { PyObject* tmp = NULL; expr_ty target; expr_ty iter; - asdl_seq* ifs; + asdl_expr_seq* ifs; int is_async; if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { @@ -9439,7 +9963,7 @@ obj2ast_comprehension(astmodulestate *state, PyObject* obj, comprehension_ty* goto failed; } len = PyList_GET_SIZE(tmp); - ifs = _Py_asdl_seq_new(len, arena); + ifs = _Py_asdl_expr_seq_new(len, arena); if (ifs == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -9477,7 +10001,7 @@ obj2ast_comprehension(astmodulestate *state, PyObject* obj, comprehension_ty* if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = comprehension(target, iter, ifs, is_async, arena); + *out = _PyAST_comprehension(target, iter, ifs, is_async, arena); return 0; failed: Py_XDECREF(tmp); @@ -9485,7 +10009,7 @@ failed: } int -obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty* +obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* out, PyArena* arena) { int isinstance; @@ -9577,7 +10101,7 @@ obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty* if (isinstance) { expr_ty type; identifier name; - asdl_seq* body; + asdl_stmt_seq* body; if (_PyObject_LookupAttr(obj, state->type, &tmp) < 0) { return 1; @@ -9629,7 +10153,7 @@ obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty* goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -9650,8 +10174,8 @@ obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty* } Py_CLEAR(tmp); } - *out = ExceptHandler(type, name, body, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_ExceptHandler(type, name, body, lineno, col_offset, + end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -9663,17 +10187,17 @@ obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty* } int -obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, +obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, PyArena* arena) { PyObject* tmp = NULL; - asdl_seq* posonlyargs; - asdl_seq* args; + asdl_arg_seq* posonlyargs; + asdl_arg_seq* args; arg_ty vararg; - asdl_seq* kwonlyargs; - asdl_seq* kw_defaults; + asdl_arg_seq* kwonlyargs; + asdl_expr_seq* kw_defaults; arg_ty kwarg; - asdl_seq* defaults; + asdl_expr_seq* defaults; if (_PyObject_LookupAttr(obj, state->posonlyargs, &tmp) < 0) { return 1; @@ -9691,7 +10215,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - posonlyargs = _Py_asdl_seq_new(len, arena); + posonlyargs = _Py_asdl_arg_seq_new(len, arena); if (posonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; @@ -9728,7 +10252,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - args = _Py_asdl_seq_new(len, arena); + args = _Py_asdl_arg_seq_new(len, arena); if (args == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; @@ -9782,7 +10306,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - kwonlyargs = _Py_asdl_seq_new(len, arena); + kwonlyargs = _Py_asdl_arg_seq_new(len, arena); if (kwonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; @@ -9819,7 +10343,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - kw_defaults = _Py_asdl_seq_new(len, arena); + kw_defaults = _Py_asdl_expr_seq_new(len, arena); if (kw_defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -9873,7 +10397,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - defaults = _Py_asdl_seq_new(len, arena); + defaults = _Py_asdl_expr_seq_new(len, arena); if (defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -9894,8 +10418,8 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, } Py_CLEAR(tmp); } - *out = arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, - defaults, arena); + *out = _PyAST_arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, + kwarg, defaults, arena); return 0; failed: Py_XDECREF(tmp); @@ -9903,7 +10427,7 @@ failed: } int -obj2ast_arg(astmodulestate *state, PyObject* obj, arg_ty* out, PyArena* arena) +obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) { PyObject* tmp = NULL; identifier arg; @@ -10033,8 +10557,8 @@ obj2ast_arg(astmodulestate *state, PyObject* obj, arg_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = arg(arg, annotation, type_comment, lineno, col_offset, end_lineno, - end_col_offset, arena); + *out = _PyAST_arg(arg, annotation, type_comment, lineno, col_offset, + end_lineno, end_col_offset, arena); return 0; failed: Py_XDECREF(tmp); @@ -10042,8 +10566,8 @@ failed: } int -obj2ast_keyword(astmodulestate *state, PyObject* obj, keyword_ty* out, PyArena* - arena) +obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, + PyArena* arena) { PyObject* tmp = NULL; identifier arg; @@ -10155,8 +10679,8 @@ obj2ast_keyword(astmodulestate *state, PyObject* obj, keyword_ty* out, PyArena* if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = keyword(arg, value, lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = _PyAST_keyword(arg, value, lineno, col_offset, end_lineno, + end_col_offset, arena); return 0; failed: Py_XDECREF(tmp); @@ -10164,12 +10688,16 @@ failed: } int -obj2ast_alias(astmodulestate *state, PyObject* obj, alias_ty* out, PyArena* +obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* arena) { PyObject* tmp = NULL; identifier name; identifier asname; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { return 1; @@ -10205,65 +10733,802 @@ obj2ast_alias(astmodulestate *state, PyObject* obj, alias_ty* out, PyArena* if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = alias(name, asname, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_withitem(astmodulestate *state, PyObject* obj, withitem_ty* out, - PyArena* arena) -{ - PyObject* tmp = NULL; - expr_ty context_expr; - expr_ty optional_vars; - - if (_PyObject_LookupAttr(obj, state->context_expr, &tmp) < 0) { + if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem"); + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from alias"); return 1; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { + if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } - res = obj2ast_expr(state, tmp, &context_expr, arena); + res = obj2ast_int(state, tmp, &lineno, arena); Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } - if (_PyObject_LookupAttr(obj, state->optional_vars, &tmp) < 0) { + if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from alias"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'alias' 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 || tmp == Py_None) { Py_CLEAR(tmp); - optional_vars = NULL; + end_lineno = 0; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { + if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } - res = obj2ast_expr(state, tmp, &optional_vars, arena); + res = obj2ast_int(state, tmp, &end_lineno, arena); Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = withitem(context_expr, optional_vars, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - + if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_col_offset = 0; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &end_col_offset, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_alias(name, asname, lineno, col_offset, end_lineno, + end_col_offset, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, + PyArena* arena) +{ + PyObject* tmp = NULL; + expr_ty context_expr; + expr_ty optional_vars; + + if (_PyObject_LookupAttr(obj, state->context_expr, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &context_expr, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->optional_vars, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + optional_vars = NULL; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &optional_vars, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_withitem(context_expr, optional_vars, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, + PyArena* arena) +{ + PyObject* tmp = NULL; + pattern_ty pattern; + expr_ty guard; + asdl_stmt_seq* body; + + if (_PyObject_LookupAttr(obj, state->pattern, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"pattern\" missing from match_case"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { + goto failed; + } + res = obj2ast_pattern(state, tmp, &pattern, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->guard, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + guard = NULL; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &guard, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from match_case"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "match_case field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_stmt_seq_new(len, 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); + if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { + goto failed; + } + res = obj2ast_stmt(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "match_case field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_match_case(pattern, guard, body, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_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 pattern"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'pattern' 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 pattern"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'pattern' 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 pattern"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'pattern' 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 pattern"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &end_col_offset, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + tp = state->MatchValue_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + + if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchValue"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'MatchValue' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &value, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_MatchValue(value, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->MatchSingleton_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + constant value; + + if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchSingleton"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'MatchSingleton' node")) { + goto failed; + } + res = obj2ast_constant(state, tmp, &value, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_MatchSingleton(value, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->MatchSequence_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_pattern_seq* patterns; + + if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchSequence"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "MatchSequence field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + patterns = _Py_asdl_pattern_seq_new(len, arena); + if (patterns == NULL) goto failed; + for (i = 0; i < len; i++) { + pattern_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'MatchSequence' node")) { + goto failed; + } + res = obj2ast_pattern(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "MatchSequence field \"patterns\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(patterns, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_MatchSequence(patterns, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->MatchMapping_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_expr_seq* keys; + asdl_pattern_seq* patterns; + identifier rest; + + if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from MatchMapping"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "MatchMapping field \"keys\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + keys = _Py_asdl_expr_seq_new(len, arena); + if (keys == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "MatchMapping field \"keys\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(keys, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchMapping"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "MatchMapping field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + patterns = _Py_asdl_pattern_seq_new(len, arena); + if (patterns == NULL) goto failed; + for (i = 0; i < len; i++) { + pattern_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { + goto failed; + } + res = obj2ast_pattern(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "MatchMapping field \"patterns\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(patterns, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->rest, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + rest = NULL; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { + goto failed; + } + res = obj2ast_identifier(state, tmp, &rest, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_MatchMapping(keys, patterns, rest, lineno, col_offset, + end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->MatchClass_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty cls; + asdl_pattern_seq* patterns; + asdl_identifier_seq* kwd_attrs; + asdl_pattern_seq* kwd_patterns; + + if (_PyObject_LookupAttr(obj, state->cls, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"cls\" missing from MatchClass"); + return 1; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &cls, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchClass"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "MatchClass field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + patterns = _Py_asdl_pattern_seq_new(len, arena); + if (patterns == NULL) goto failed; + for (i = 0; i < len; i++) { + pattern_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + goto failed; + } + res = obj2ast_pattern(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"patterns\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(patterns, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->kwd_attrs, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"kwd_attrs\" missing from MatchClass"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "MatchClass field \"kwd_attrs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + kwd_attrs = _Py_asdl_identifier_seq_new(len, arena); + if (kwd_attrs == NULL) goto failed; + for (i = 0; i < len; i++) { + identifier val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + goto failed; + } + res = obj2ast_identifier(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"kwd_attrs\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(kwd_attrs, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->kwd_patterns, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"kwd_patterns\" missing from MatchClass"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "MatchClass field \"kwd_patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + kwd_patterns = _Py_asdl_pattern_seq_new(len, arena); + 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); + if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + goto failed; + } + res = obj2ast_pattern(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"kwd_patterns\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(kwd_patterns, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_MatchClass(cls, patterns, kwd_attrs, kwd_patterns, + lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->MatchStar_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 || tmp == Py_None) { + Py_CLEAR(tmp); + name = NULL; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'MatchStar' node")) { + goto failed; + } + res = obj2ast_identifier(state, tmp, &name, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_MatchStar(name, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->MatchAs_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + pattern_ty pattern; + identifier name; + + if (_PyObject_LookupAttr(obj, state->pattern, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + pattern = NULL; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { + goto failed; + } + res = obj2ast_pattern(state, tmp, &pattern, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + name = NULL; + } + else { + int res; + if (Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { + goto failed; + } + res = obj2ast_identifier(state, tmp, &name, arena); + Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_MatchAs(pattern, name, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->MatchOr_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_pattern_seq* patterns; + + if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchOr"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "MatchOr field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + patterns = _Py_asdl_pattern_seq_new(len, arena); + if (patterns == NULL) goto failed; + for (i = 0; i < len; i++) { + pattern_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'MatchOr' node")) { + goto failed; + } + res = obj2ast_pattern(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "MatchOr field \"patterns\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(patterns, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_MatchOr(patterns, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of pattern, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + int -obj2ast_type_ignore(astmodulestate *state, PyObject* obj, type_ignore_ty* out, - PyArena* arena) +obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* + out, PyArena* arena) { int isinstance; @@ -10317,7 +11582,7 @@ obj2ast_type_ignore(astmodulestate *state, PyObject* obj, type_ignore_ty* out, if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = TypeIgnore(lineno, tag, arena); + *out = _PyAST_TypeIgnore(lineno, tag, arena); if (*out == NULL) goto failed; return 0; } @@ -10332,15 +11597,13 @@ obj2ast_type_ignore(astmodulestate *state, PyObject* obj, type_ignore_ty* out, static int astmodule_exec(PyObject *m) { - astmodulestate *state = get_ast_state(m); - - if (!init_types(state)) { + struct ast_state *state = get_ast_state(); + if (state == NULL) { return -1; } - if (PyModule_AddObject(m, "AST", state->AST_type) < 0) { + if (PyModule_AddObjectRef(m, "AST", state->AST_type) < 0) { return -1; } - Py_INCREF(state->AST_type); if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) { return -1; } @@ -10350,432 +11613,368 @@ astmodule_exec(PyObject *m) if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) { return -1; } - if (PyModule_AddObject(m, "mod", state->mod_type) < 0) { + if (PyModule_AddObjectRef(m, "mod", state->mod_type) < 0) { return -1; } - Py_INCREF(state->mod_type); - if (PyModule_AddObject(m, "Module", state->Module_type) < 0) { + if (PyModule_AddObjectRef(m, "Module", state->Module_type) < 0) { return -1; } - Py_INCREF(state->Module_type); - if (PyModule_AddObject(m, "Interactive", state->Interactive_type) < 0) { + if (PyModule_AddObjectRef(m, "Interactive", state->Interactive_type) < 0) { return -1; } - Py_INCREF(state->Interactive_type); - if (PyModule_AddObject(m, "Expression", state->Expression_type) < 0) { + if (PyModule_AddObjectRef(m, "Expression", state->Expression_type) < 0) { return -1; } - Py_INCREF(state->Expression_type); - if (PyModule_AddObject(m, "FunctionType", state->FunctionType_type) < 0) { + if (PyModule_AddObjectRef(m, "FunctionType", state->FunctionType_type) < 0) + { return -1; } - Py_INCREF(state->FunctionType_type); - if (PyModule_AddObject(m, "stmt", state->stmt_type) < 0) { + if (PyModule_AddObjectRef(m, "stmt", state->stmt_type) < 0) { return -1; } - Py_INCREF(state->stmt_type); - if (PyModule_AddObject(m, "FunctionDef", state->FunctionDef_type) < 0) { + if (PyModule_AddObjectRef(m, "FunctionDef", state->FunctionDef_type) < 0) { return -1; } - Py_INCREF(state->FunctionDef_type); - if (PyModule_AddObject(m, "AsyncFunctionDef", state->AsyncFunctionDef_type) - < 0) { + if (PyModule_AddObjectRef(m, "AsyncFunctionDef", + state->AsyncFunctionDef_type) < 0) { return -1; } - Py_INCREF(state->AsyncFunctionDef_type); - if (PyModule_AddObject(m, "ClassDef", state->ClassDef_type) < 0) { + if (PyModule_AddObjectRef(m, "ClassDef", state->ClassDef_type) < 0) { return -1; } - Py_INCREF(state->ClassDef_type); - if (PyModule_AddObject(m, "Return", state->Return_type) < 0) { + if (PyModule_AddObjectRef(m, "Return", state->Return_type) < 0) { return -1; } - Py_INCREF(state->Return_type); - if (PyModule_AddObject(m, "Delete", state->Delete_type) < 0) { + if (PyModule_AddObjectRef(m, "Delete", state->Delete_type) < 0) { return -1; } - Py_INCREF(state->Delete_type); - if (PyModule_AddObject(m, "Assign", state->Assign_type) < 0) { + if (PyModule_AddObjectRef(m, "Assign", state->Assign_type) < 0) { return -1; } - Py_INCREF(state->Assign_type); - if (PyModule_AddObject(m, "AugAssign", state->AugAssign_type) < 0) { + if (PyModule_AddObjectRef(m, "AugAssign", state->AugAssign_type) < 0) { return -1; } - Py_INCREF(state->AugAssign_type); - if (PyModule_AddObject(m, "AnnAssign", state->AnnAssign_type) < 0) { + if (PyModule_AddObjectRef(m, "AnnAssign", state->AnnAssign_type) < 0) { return -1; } - Py_INCREF(state->AnnAssign_type); - if (PyModule_AddObject(m, "For", state->For_type) < 0) { + if (PyModule_AddObjectRef(m, "For", state->For_type) < 0) { return -1; } - Py_INCREF(state->For_type); - if (PyModule_AddObject(m, "AsyncFor", state->AsyncFor_type) < 0) { + if (PyModule_AddObjectRef(m, "AsyncFor", state->AsyncFor_type) < 0) { return -1; } - Py_INCREF(state->AsyncFor_type); - if (PyModule_AddObject(m, "While", state->While_type) < 0) { + if (PyModule_AddObjectRef(m, "While", state->While_type) < 0) { return -1; } - Py_INCREF(state->While_type); - if (PyModule_AddObject(m, "If", state->If_type) < 0) { + if (PyModule_AddObjectRef(m, "If", state->If_type) < 0) { return -1; } - Py_INCREF(state->If_type); - if (PyModule_AddObject(m, "With", state->With_type) < 0) { + if (PyModule_AddObjectRef(m, "With", state->With_type) < 0) { return -1; } - Py_INCREF(state->With_type); - if (PyModule_AddObject(m, "AsyncWith", state->AsyncWith_type) < 0) { + if (PyModule_AddObjectRef(m, "AsyncWith", state->AsyncWith_type) < 0) { return -1; } - Py_INCREF(state->AsyncWith_type); - if (PyModule_AddObject(m, "Raise", state->Raise_type) < 0) { + if (PyModule_AddObjectRef(m, "Match", state->Match_type) < 0) { return -1; } - Py_INCREF(state->Raise_type); - if (PyModule_AddObject(m, "Try", state->Try_type) < 0) { + if (PyModule_AddObjectRef(m, "Raise", state->Raise_type) < 0) { return -1; } - Py_INCREF(state->Try_type); - if (PyModule_AddObject(m, "Assert", state->Assert_type) < 0) { + if (PyModule_AddObjectRef(m, "Try", state->Try_type) < 0) { return -1; } - Py_INCREF(state->Assert_type); - if (PyModule_AddObject(m, "Import", state->Import_type) < 0) { + if (PyModule_AddObjectRef(m, "Assert", state->Assert_type) < 0) { return -1; } - Py_INCREF(state->Import_type); - if (PyModule_AddObject(m, "ImportFrom", state->ImportFrom_type) < 0) { + if (PyModule_AddObjectRef(m, "Import", state->Import_type) < 0) { return -1; } - Py_INCREF(state->ImportFrom_type); - if (PyModule_AddObject(m, "Global", state->Global_type) < 0) { + if (PyModule_AddObjectRef(m, "ImportFrom", state->ImportFrom_type) < 0) { return -1; } - Py_INCREF(state->Global_type); - if (PyModule_AddObject(m, "Nonlocal", state->Nonlocal_type) < 0) { + if (PyModule_AddObjectRef(m, "Global", state->Global_type) < 0) { return -1; } - Py_INCREF(state->Nonlocal_type); - if (PyModule_AddObject(m, "Expr", state->Expr_type) < 0) { + if (PyModule_AddObjectRef(m, "Nonlocal", state->Nonlocal_type) < 0) { return -1; } - Py_INCREF(state->Expr_type); - if (PyModule_AddObject(m, "Pass", state->Pass_type) < 0) { + if (PyModule_AddObjectRef(m, "Expr", state->Expr_type) < 0) { return -1; } - Py_INCREF(state->Pass_type); - if (PyModule_AddObject(m, "Break", state->Break_type) < 0) { + if (PyModule_AddObjectRef(m, "Pass", state->Pass_type) < 0) { return -1; } - Py_INCREF(state->Break_type); - if (PyModule_AddObject(m, "Continue", state->Continue_type) < 0) { + if (PyModule_AddObjectRef(m, "Break", state->Break_type) < 0) { return -1; } - Py_INCREF(state->Continue_type); - if (PyModule_AddObject(m, "expr", state->expr_type) < 0) { + if (PyModule_AddObjectRef(m, "Continue", state->Continue_type) < 0) { return -1; } - Py_INCREF(state->expr_type); - if (PyModule_AddObject(m, "BoolOp", state->BoolOp_type) < 0) { + if (PyModule_AddObjectRef(m, "expr", state->expr_type) < 0) { return -1; } - Py_INCREF(state->BoolOp_type); - if (PyModule_AddObject(m, "NamedExpr", state->NamedExpr_type) < 0) { + if (PyModule_AddObjectRef(m, "BoolOp", state->BoolOp_type) < 0) { return -1; } - Py_INCREF(state->NamedExpr_type); - if (PyModule_AddObject(m, "BinOp", state->BinOp_type) < 0) { + if (PyModule_AddObjectRef(m, "NamedExpr", state->NamedExpr_type) < 0) { return -1; } - Py_INCREF(state->BinOp_type); - if (PyModule_AddObject(m, "UnaryOp", state->UnaryOp_type) < 0) { + if (PyModule_AddObjectRef(m, "BinOp", state->BinOp_type) < 0) { return -1; } - Py_INCREF(state->UnaryOp_type); - if (PyModule_AddObject(m, "Lambda", state->Lambda_type) < 0) { + if (PyModule_AddObjectRef(m, "UnaryOp", state->UnaryOp_type) < 0) { return -1; } - Py_INCREF(state->Lambda_type); - if (PyModule_AddObject(m, "IfExp", state->IfExp_type) < 0) { + if (PyModule_AddObjectRef(m, "Lambda", state->Lambda_type) < 0) { return -1; } - Py_INCREF(state->IfExp_type); - if (PyModule_AddObject(m, "Dict", state->Dict_type) < 0) { + if (PyModule_AddObjectRef(m, "IfExp", state->IfExp_type) < 0) { return -1; } - Py_INCREF(state->Dict_type); - if (PyModule_AddObject(m, "Set", state->Set_type) < 0) { + if (PyModule_AddObjectRef(m, "Dict", state->Dict_type) < 0) { return -1; } - Py_INCREF(state->Set_type); - if (PyModule_AddObject(m, "ListComp", state->ListComp_type) < 0) { + if (PyModule_AddObjectRef(m, "Set", state->Set_type) < 0) { return -1; } - Py_INCREF(state->ListComp_type); - if (PyModule_AddObject(m, "SetComp", state->SetComp_type) < 0) { + if (PyModule_AddObjectRef(m, "ListComp", state->ListComp_type) < 0) { return -1; } - Py_INCREF(state->SetComp_type); - if (PyModule_AddObject(m, "DictComp", state->DictComp_type) < 0) { + if (PyModule_AddObjectRef(m, "SetComp", state->SetComp_type) < 0) { return -1; } - Py_INCREF(state->DictComp_type); - if (PyModule_AddObject(m, "GeneratorExp", state->GeneratorExp_type) < 0) { + if (PyModule_AddObjectRef(m, "DictComp", state->DictComp_type) < 0) { return -1; } - Py_INCREF(state->GeneratorExp_type); - if (PyModule_AddObject(m, "Await", state->Await_type) < 0) { + if (PyModule_AddObjectRef(m, "GeneratorExp", state->GeneratorExp_type) < 0) + { return -1; } - Py_INCREF(state->Await_type); - if (PyModule_AddObject(m, "Yield", state->Yield_type) < 0) { + if (PyModule_AddObjectRef(m, "Await", state->Await_type) < 0) { return -1; } - Py_INCREF(state->Yield_type); - if (PyModule_AddObject(m, "YieldFrom", state->YieldFrom_type) < 0) { + if (PyModule_AddObjectRef(m, "Yield", state->Yield_type) < 0) { return -1; } - Py_INCREF(state->YieldFrom_type); - if (PyModule_AddObject(m, "Compare", state->Compare_type) < 0) { + if (PyModule_AddObjectRef(m, "YieldFrom", state->YieldFrom_type) < 0) { return -1; } - Py_INCREF(state->Compare_type); - if (PyModule_AddObject(m, "Call", state->Call_type) < 0) { + if (PyModule_AddObjectRef(m, "Compare", state->Compare_type) < 0) { return -1; } - Py_INCREF(state->Call_type); - if (PyModule_AddObject(m, "FormattedValue", state->FormattedValue_type) < - 0) { + if (PyModule_AddObjectRef(m, "Call", state->Call_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "FormattedValue", state->FormattedValue_type) + < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "JoinedStr", state->JoinedStr_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "Constant", state->Constant_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "Attribute", state->Attribute_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "Subscript", state->Subscript_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "Starred", state->Starred_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "Name", state->Name_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "List", state->List_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "Tuple", state->Tuple_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "Slice", state->Slice_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "expr_context", state->expr_context_type) < 0) + { return -1; } - Py_INCREF(state->FormattedValue_type); - if (PyModule_AddObject(m, "JoinedStr", state->JoinedStr_type) < 0) { + if (PyModule_AddObjectRef(m, "Load", state->Load_type) < 0) { return -1; } - Py_INCREF(state->JoinedStr_type); - if (PyModule_AddObject(m, "Constant", state->Constant_type) < 0) { + if (PyModule_AddObjectRef(m, "Store", state->Store_type) < 0) { return -1; } - Py_INCREF(state->Constant_type); - if (PyModule_AddObject(m, "Attribute", state->Attribute_type) < 0) { + if (PyModule_AddObjectRef(m, "Del", state->Del_type) < 0) { return -1; } - Py_INCREF(state->Attribute_type); - if (PyModule_AddObject(m, "Subscript", state->Subscript_type) < 0) { + if (PyModule_AddObjectRef(m, "boolop", state->boolop_type) < 0) { return -1; } - Py_INCREF(state->Subscript_type); - if (PyModule_AddObject(m, "Starred", state->Starred_type) < 0) { + if (PyModule_AddObjectRef(m, "And", state->And_type) < 0) { return -1; } - Py_INCREF(state->Starred_type); - if (PyModule_AddObject(m, "Name", state->Name_type) < 0) { + if (PyModule_AddObjectRef(m, "Or", state->Or_type) < 0) { return -1; } - Py_INCREF(state->Name_type); - if (PyModule_AddObject(m, "List", state->List_type) < 0) { + if (PyModule_AddObjectRef(m, "operator", state->operator_type) < 0) { return -1; } - Py_INCREF(state->List_type); - if (PyModule_AddObject(m, "Tuple", state->Tuple_type) < 0) { + if (PyModule_AddObjectRef(m, "Add", state->Add_type) < 0) { return -1; } - Py_INCREF(state->Tuple_type); - if (PyModule_AddObject(m, "Slice", state->Slice_type) < 0) { + if (PyModule_AddObjectRef(m, "Sub", state->Sub_type) < 0) { return -1; } - Py_INCREF(state->Slice_type); - if (PyModule_AddObject(m, "expr_context", state->expr_context_type) < 0) { + if (PyModule_AddObjectRef(m, "Mult", state->Mult_type) < 0) { return -1; } - Py_INCREF(state->expr_context_type); - if (PyModule_AddObject(m, "Load", state->Load_type) < 0) { + if (PyModule_AddObjectRef(m, "MatMult", state->MatMult_type) < 0) { return -1; } - Py_INCREF(state->Load_type); - if (PyModule_AddObject(m, "Store", state->Store_type) < 0) { + if (PyModule_AddObjectRef(m, "Div", state->Div_type) < 0) { return -1; } - Py_INCREF(state->Store_type); - if (PyModule_AddObject(m, "Del", state->Del_type) < 0) { + if (PyModule_AddObjectRef(m, "Mod", state->Mod_type) < 0) { return -1; } - Py_INCREF(state->Del_type); - if (PyModule_AddObject(m, "boolop", state->boolop_type) < 0) { + if (PyModule_AddObjectRef(m, "Pow", state->Pow_type) < 0) { return -1; } - Py_INCREF(state->boolop_type); - if (PyModule_AddObject(m, "And", state->And_type) < 0) { + if (PyModule_AddObjectRef(m, "LShift", state->LShift_type) < 0) { return -1; } - Py_INCREF(state->And_type); - if (PyModule_AddObject(m, "Or", state->Or_type) < 0) { + if (PyModule_AddObjectRef(m, "RShift", state->RShift_type) < 0) { return -1; } - Py_INCREF(state->Or_type); - if (PyModule_AddObject(m, "operator", state->operator_type) < 0) { + if (PyModule_AddObjectRef(m, "BitOr", state->BitOr_type) < 0) { return -1; } - Py_INCREF(state->operator_type); - if (PyModule_AddObject(m, "Add", state->Add_type) < 0) { + if (PyModule_AddObjectRef(m, "BitXor", state->BitXor_type) < 0) { return -1; } - Py_INCREF(state->Add_type); - if (PyModule_AddObject(m, "Sub", state->Sub_type) < 0) { + if (PyModule_AddObjectRef(m, "BitAnd", state->BitAnd_type) < 0) { return -1; } - Py_INCREF(state->Sub_type); - if (PyModule_AddObject(m, "Mult", state->Mult_type) < 0) { + if (PyModule_AddObjectRef(m, "FloorDiv", state->FloorDiv_type) < 0) { return -1; } - Py_INCREF(state->Mult_type); - if (PyModule_AddObject(m, "MatMult", state->MatMult_type) < 0) { + if (PyModule_AddObjectRef(m, "unaryop", state->unaryop_type) < 0) { return -1; } - Py_INCREF(state->MatMult_type); - if (PyModule_AddObject(m, "Div", state->Div_type) < 0) { + if (PyModule_AddObjectRef(m, "Invert", state->Invert_type) < 0) { return -1; } - Py_INCREF(state->Div_type); - if (PyModule_AddObject(m, "Mod", state->Mod_type) < 0) { + if (PyModule_AddObjectRef(m, "Not", state->Not_type) < 0) { return -1; } - Py_INCREF(state->Mod_type); - if (PyModule_AddObject(m, "Pow", state->Pow_type) < 0) { + if (PyModule_AddObjectRef(m, "UAdd", state->UAdd_type) < 0) { return -1; } - Py_INCREF(state->Pow_type); - if (PyModule_AddObject(m, "LShift", state->LShift_type) < 0) { + if (PyModule_AddObjectRef(m, "USub", state->USub_type) < 0) { return -1; } - Py_INCREF(state->LShift_type); - if (PyModule_AddObject(m, "RShift", state->RShift_type) < 0) { + if (PyModule_AddObjectRef(m, "cmpop", state->cmpop_type) < 0) { return -1; } - Py_INCREF(state->RShift_type); - if (PyModule_AddObject(m, "BitOr", state->BitOr_type) < 0) { + if (PyModule_AddObjectRef(m, "Eq", state->Eq_type) < 0) { return -1; } - Py_INCREF(state->BitOr_type); - if (PyModule_AddObject(m, "BitXor", state->BitXor_type) < 0) { + if (PyModule_AddObjectRef(m, "NotEq", state->NotEq_type) < 0) { return -1; } - Py_INCREF(state->BitXor_type); - if (PyModule_AddObject(m, "BitAnd", state->BitAnd_type) < 0) { + if (PyModule_AddObjectRef(m, "Lt", state->Lt_type) < 0) { return -1; } - Py_INCREF(state->BitAnd_type); - if (PyModule_AddObject(m, "FloorDiv", state->FloorDiv_type) < 0) { + if (PyModule_AddObjectRef(m, "LtE", state->LtE_type) < 0) { return -1; } - Py_INCREF(state->FloorDiv_type); - if (PyModule_AddObject(m, "unaryop", state->unaryop_type) < 0) { + if (PyModule_AddObjectRef(m, "Gt", state->Gt_type) < 0) { return -1; } - Py_INCREF(state->unaryop_type); - if (PyModule_AddObject(m, "Invert", state->Invert_type) < 0) { + if (PyModule_AddObjectRef(m, "GtE", state->GtE_type) < 0) { return -1; } - Py_INCREF(state->Invert_type); - if (PyModule_AddObject(m, "Not", state->Not_type) < 0) { + if (PyModule_AddObjectRef(m, "Is", state->Is_type) < 0) { return -1; } - Py_INCREF(state->Not_type); - if (PyModule_AddObject(m, "UAdd", state->UAdd_type) < 0) { + if (PyModule_AddObjectRef(m, "IsNot", state->IsNot_type) < 0) { return -1; } - Py_INCREF(state->UAdd_type); - if (PyModule_AddObject(m, "USub", state->USub_type) < 0) { + if (PyModule_AddObjectRef(m, "In", state->In_type) < 0) { return -1; } - Py_INCREF(state->USub_type); - if (PyModule_AddObject(m, "cmpop", state->cmpop_type) < 0) { + if (PyModule_AddObjectRef(m, "NotIn", state->NotIn_type) < 0) { return -1; } - Py_INCREF(state->cmpop_type); - if (PyModule_AddObject(m, "Eq", state->Eq_type) < 0) { + if (PyModule_AddObjectRef(m, "comprehension", state->comprehension_type) < + 0) { return -1; } - Py_INCREF(state->Eq_type); - if (PyModule_AddObject(m, "NotEq", state->NotEq_type) < 0) { + if (PyModule_AddObjectRef(m, "excepthandler", state->excepthandler_type) < + 0) { return -1; } - Py_INCREF(state->NotEq_type); - if (PyModule_AddObject(m, "Lt", state->Lt_type) < 0) { + if (PyModule_AddObjectRef(m, "ExceptHandler", state->ExceptHandler_type) < + 0) { return -1; } - Py_INCREF(state->Lt_type); - if (PyModule_AddObject(m, "LtE", state->LtE_type) < 0) { + if (PyModule_AddObjectRef(m, "arguments", state->arguments_type) < 0) { return -1; } - Py_INCREF(state->LtE_type); - if (PyModule_AddObject(m, "Gt", state->Gt_type) < 0) { + if (PyModule_AddObjectRef(m, "arg", state->arg_type) < 0) { return -1; } - Py_INCREF(state->Gt_type); - if (PyModule_AddObject(m, "GtE", state->GtE_type) < 0) { + if (PyModule_AddObjectRef(m, "keyword", state->keyword_type) < 0) { return -1; } - Py_INCREF(state->GtE_type); - if (PyModule_AddObject(m, "Is", state->Is_type) < 0) { + if (PyModule_AddObjectRef(m, "alias", state->alias_type) < 0) { return -1; } - Py_INCREF(state->Is_type); - if (PyModule_AddObject(m, "IsNot", state->IsNot_type) < 0) { + if (PyModule_AddObjectRef(m, "withitem", state->withitem_type) < 0) { return -1; } - Py_INCREF(state->IsNot_type); - if (PyModule_AddObject(m, "In", state->In_type) < 0) { + if (PyModule_AddObjectRef(m, "match_case", state->match_case_type) < 0) { return -1; } - Py_INCREF(state->In_type); - if (PyModule_AddObject(m, "NotIn", state->NotIn_type) < 0) { + if (PyModule_AddObjectRef(m, "pattern", state->pattern_type) < 0) { return -1; } - Py_INCREF(state->NotIn_type); - if (PyModule_AddObject(m, "comprehension", state->comprehension_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchValue", state->MatchValue_type) < 0) { return -1; } - Py_INCREF(state->comprehension_type); - if (PyModule_AddObject(m, "excepthandler", state->excepthandler_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchSingleton", state->MatchSingleton_type) + < 0) { return -1; } - Py_INCREF(state->excepthandler_type); - if (PyModule_AddObject(m, "ExceptHandler", state->ExceptHandler_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchSequence", state->MatchSequence_type) < + 0) { return -1; } - Py_INCREF(state->ExceptHandler_type); - if (PyModule_AddObject(m, "arguments", state->arguments_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchMapping", state->MatchMapping_type) < 0) + { return -1; } - Py_INCREF(state->arguments_type); - if (PyModule_AddObject(m, "arg", state->arg_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchClass", state->MatchClass_type) < 0) { return -1; } - Py_INCREF(state->arg_type); - if (PyModule_AddObject(m, "keyword", state->keyword_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchStar", state->MatchStar_type) < 0) { return -1; } - Py_INCREF(state->keyword_type); - if (PyModule_AddObject(m, "alias", state->alias_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchAs", state->MatchAs_type) < 0) { return -1; } - Py_INCREF(state->alias_type); - if (PyModule_AddObject(m, "withitem", state->withitem_type) < 0) { + if (PyModule_AddObjectRef(m, "MatchOr", state->MatchOr_type) < 0) { return -1; } - Py_INCREF(state->withitem_type); - if (PyModule_AddObject(m, "type_ignore", state->type_ignore_type) < 0) { + if (PyModule_AddObjectRef(m, "type_ignore", state->type_ignore_type) < 0) { return -1; } - Py_INCREF(state->type_ignore_type); - if (PyModule_AddObject(m, "TypeIgnore", state->TypeIgnore_type) < 0) { + if (PyModule_AddObjectRef(m, "TypeIgnore", state->TypeIgnore_type) < 0) { return -1; } - Py_INCREF(state->TypeIgnore_type); return 0; } @@ -10787,7 +11986,7 @@ static PyModuleDef_Slot astmodule_slots[] = { static struct PyModuleDef _astmodule = { PyModuleDef_HEAD_INIT, .m_name = "_ast", - // The _ast module uses a global state (global_ast_state). + // The _ast module uses a per-interpreter state (PyInterpreterState.ast) .m_size = 0, .m_slots = astmodule_slots, }; @@ -10801,7 +12000,7 @@ PyInit__ast(void) PyObject* PyAST_mod2obj(mod_ty t) { - astmodulestate *state = get_global_ast_state(); + struct ast_state *state = get_ast_state(); if (state == NULL) { return NULL; } @@ -10818,7 +12017,11 @@ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) return NULL; } - astmodulestate *state = get_global_ast_state(); + struct ast_state *state = get_ast_state(); + if (state == NULL) { + return NULL; + } + PyObject *req_type[3]; req_type[0] = state->Module_type; req_type[1] = state->Expression_type; @@ -10844,7 +12047,7 @@ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) int PyAST_Check(PyObject* obj) { - astmodulestate *state = get_global_ast_state(); + struct ast_state *state = get_ast_state(); if (state == NULL) { return -1; } diff --git a/contrib/tools/python3/src/Python/_warnings.c b/contrib/tools/python3/src/Python/_warnings.c index 91a78fe72b3..2c9a2a76872 100644 --- a/contrib/tools/python3/src/Python/_warnings.c +++ b/contrib/tools/python3/src/Python/_warnings.c @@ -1,6 +1,7 @@ #include "Python.h" #include "pycore_initconfig.h" #include "pycore_interp.h" // PyInterpreterState.warnings +#include "pycore_long.h" // _PyLong_GetZero() #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() #include "frameobject.h" // PyFrame_GetBack() @@ -23,23 +24,20 @@ _Py_IDENTIFIER(ignore); typedef struct _warnings_runtime_state WarningsState; -/* Forward declaration of the _warnings module definition. */ -static struct PyModuleDef warningsmodule; - _Py_IDENTIFIER(__name__); /* Given a module object, get its per-module state. */ static WarningsState * warnings_get_state(void) { - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "warnings_get_state: could not identify " - "current interpreter"); + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (interp == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "warnings_get_state: could not identify " + "current interpreter"); return NULL; } - return &tstate->interp->warnings; + return &interp->warnings; } /* Clear the given warnings module state. */ @@ -68,13 +66,12 @@ create_filter(PyObject *category, _Py_Identifier *id, const char *modname) return NULL; } } else { - modname_obj = Py_None; - Py_INCREF(modname_obj); + modname_obj = Py_NewRef(Py_None); } /* This assumes the line number is zero for now. */ PyObject *filter = PyTuple_Pack(5, action_str, Py_None, - category, modname_obj, _PyLong_Zero); + category, modname_obj, _PyLong_GetZero()); Py_DECREF(modname_obj); return filter; } @@ -116,37 +113,34 @@ init_filters(void) } /* Initialize the given warnings module state. */ -static int -warnings_init_state(WarningsState *st) +int +_PyWarnings_InitState(PyInterpreterState *interp) { + WarningsState *st = &interp->warnings; + if (st->filters == NULL) { st->filters = init_filters(); if (st->filters == NULL) { - goto error; + return -1; } } if (st->once_registry == NULL) { st->once_registry = PyDict_New(); if (st->once_registry == NULL) { - goto error; + return -1; } } if (st->default_action == NULL) { st->default_action = PyUnicode_FromString("default"); if (st->default_action == NULL) { - goto error; + return -1; } } st->filters_version = 0; - return 0; - -error: - warnings_clear_state(st); - return -1; } @@ -475,7 +469,7 @@ update_registry(PyObject *registry, PyObject *text, PyObject *category, int rc; if (add_zero) - altkey = PyTuple_Pack(3, text, category, _PyLong_Zero); + altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero()); else altkey = PyTuple_Pack(2, text, category); @@ -854,7 +848,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, } if (f == NULL) { - globals = _PyInterpreterState_GET()->sysdict; + globals = tstate->interp->sysdict; *filename = PyUnicode_FromString("sys"); *lineno = 1; } @@ -1356,70 +1350,45 @@ static PyMethodDef warnings_functions[] = { }; -static struct PyModuleDef warningsmodule = { - PyModuleDef_HEAD_INIT, - MODULE_NAME, /* m_name */ - warnings__doc__, /* m_doc */ - 0, /* m_size */ - warnings_functions, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; - - -PyStatus -_PyWarnings_InitState(PyThreadState *tstate) -{ - if (warnings_init_state(&tstate->interp->warnings) < 0) { - return _PyStatus_ERR("can't initialize warnings"); - } - return _PyStatus_OK(); -} - - -PyMODINIT_FUNC -_PyWarnings_Init(void) +static int +warnings_module_exec(PyObject *module) { - PyObject *m; - - m = PyModule_Create(&warningsmodule); - if (m == NULL) { - return NULL; - } - WarningsState *st = warnings_get_state(); if (st == NULL) { - goto error; + return -1; } - if (warnings_init_state(st) < 0) { - goto error; + if (PyModule_AddObjectRef(module, "filters", st->filters) < 0) { + return -1; } - - Py_INCREF(st->filters); - if (PyModule_AddObject(m, "filters", st->filters) < 0) { - goto error; + if (PyModule_AddObjectRef(module, "_onceregistry", st->once_registry) < 0) { + return -1; } - - Py_INCREF(st->once_registry); - if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) { - goto error; + if (PyModule_AddObjectRef(module, "_defaultaction", st->default_action) < 0) { + return -1; } + return 0; +} - Py_INCREF(st->default_action); - if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) { - goto error; - } - return m; +static PyModuleDef_Slot warnings_slots[] = { + {Py_mod_exec, warnings_module_exec}, + {0, NULL} +}; -error: - if (st != NULL) { - warnings_clear_state(st); - } - Py_DECREF(m); - return NULL; +static struct PyModuleDef warnings_module = { + PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = warnings__doc__, + .m_size = 0, + .m_methods = warnings_functions, + .m_slots = warnings_slots, +}; + + +PyMODINIT_FUNC +_PyWarnings_Init(void) +{ + return PyModuleDef_Init(&warnings_module); } // We need this to ensure that warnings still work until late in finalization. diff --git a/contrib/tools/python3/src/Python/asdl.c b/contrib/tools/python3/src/Python/asdl.c index c2110781181..a7f2180c88e 100644 --- a/contrib/tools/python3/src/Python/asdl.c +++ b/contrib/tools/python3/src/Python/asdl.c @@ -1,64 +1,6 @@ #include "Python.h" -#include "asdl.h" +#include "pycore_asdl.h" -asdl_seq * -_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena) -{ - asdl_seq *seq = NULL; - size_t n; - - /* check size is sane */ - if (size < 0 || - (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { - PyErr_NoMemory(); - return NULL; - } - n = (size ? (sizeof(void *) * (size - 1)) : 0); - - /* check if size can be added safely */ - if (n > SIZE_MAX - sizeof(asdl_seq)) { - PyErr_NoMemory(); - return NULL; - } - n += sizeof(asdl_seq); - - seq = (asdl_seq *)PyArena_Malloc(arena, n); - if (!seq) { - PyErr_NoMemory(); - return NULL; - } - memset(seq, 0, n); - seq->size = size; - return seq; -} - -asdl_int_seq * -_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena) -{ - asdl_int_seq *seq = NULL; - size_t n; - - /* check size is sane */ - if (size < 0 || - (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { - PyErr_NoMemory(); - return NULL; - } - n = (size ? (sizeof(void *) * (size - 1)) : 0); - - /* check if size can be added safely */ - if (n > SIZE_MAX - sizeof(asdl_seq)) { - PyErr_NoMemory(); - return NULL; - } - n += sizeof(asdl_seq); - - seq = (asdl_int_seq *)PyArena_Malloc(arena, n); - if (!seq) { - PyErr_NoMemory(); - return NULL; - } - memset(seq, 0, n); - seq->size = size; - return seq; -} +GENERATE_ASDL_SEQ_CONSTRUCTOR(generic, void*); +GENERATE_ASDL_SEQ_CONSTRUCTOR(identifier, PyObject*); +GENERATE_ASDL_SEQ_CONSTRUCTOR(int, int); diff --git a/contrib/tools/python3/src/Python/ast.c b/contrib/tools/python3/src/Python/ast.c index 6dd70592631..2113124dbd5 100644 --- a/contrib/tools/python3/src/Python/ast.c +++ b/contrib/tools/python3/src/Python/ast.c @@ -1,25 +1,26 @@ /* - * This file includes functions to transform a concrete syntax tree (CST) to - * an abstract syntax tree (AST). The main function is PyAST_FromNode(). - * + * This file exposes PyAST_Validate interface to check the integrity + * of the given abstract syntax tree (potentially constructed manually). */ #include "Python.h" -#include "Python-ast.h" -#include "node.h" -#include "ast.h" -#include "token.h" -#include "pythonrun.h" +#include "pycore_ast.h" // asdl_stmt_seq +#include "pycore_pystate.h" // _PyThreadState_GET() #include #include -#define MAXLEVEL 200 /* Max parentheses level */ +struct validator { + int recursion_depth; /* current recursion depth */ + int recursion_limit; /* recursion limit */ +}; -static int validate_stmts(asdl_seq *); -static int validate_exprs(asdl_seq *, expr_context_ty, int); -static int validate_nonempty_seq(asdl_seq *, const char *, const char *); -static int validate_stmt(stmt_ty); -static int validate_expr(expr_ty, expr_context_ty); +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_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_name(PyObject *name) @@ -33,7 +34,7 @@ validate_name(PyObject *name) }; for (int i = 0; forbidden[i] != NULL; i++) { if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) { - PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]); + PyErr_Format(PyExc_ValueError, "identifier field can't represent '%s' constant", forbidden[i]); return 0; } } @@ -41,7 +42,7 @@ validate_name(PyObject *name) } static int -validate_comprehension(asdl_seq *gens) +validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) { Py_ssize_t i; if (!asdl_seq_LEN(gens)) { @@ -50,31 +51,31 @@ validate_comprehension(asdl_seq *gens) } for (i = 0; i < asdl_seq_LEN(gens); i++) { comprehension_ty comp = asdl_seq_GET(gens, i); - if (!validate_expr(comp->target, Store) || - !validate_expr(comp->iter, Load) || - !validate_exprs(comp->ifs, Load, 0)) + if (!validate_expr(state, comp->target, Store) || + !validate_expr(state, comp->iter, Load) || + !validate_exprs(state, comp->ifs, Load, 0)) return 0; } return 1; } static int -validate_keywords(asdl_seq *keywords) +validate_keywords(struct validator *state, asdl_keyword_seq *keywords) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(keywords); i++) - if (!validate_expr(((keyword_ty)asdl_seq_GET(keywords, i))->value, Load)) + if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load)) return 0; return 1; } static int -validate_args(asdl_seq *args) +validate_args(struct validator *state, asdl_arg_seq *args) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = asdl_seq_GET(args, i); - if (arg->annotation && !validate_expr(arg->annotation, Load)) + if (arg->annotation && !validate_expr(state, arg->annotation, Load)) return 0; } return 1; @@ -90,25 +91,25 @@ expr_context_name(expr_context_ty ctx) return "Store"; case Del: return "Del"; - default: - Py_UNREACHABLE(); + // No default case so compiler emits warning for unhandled cases } + Py_UNREACHABLE(); } static int -validate_arguments(arguments_ty args) +validate_arguments(struct validator *state, arguments_ty args) { - if (!validate_args(args->posonlyargs) || !validate_args(args->args)) { + if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) { return 0; } if (args->vararg && args->vararg->annotation - && !validate_expr(args->vararg->annotation, Load)) { + && !validate_expr(state, args->vararg->annotation, Load)) { return 0; } - if (!validate_args(args->kwonlyargs)) + if (!validate_args(state, args->kwonlyargs)) return 0; if (args->kwarg && args->kwarg->annotation - && !validate_expr(args->kwarg->annotation, Load)) { + && !validate_expr(state, args->kwarg->annotation, Load)) { return 0; } if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) { @@ -120,11 +121,11 @@ validate_arguments(arguments_ty args) "kw_defaults on arguments"); return 0; } - return validate_exprs(args->defaults, Load, 0) && validate_exprs(args->kw_defaults, Load, 1); + return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1); } static int -validate_constant(PyObject *value) +validate_constant(struct validator *state, PyObject *value) { if (value == Py_None || value == Py_Ellipsis) return 1; @@ -138,9 +139,13 @@ validate_constant(PyObject *value) return 1; if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) { - PyObject *it; + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + return 0; + } - it = PyObject_GetIter(value); + PyObject *it = PyObject_GetIter(value); if (it == NULL) return 0; @@ -154,7 +159,7 @@ validate_constant(PyObject *value) break; } - if (!validate_constant(item)) { + if (!validate_constant(state, item)) { Py_DECREF(it); Py_DECREF(item); return 0; @@ -163,6 +168,7 @@ validate_constant(PyObject *value) } Py_DECREF(it); + --state->recursion_depth; return 1; } @@ -175,8 +181,14 @@ validate_constant(PyObject *value) } static int -validate_expr(expr_ty exp, expr_context_ty ctx) +validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) { + int ret = -1; + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + return 0; + } int check_ctx = 1; expr_context_ty actual_ctx; @@ -226,19 +238,24 @@ validate_expr(expr_ty exp, expr_context_ty ctx) PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values"); return 0; } - return validate_exprs(exp->v.BoolOp.values, Load, 0); + ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0); + break; case BinOp_kind: - return validate_expr(exp->v.BinOp.left, Load) && - validate_expr(exp->v.BinOp.right, Load); + ret = validate_expr(state, exp->v.BinOp.left, Load) && + validate_expr(state, exp->v.BinOp.right, Load); + break; case UnaryOp_kind: - return validate_expr(exp->v.UnaryOp.operand, Load); + ret = validate_expr(state, exp->v.UnaryOp.operand, Load); + break; case Lambda_kind: - return validate_arguments(exp->v.Lambda.args) && - validate_expr(exp->v.Lambda.body, Load); + ret = validate_arguments(state, exp->v.Lambda.args) && + validate_expr(state, exp->v.Lambda.body, Load); + break; case IfExp_kind: - return validate_expr(exp->v.IfExp.test, Load) && - validate_expr(exp->v.IfExp.body, Load) && - validate_expr(exp->v.IfExp.orelse, Load); + ret = validate_expr(state, exp->v.IfExp.test, Load) && + validate_expr(state, exp->v.IfExp.body, Load) && + validate_expr(state, exp->v.IfExp.orelse, Load); + break; case Dict_kind: if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) { PyErr_SetString(PyExc_ValueError, @@ -247,28 +264,35 @@ validate_expr(expr_ty exp, expr_context_ty ctx) } /* null_ok=1 for keys expressions to allow dict unpacking to work in dict literals, i.e. ``{**{a:b}}`` */ - return validate_exprs(exp->v.Dict.keys, Load, /*null_ok=*/ 1) && - validate_exprs(exp->v.Dict.values, Load, /*null_ok=*/ 0); + ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) && + validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0); + break; case Set_kind: - return validate_exprs(exp->v.Set.elts, Load, 0); + ret = validate_exprs(state, exp->v.Set.elts, Load, 0); + break; #define COMP(NAME) \ case NAME ## _kind: \ - return validate_comprehension(exp->v.NAME.generators) && \ - validate_expr(exp->v.NAME.elt, Load); + ret = validate_comprehension(state, exp->v.NAME.generators) && \ + validate_expr(state, exp->v.NAME.elt, Load); \ + break; COMP(ListComp) COMP(SetComp) COMP(GeneratorExp) #undef COMP case DictComp_kind: - return validate_comprehension(exp->v.DictComp.generators) && - validate_expr(exp->v.DictComp.key, Load) && - validate_expr(exp->v.DictComp.value, Load); + ret = validate_comprehension(state, exp->v.DictComp.generators) && + validate_expr(state, exp->v.DictComp.key, Load) && + validate_expr(state, exp->v.DictComp.value, Load); + break; case Yield_kind: - return !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load); + ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load); + break; case YieldFrom_kind: - return validate_expr(exp->v.YieldFrom.value, Load); + ret = validate_expr(state, exp->v.YieldFrom.value, Load); + break; case Await_kind: - return validate_expr(exp->v.Await.value, Load); + ret = validate_expr(state, exp->v.Await.value, Load); + break; case Compare_kind: if (!asdl_seq_LEN(exp->v.Compare.comparators)) { PyErr_SetString(PyExc_ValueError, "Compare with no comparators"); @@ -280,98 +304,411 @@ validate_expr(expr_ty exp, expr_context_ty ctx) "of comparators and operands"); return 0; } - return validate_exprs(exp->v.Compare.comparators, Load, 0) && - validate_expr(exp->v.Compare.left, Load); + ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) && + validate_expr(state, exp->v.Compare.left, Load); + break; case Call_kind: - return validate_expr(exp->v.Call.func, Load) && - validate_exprs(exp->v.Call.args, Load, 0) && - validate_keywords(exp->v.Call.keywords); + ret = validate_expr(state, exp->v.Call.func, Load) && + validate_exprs(state, exp->v.Call.args, Load, 0) && + validate_keywords(state, exp->v.Call.keywords); + break; case Constant_kind: - if (!validate_constant(exp->v.Constant.value)) { + if (!validate_constant(state, exp->v.Constant.value)) { return 0; } - return 1; + ret = 1; + break; case JoinedStr_kind: - return validate_exprs(exp->v.JoinedStr.values, Load, 0); + ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0); + break; case FormattedValue_kind: - if (validate_expr(exp->v.FormattedValue.value, Load) == 0) + if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0) return 0; - if (exp->v.FormattedValue.format_spec) - return validate_expr(exp->v.FormattedValue.format_spec, Load); - return 1; + if (exp->v.FormattedValue.format_spec) { + ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load); + break; + } + ret = 1; + break; case Attribute_kind: - return validate_expr(exp->v.Attribute.value, Load); + ret = validate_expr(state, exp->v.Attribute.value, Load); + break; case Subscript_kind: - return validate_expr(exp->v.Subscript.slice, Load) && - validate_expr(exp->v.Subscript.value, Load); + ret = validate_expr(state, exp->v.Subscript.slice, Load) && + validate_expr(state, exp->v.Subscript.value, Load); + break; case Starred_kind: - return validate_expr(exp->v.Starred.value, ctx); + ret = validate_expr(state, exp->v.Starred.value, ctx); + break; case Slice_kind: - return (!exp->v.Slice.lower || validate_expr(exp->v.Slice.lower, Load)) && - (!exp->v.Slice.upper || validate_expr(exp->v.Slice.upper, Load)) && - (!exp->v.Slice.step || validate_expr(exp->v.Slice.step, Load)); + ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) && + (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) && + (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load)); + break; case List_kind: - return validate_exprs(exp->v.List.elts, ctx, 0); + ret = validate_exprs(state, exp->v.List.elts, ctx, 0); + break; case Tuple_kind: - return validate_exprs(exp->v.Tuple.elts, ctx, 0); + ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0); + break; case NamedExpr_kind: - return validate_expr(exp->v.NamedExpr.value, Load); + ret = validate_expr(state, exp->v.NamedExpr.value, Load); + break; /* This last case doesn't have any checking. */ case Name_kind: - return 1; + ret = 1; + break; + // No default case so compiler emits warning for unhandled cases + } + if (ret < 0) { + PyErr_SetString(PyExc_SystemError, "unexpected expression"); + ret = 0; + } + state->recursion_depth--; + return ret; +} + + +// Note: the ensure_literal_* functions are only used to validate a restricted +// set of non-recursive literals that have already been checked with +// validate_expr, so they don't accept the validator state +static int +ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary) +{ + assert(exp->kind == Constant_kind); + PyObject *value = exp->v.Constant.value; + return (allow_real && PyFloat_CheckExact(value)) || + (allow_real && PyLong_CheckExact(value)) || + (allow_imaginary && PyComplex_CheckExact(value)); +} + +static int +ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary) +{ + assert(exp->kind == UnaryOp_kind); + // Must be negation ... + if (exp->v.UnaryOp.op != USub) { + return 0; + } + // ... of a constant ... + expr_ty operand = exp->v.UnaryOp.operand; + if (operand->kind != Constant_kind) { + return 0; + } + // ... number + return ensure_literal_number(operand, allow_real, allow_imaginary); +} + +static int +ensure_literal_complex(expr_ty exp) +{ + assert(exp->kind == BinOp_kind); + expr_ty left = exp->v.BinOp.left; + expr_ty right = exp->v.BinOp.right; + // Ensure op is addition or subtraction + if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) { + return 0; + } + // Check LHS is a real number (potentially signed) + switch (left->kind) + { + case Constant_kind: + if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) { + return 0; + } + break; + case UnaryOp_kind: + if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) { + return 0; + } + break; + default: + return 0; + } + // Check RHS is an imaginary number (no separate sign allowed) + switch (right->kind) + { + case Constant_kind: + if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) { + return 0; + } + break; + default: + return 0; + } + return 1; +} + +static int +validate_pattern_match_value(struct validator *state, expr_ty exp) +{ + if (!validate_expr(state, exp, Load)) { + return 0; + } + + switch (exp->kind) + { + case Constant_kind: + /* Ellipsis and immutable sequences are not allowed. + For True, False and None, MatchSingleton() should + be used */ + if (!validate_expr(state, exp, Load)) { + return 0; + } + PyObject *literal = exp->v.Constant.value; + if (PyLong_CheckExact(literal) || PyFloat_CheckExact(literal) || + PyBytes_CheckExact(literal) || PyComplex_CheckExact(literal) || + PyUnicode_CheckExact(literal)) { + return 1; + } + PyErr_SetString(PyExc_ValueError, + "unexpected constant inside of a literal pattern"); + return 0; + case Attribute_kind: + // Constants and attribute lookups are always permitted + return 1; + case UnaryOp_kind: + // Negated numbers are permitted (whether real or imaginary) + // Compiler will complain if AST folding doesn't create a constant + if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) { + return 1; + } + break; + case BinOp_kind: + // Complex literals are permitted + // Compiler will complain if AST folding doesn't create a constant + if (ensure_literal_complex(exp)) { + return 1; + } + break; + case JoinedStr_kind: + // Handled in the later stages + return 1; + default: + break; } - PyErr_SetString(PyExc_SystemError, "unexpected expression"); + PyErr_SetString(PyExc_ValueError, + "patterns may only match literals and attribute lookups"); return 0; } static int -validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) +validate_capture(PyObject *name) +{ + if (_PyUnicode_EqualToASCIIString(name, "_")) { + PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns"); + return 0; + } + return validate_name(name); +} + +static int +validate_pattern(struct validator *state, pattern_ty p, int star_ok) +{ + int ret = -1; + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + return 0; + } + switch (p->kind) { + case MatchValue_kind: + ret = validate_pattern_match_value(state, p->v.MatchValue.value); + break; + case MatchSingleton_kind: + ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value); + if (!ret) { + PyErr_SetString(PyExc_ValueError, + "MatchSingleton can only contain True, False and None"); + } + break; + case MatchSequence_kind: + ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1); + break; + case MatchMapping_kind: + if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) { + PyErr_SetString(PyExc_ValueError, + "MatchMapping doesn't have the same number of keys as patterns"); + ret = 0; + break; + } + + if (p->v.MatchMapping.rest && !validate_capture(p->v.MatchMapping.rest)) { + ret = 0; + break; + } + + asdl_expr_seq *keys = p->v.MatchMapping.keys; + for (Py_ssize_t i = 0; i < asdl_seq_LEN(keys); i++) { + expr_ty key = asdl_seq_GET(keys, i); + if (key->kind == Constant_kind) { + PyObject *literal = key->v.Constant.value; + if (literal == Py_None || PyBool_Check(literal)) { + /* validate_pattern_match_value will ensure the key + doesn't contain True, False and None but it is + syntactically valid, so we will pass those on in + a special case. */ + continue; + } + } + if (!validate_pattern_match_value(state, key)) { + ret = 0; + break; + } + } + + ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0); + break; + case MatchClass_kind: + if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) { + PyErr_SetString(PyExc_ValueError, + "MatchClass doesn't have the same number of keyword attributes as patterns"); + ret = 0; + break; + } + if (!validate_expr(state, p->v.MatchClass.cls, Load)) { + ret = 0; + break; + } + + expr_ty cls = p->v.MatchClass.cls; + while (1) { + if (cls->kind == Name_kind) { + break; + } + else if (cls->kind == Attribute_kind) { + cls = cls->v.Attribute.value; + continue; + } + else { + PyErr_SetString(PyExc_ValueError, + "MatchClass cls field can only contain Name or Attribute nodes."); + 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); + if (!validate_name(identifier)) { + ret = 0; + break; + } + } + + if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) { + ret = 0; + break; + } + + ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0); + break; + case MatchStar_kind: + if (!star_ok) { + PyErr_SetString(PyExc_ValueError, "can't use MatchStar here"); + ret = 0; + break; + } + ret = p->v.MatchStar.name == NULL || validate_capture(p->v.MatchStar.name); + break; + case MatchAs_kind: + if (p->v.MatchAs.name && !validate_capture(p->v.MatchAs.name)) { + ret = 0; + break; + } + if (p->v.MatchAs.pattern == NULL) { + ret = 1; + } + else if (p->v.MatchAs.name == NULL) { + PyErr_SetString(PyExc_ValueError, + "MatchAs must specify a target name if a pattern is given"); + ret = 0; + } + else { + ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0); + } + break; + case MatchOr_kind: + if (asdl_seq_LEN(p->v.MatchOr.patterns) < 2) { + PyErr_SetString(PyExc_ValueError, + "MatchOr requires at least 2 patterns"); + ret = 0; + break; + } + ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0); + break; + // No default case, so the compiler will emit a warning if new pattern + // kinds are added without being handled here + } + if (ret < 0) { + PyErr_SetString(PyExc_SystemError, "unexpected pattern"); + ret = 0; + } + state->recursion_depth--; + return ret; +} + +static int +_validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) { if (asdl_seq_LEN(seq)) return 1; PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner); return 0; } +#define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner) static int -validate_assignlist(asdl_seq *targets, expr_context_ty ctx) +validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx) { return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && - validate_exprs(targets, ctx, 0); + validate_exprs(state, targets, ctx, 0); } static int -validate_body(asdl_seq *body, const char *owner) +validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner) { - return validate_nonempty_seq(body, "body", owner) && validate_stmts(body); + return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body); } static int -validate_stmt(stmt_ty stmt) +validate_stmt(struct validator *state, stmt_ty 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"); + return 0; + } switch (stmt->kind) { case FunctionDef_kind: - return validate_body(stmt->v.FunctionDef.body, "FunctionDef") && - validate_arguments(stmt->v.FunctionDef.args) && - validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) && + ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") && + validate_arguments(state, stmt->v.FunctionDef.args) && + validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) && (!stmt->v.FunctionDef.returns || - validate_expr(stmt->v.FunctionDef.returns, Load)); + validate_expr(state, stmt->v.FunctionDef.returns, Load)); + break; case ClassDef_kind: - return validate_body(stmt->v.ClassDef.body, "ClassDef") && - validate_exprs(stmt->v.ClassDef.bases, Load, 0) && - validate_keywords(stmt->v.ClassDef.keywords) && - validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0); + ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") && + 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); + break; case Return_kind: - return !stmt->v.Return.value || validate_expr(stmt->v.Return.value, Load); + ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load); + break; case Delete_kind: - return validate_assignlist(stmt->v.Delete.targets, Del); + ret = validate_assignlist(state, stmt->v.Delete.targets, Del); + break; case Assign_kind: - return validate_assignlist(stmt->v.Assign.targets, Store) && - validate_expr(stmt->v.Assign.value, Load); + ret = validate_assignlist(state, stmt->v.Assign.targets, Store) && + validate_expr(state, stmt->v.Assign.value, Load); + break; case AugAssign_kind: - return validate_expr(stmt->v.AugAssign.target, Store) && - validate_expr(stmt->v.AugAssign.value, Load); + ret = validate_expr(state, stmt->v.AugAssign.target, Store) && + validate_expr(state, stmt->v.AugAssign.value, Load); + break; case AnnAssign_kind: if (stmt->v.AnnAssign.target->kind != Name_kind && stmt->v.AnnAssign.simple) { @@ -379,60 +716,84 @@ validate_stmt(stmt_ty stmt) "AnnAssign with simple non-Name target"); return 0; } - return validate_expr(stmt->v.AnnAssign.target, Store) && + ret = validate_expr(state, stmt->v.AnnAssign.target, Store) && (!stmt->v.AnnAssign.value || - validate_expr(stmt->v.AnnAssign.value, Load)) && - validate_expr(stmt->v.AnnAssign.annotation, Load); + validate_expr(state, stmt->v.AnnAssign.value, Load)) && + validate_expr(state, stmt->v.AnnAssign.annotation, Load); + break; case For_kind: - return validate_expr(stmt->v.For.target, Store) && - validate_expr(stmt->v.For.iter, Load) && - validate_body(stmt->v.For.body, "For") && - validate_stmts(stmt->v.For.orelse); + ret = validate_expr(state, stmt->v.For.target, Store) && + validate_expr(state, stmt->v.For.iter, Load) && + validate_body(state, stmt->v.For.body, "For") && + validate_stmts(state, stmt->v.For.orelse); + break; case AsyncFor_kind: - return validate_expr(stmt->v.AsyncFor.target, Store) && - validate_expr(stmt->v.AsyncFor.iter, Load) && - validate_body(stmt->v.AsyncFor.body, "AsyncFor") && - validate_stmts(stmt->v.AsyncFor.orelse); + ret = validate_expr(state, stmt->v.AsyncFor.target, Store) && + validate_expr(state, stmt->v.AsyncFor.iter, Load) && + validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") && + validate_stmts(state, stmt->v.AsyncFor.orelse); + break; case While_kind: - return validate_expr(stmt->v.While.test, Load) && - validate_body(stmt->v.While.body, "While") && - validate_stmts(stmt->v.While.orelse); + ret = validate_expr(state, stmt->v.While.test, Load) && + validate_body(state, stmt->v.While.body, "While") && + validate_stmts(state, stmt->v.While.orelse); + break; case If_kind: - return validate_expr(stmt->v.If.test, Load) && - validate_body(stmt->v.If.body, "If") && - validate_stmts(stmt->v.If.orelse); + ret = validate_expr(state, stmt->v.If.test, Load) && + validate_body(state, stmt->v.If.body, "If") && + validate_stmts(state, stmt->v.If.orelse); + break; 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++) { withitem_ty item = asdl_seq_GET(stmt->v.With.items, i); - if (!validate_expr(item->context_expr, Load) || - (item->optional_vars && !validate_expr(item->optional_vars, Store))) + if (!validate_expr(state, item->context_expr, Load) || + (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) return 0; } - return validate_body(stmt->v.With.body, "With"); + ret = validate_body(state, stmt->v.With.body, "With"); + break; 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++) { withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i); - if (!validate_expr(item->context_expr, Load) || - (item->optional_vars && !validate_expr(item->optional_vars, Store))) + if (!validate_expr(state, item->context_expr, Load) || + (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) + return 0; + } + ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith"); + break; + case Match_kind: + if (!validate_expr(state, stmt->v.Match.subject, Load) + || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) { + return 0; + } + for (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)) + || !validate_body(state, m->body, "match_case")) { return 0; + } } - return validate_body(stmt->v.AsyncWith.body, "AsyncWith"); + ret = 1; + break; case Raise_kind: if (stmt->v.Raise.exc) { - return validate_expr(stmt->v.Raise.exc, Load) && - (!stmt->v.Raise.cause || validate_expr(stmt->v.Raise.cause, Load)); + ret = validate_expr(state, stmt->v.Raise.exc, Load) && + (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load)); + break; } if (stmt->v.Raise.cause) { PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception"); return 0; } - return 1; + ret = 1; + break; case Try_kind: - if (!validate_body(stmt->v.Try.body, "Try")) + if (!validate_body(state, stmt->v.Try.body, "Try")) return 0; if (!asdl_seq_LEN(stmt->v.Try.handlers) && !asdl_seq_LEN(stmt->v.Try.finalbody)) { @@ -447,55 +808,68 @@ validate_stmt(stmt_ty stmt) for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) { excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); if ((handler->v.ExceptHandler.type && - !validate_expr(handler->v.ExceptHandler.type, Load)) || - !validate_body(handler->v.ExceptHandler.body, "ExceptHandler")) + !validate_expr(state, handler->v.ExceptHandler.type, Load)) || + !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) return 0; } - return (!asdl_seq_LEN(stmt->v.Try.finalbody) || - validate_stmts(stmt->v.Try.finalbody)) && + ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) || + validate_stmts(state, stmt->v.Try.finalbody)) && (!asdl_seq_LEN(stmt->v.Try.orelse) || - validate_stmts(stmt->v.Try.orelse)); + validate_stmts(state, stmt->v.Try.orelse)); + break; case Assert_kind: - return validate_expr(stmt->v.Assert.test, Load) && - (!stmt->v.Assert.msg || validate_expr(stmt->v.Assert.msg, Load)); + ret = validate_expr(state, stmt->v.Assert.test, Load) && + (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load)); + break; case Import_kind: - return validate_nonempty_seq(stmt->v.Import.names, "names", "Import"); + ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import"); + break; case ImportFrom_kind: if (stmt->v.ImportFrom.level < 0) { PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level"); return 0; } - return validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom"); + ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom"); + break; case Global_kind: - return validate_nonempty_seq(stmt->v.Global.names, "names", "Global"); + ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global"); + break; case Nonlocal_kind: - return validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal"); + ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal"); + break; case Expr_kind: - return validate_expr(stmt->v.Expr.value, Load); + ret = validate_expr(state, stmt->v.Expr.value, Load); + break; case AsyncFunctionDef_kind: - return validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && - validate_arguments(stmt->v.AsyncFunctionDef.args) && - validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && + ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && + validate_arguments(state, stmt->v.AsyncFunctionDef.args) && + validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && (!stmt->v.AsyncFunctionDef.returns || - validate_expr(stmt->v.AsyncFunctionDef.returns, Load)); + validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load)); + break; case Pass_kind: case Break_kind: case Continue_kind: - return 1; - default: + ret = 1; + break; + // No default case so compiler emits warning for unhandled cases + } + if (ret < 0) { PyErr_SetString(PyExc_SystemError, "unexpected statement"); - return 0; + ret = 0; } + state->recursion_depth--; + return ret; } static int -validate_stmts(asdl_seq *seq) +validate_stmts(struct validator *state, asdl_stmt_seq *seq) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(seq); i++) { stmt_ty stmt = asdl_seq_GET(seq, i); if (stmt) { - if (!validate_stmt(stmt)) + if (!validate_stmt(state, stmt)) return 0; } else { @@ -508,13 +882,13 @@ validate_stmts(asdl_seq *seq) } static int -validate_exprs(asdl_seq *exprs, expr_context_ty ctx, int null_ok) +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++) { expr_ty expr = asdl_seq_GET(exprs, i); if (expr) { - if (!validate_expr(expr, ctx)) + if (!validate_expr(state, expr, ctx)) return 0; } else if (!null_ok) { @@ -527,5326 +901,83 @@ validate_exprs(asdl_seq *exprs, expr_context_ty ctx, int null_ok) return 1; } +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++) { + pattern_ty pattern = asdl_seq_GET(patterns, i); + if (!validate_pattern(state, pattern, star_ok)) { + return 0; + } + } + return 1; +} + + +/* See comments in symtable.c. */ +#define COMPILER_STACK_FRAME_SCALE 3 + int -PyAST_Validate(mod_ty mod) +_PyAST_Validate(mod_ty mod) { - int res = 0; + int res = -1; + struct validator state; + PyThreadState *tstate; + int recursion_limit = Py_GetRecursionLimit(); + int starting_recursion_depth; + + /* Setup recursion depth check counters */ + tstate = _PyThreadState_GET(); + if (!tstate) { + return 0; + } + /* Be careful here to prevent overflow. */ + starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? + tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; + 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; switch (mod->kind) { case Module_kind: - res = validate_stmts(mod->v.Module.body); + res = validate_stmts(&state, mod->v.Module.body); break; case Interactive_kind: - res = validate_stmts(mod->v.Interactive.body); + res = validate_stmts(&state, mod->v.Interactive.body); break; case Expression_kind: - res = validate_expr(mod->v.Expression.body, Load); + res = validate_expr(&state, mod->v.Expression.body, Load); break; - default: - PyErr_SetString(PyExc_SystemError, "impossible module node"); - res = 0; + case FunctionType_kind: + res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) && + validate_expr(&state, mod->v.FunctionType.returns, Load); break; + // No default case so compiler emits warning for unhandled cases } - return res; -} - -/* This is done here, so defines like "test" don't interfere with AST use above. */ -#include "grammar.h" -#include "parsetok.h" -#include "graminit.h" - -/* Data structure used internally */ -struct compiling { - PyArena *c_arena; /* Arena for allocating memory. */ - PyObject *c_filename; /* filename */ - PyObject *c_normalize; /* Normalization function from unicodedata. */ - int c_feature_version; /* Latest minor version of Python for allowed features */ -}; - -static asdl_seq *seq_for_testlist(struct compiling *, const node *); -static expr_ty ast_for_expr(struct compiling *, const node *); -static stmt_ty ast_for_stmt(struct compiling *, const node *); -static asdl_seq *ast_for_suite(struct compiling *c, const node *n); -static asdl_seq *ast_for_exprlist(struct compiling *, const node *, - expr_context_ty); -static expr_ty ast_for_testlist(struct compiling *, const node *); -static stmt_ty ast_for_classdef(struct compiling *, const node *, asdl_seq *); - -static stmt_ty ast_for_with_stmt(struct compiling *, const node *, bool); -static stmt_ty ast_for_for_stmt(struct compiling *, const node *, bool); -/* Note different signature for ast_for_call */ -static expr_ty ast_for_call(struct compiling *, const node *, expr_ty, - const node *, const node *, const node *); - -static PyObject *parsenumber(struct compiling *, const char *); -static expr_ty parsestrplus(struct compiling *, const node *n); -static void get_last_end_pos(asdl_seq *, int *, int *); - -#define COMP_GENEXP 0 -#define COMP_LISTCOMP 1 -#define COMP_SETCOMP 2 - -static int -init_normalization(struct compiling *c) -{ - PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); - if (!m) - return 0; - c->c_normalize = PyObject_GetAttrString(m, "normalize"); - Py_DECREF(m); - if (!c->c_normalize) + if (res < 0) { + PyErr_SetString(PyExc_SystemError, "impossible module node"); return 0; - return 1; -} - -static identifier -new_identifier(const char *n, struct compiling *c) -{ - PyObject *id = PyUnicode_DecodeUTF8(n, strlen(n), NULL); - if (!id) - return NULL; - /* PyUnicode_DecodeUTF8 should always return a ready string. */ - assert(PyUnicode_IS_READY(id)); - /* Check whether there are non-ASCII characters in the - identifier; if so, normalize to NFKC. */ - if (!PyUnicode_IS_ASCII(id)) { - PyObject *id2; - if (!c->c_normalize && !init_normalization(c)) { - Py_DECREF(id); - return NULL; - } - PyObject *form = PyUnicode_InternFromString("NFKC"); - if (form == NULL) { - Py_DECREF(id); - return NULL; - } - PyObject *args[2] = {form, id}; - id2 = _PyObject_FastCall(c->c_normalize, args, 2); - Py_DECREF(id); - Py_DECREF(form); - if (!id2) - return NULL; - if (!PyUnicode_Check(id2)) { - PyErr_Format(PyExc_TypeError, - "unicodedata.normalize() must return a string, not " - "%.200s", - _PyType_Name(Py_TYPE(id2))); - Py_DECREF(id2); - return NULL; - } - id = id2; - } - PyUnicode_InternInPlace(&id); - if (PyArena_AddPyObject(c->c_arena, id) < 0) { - Py_DECREF(id); - return NULL; } - return id; -} - -#define NEW_IDENTIFIER(n) new_identifier(STR(n), c) - -static int -ast_error(struct compiling *c, const node *n, const char *errmsg, ...) -{ - PyObject *value, *errstr, *loc, *tmp; - va_list va; - va_start(va, errmsg); - errstr = PyUnicode_FromFormatV(errmsg, va); - va_end(va); - if (!errstr) { + /* Check that the recursion depth counting balanced correctly */ + if (res && state.recursion_depth != starting_recursion_depth) { + PyErr_Format(PyExc_SystemError, + "AST validator recursion depth mismatch (before=%d, after=%d)", + starting_recursion_depth, state.recursion_depth); return 0; } - loc = PyErr_ProgramTextObject(c->c_filename, LINENO(n)); - if (!loc) { - Py_INCREF(Py_None); - loc = Py_None; - } - tmp = Py_BuildValue("(OiiN)", c->c_filename, LINENO(n), n->n_col_offset + 1, loc); - if (!tmp) { - Py_DECREF(errstr); - return 0; - } - value = PyTuple_Pack(2, errstr, tmp); - Py_DECREF(errstr); - Py_DECREF(tmp); - if (value) { - PyErr_SetObject(PyExc_SyntaxError, value); - Py_DECREF(value); - } - return 0; -} - -/* num_stmts() returns number of contained statements. - - Use this routine to determine how big a sequence is needed for - the statements in a parse tree. Its raison d'etre is this bit of - grammar: - - stmt: simple_stmt | compound_stmt - simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE - - A simple_stmt can contain multiple small_stmt elements joined - by semicolons. If the arg is a simple_stmt, the number of - small_stmt elements is returned. -*/ - -static string -new_type_comment(const char *s, struct compiling *c) -{ - PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL); - if (res == NULL) - return NULL; - if (PyArena_AddPyObject(c->c_arena, res) < 0) { - Py_DECREF(res); - return NULL; - } - return res; -} -#define NEW_TYPE_COMMENT(n) new_type_comment(STR(n), c) - -static int -num_stmts(const node *n) -{ - int i, l; - node *ch; - - switch (TYPE(n)) { - case single_input: - if (TYPE(CHILD(n, 0)) == NEWLINE) - return 0; - else - return num_stmts(CHILD(n, 0)); - case file_input: - l = 0; - for (i = 0; i < NCH(n); i++) { - ch = CHILD(n, i); - if (TYPE(ch) == stmt) - l += num_stmts(ch); - } - return l; - case stmt: - return num_stmts(CHILD(n, 0)); - case compound_stmt: - return 1; - case simple_stmt: - return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */ - case suite: - case func_body_suite: - /* func_body_suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */ - /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */ - if (NCH(n) == 1) - return num_stmts(CHILD(n, 0)); - else { - i = 2; - l = 0; - if (TYPE(CHILD(n, 1)) == TYPE_COMMENT) - i += 2; - for (; i < (NCH(n) - 1); i++) - l += num_stmts(CHILD(n, i)); - return l; - } - default: { - _Py_FatalErrorFormat(__func__, "Non-statement found: %d %d", - TYPE(n), NCH(n)); - } - } - Py_UNREACHABLE(); -} - -/* Transform the CST rooted at node * to the appropriate AST -*/ - -mod_ty -PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags, - PyObject *filename, PyArena *arena) -{ - int i, j, k, num; - asdl_seq *stmts = NULL; - asdl_seq *type_ignores = NULL; - stmt_ty s; - node *ch; - struct compiling c; - mod_ty res = NULL; - asdl_seq *argtypes = NULL; - expr_ty ret, arg; - - c.c_arena = arena; - /* borrowed reference */ - c.c_filename = filename; - c.c_normalize = NULL; - c.c_feature_version = flags && (flags->cf_flags & PyCF_ONLY_AST) ? - flags->cf_feature_version : PY_MINOR_VERSION; - - if (TYPE(n) == encoding_decl) - n = CHILD(n, 0); - - k = 0; - switch (TYPE(n)) { - case file_input: - stmts = _Py_asdl_seq_new(num_stmts(n), arena); - if (!stmts) - goto out; - for (i = 0; i < NCH(n) - 1; i++) { - ch = CHILD(n, i); - if (TYPE(ch) == NEWLINE) - continue; - REQ(ch, stmt); - num = num_stmts(ch); - if (num == 1) { - s = ast_for_stmt(&c, ch); - if (!s) - goto out; - asdl_seq_SET(stmts, k++, s); - } - else { - ch = CHILD(ch, 0); - REQ(ch, simple_stmt); - for (j = 0; j < num; j++) { - s = ast_for_stmt(&c, CHILD(ch, j * 2)); - if (!s) - goto out; - asdl_seq_SET(stmts, k++, s); - } - } - } - - /* Type ignores are stored under the ENDMARKER in file_input. */ - ch = CHILD(n, NCH(n) - 1); - REQ(ch, ENDMARKER); - num = NCH(ch); - type_ignores = _Py_asdl_seq_new(num, arena); - if (!type_ignores) - goto out; - - for (i = 0; i < num; i++) { - string type_comment = new_type_comment(STR(CHILD(ch, i)), &c); - if (!type_comment) - goto out; - type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), type_comment, arena); - if (!ti) - goto out; - asdl_seq_SET(type_ignores, i, ti); - } - - res = Module(stmts, type_ignores, arena); - break; - case eval_input: { - expr_ty testlist_ast; - - /* XXX Why not comp_for here? */ - testlist_ast = ast_for_testlist(&c, CHILD(n, 0)); - if (!testlist_ast) - goto out; - res = Expression(testlist_ast, arena); - break; - } - case single_input: - if (TYPE(CHILD(n, 0)) == NEWLINE) { - stmts = _Py_asdl_seq_new(1, arena); - if (!stmts) - goto out; - asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - arena)); - if (!asdl_seq_GET(stmts, 0)) - goto out; - res = Interactive(stmts, arena); - } - else { - n = CHILD(n, 0); - num = num_stmts(n); - stmts = _Py_asdl_seq_new(num, arena); - if (!stmts) - goto out; - if (num == 1) { - s = ast_for_stmt(&c, n); - if (!s) - goto out; - asdl_seq_SET(stmts, 0, s); - } - else { - /* Only a simple_stmt can contain multiple statements. */ - REQ(n, simple_stmt); - for (i = 0; i < NCH(n); i += 2) { - if (TYPE(CHILD(n, i)) == NEWLINE) - break; - s = ast_for_stmt(&c, CHILD(n, i)); - if (!s) - goto out; - asdl_seq_SET(stmts, i / 2, s); - } - } - - res = Interactive(stmts, arena); - } - break; - case func_type_input: - n = CHILD(n, 0); - REQ(n, func_type); - - if (TYPE(CHILD(n, 1)) == typelist) { - ch = CHILD(n, 1); - /* this is overly permissive -- we don't pay any attention to - * stars on the args -- just parse them into an ordered list */ - num = 0; - for (i = 0; i < NCH(ch); i++) { - if (TYPE(CHILD(ch, i)) == test) { - num++; - } - } - - argtypes = _Py_asdl_seq_new(num, arena); - if (!argtypes) - goto out; - - j = 0; - for (i = 0; i < NCH(ch); i++) { - if (TYPE(CHILD(ch, i)) == test) { - arg = ast_for_expr(&c, CHILD(ch, i)); - if (!arg) - goto out; - asdl_seq_SET(argtypes, j++, arg); - } - } - } - else { - argtypes = _Py_asdl_seq_new(0, arena); - if (!argtypes) - goto out; - } - - ret = ast_for_expr(&c, CHILD(n, NCH(n) - 1)); - if (!ret) - goto out; - res = FunctionType(argtypes, ret, arena); - break; - default: - PyErr_Format(PyExc_SystemError, - "invalid node %d for PyAST_FromNode", TYPE(n)); - goto out; - } - out: - if (c.c_normalize) { - Py_DECREF(c.c_normalize); - } return res; } -mod_ty -PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename_str, - PyArena *arena) -{ - mod_ty mod; - PyObject *filename; - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - mod = PyAST_FromNodeObject(n, flags, filename, arena); - Py_DECREF(filename); - return mod; - -} - -/* Return the AST repr. of the operator represented as syntax (|, ^, etc.) -*/ - -static operator_ty -get_operator(struct compiling *c, const node *n) -{ - switch (TYPE(n)) { - case VBAR: - return BitOr; - case CIRCUMFLEX: - return BitXor; - case AMPER: - return BitAnd; - case LEFTSHIFT: - return LShift; - case RIGHTSHIFT: - return RShift; - case PLUS: - return Add; - case MINUS: - return Sub; - case STAR: - return Mult; - case AT: - if (c->c_feature_version < 5) { - ast_error(c, n, - "The '@' operator is only supported in Python 3.5 and greater"); - return (operator_ty)0; - } - return MatMult; - case SLASH: - return Div; - case DOUBLESLASH: - return FloorDiv; - case PERCENT: - return Mod; - default: - return (operator_ty)0; - } -} - -static const char * const FORBIDDEN[] = { - "None", - "True", - "False", - "__debug__", - NULL, -}; - -static int -forbidden_name(struct compiling *c, identifier name, const node *n, - int full_checks) -{ - assert(PyUnicode_Check(name)); - const char * const *p = FORBIDDEN; - if (!full_checks) { - /* In most cases, the parser will protect True, False, and None - from being assign to. */ - p += 3; - } - for (; *p; p++) { - if (_PyUnicode_EqualToASCIIString(name, *p)) { - ast_error(c, n, "cannot assign to %U", name); - return 1; - } - } - return 0; -} - -static expr_ty -copy_location(expr_ty e, const node *n, const node *end) -{ - if (e) { - e->lineno = LINENO(n); - e->col_offset = n->n_col_offset; - e->end_lineno = end->n_end_lineno; - e->end_col_offset = end->n_end_col_offset; - } - return e; -} - -static const char * -get_expr_name(expr_ty e) -{ - switch (e->kind) { - case Attribute_kind: - return "attribute"; - case Subscript_kind: - return "subscript"; - case Starred_kind: - return "starred"; - case Name_kind: - return "name"; - case List_kind: - return "list"; - case Tuple_kind: - return "tuple"; - case Lambda_kind: - return "lambda"; - case Call_kind: - return "function call"; - case BoolOp_kind: - case BinOp_kind: - case UnaryOp_kind: - return "operator"; - case GeneratorExp_kind: - return "generator expression"; - case Yield_kind: - case YieldFrom_kind: - return "yield expression"; - case Await_kind: - return "await expression"; - case ListComp_kind: - return "list comprehension"; - case SetComp_kind: - return "set comprehension"; - case DictComp_kind: - return "dict comprehension"; - case Dict_kind: - return "dict display"; - case Set_kind: - return "set display"; - case JoinedStr_kind: - case FormattedValue_kind: - return "f-string expression"; - case Constant_kind: { - PyObject *value = e->v.Constant.value; - if (value == Py_None) { - return "None"; - } - if (value == Py_False) { - return "False"; - } - if (value == Py_True) { - return "True"; - } - if (value == Py_Ellipsis) { - return "Ellipsis"; - } - return "literal"; - } - case Compare_kind: - return "comparison"; - case IfExp_kind: - return "conditional expression"; - case NamedExpr_kind: - return "named expression"; - default: - PyErr_Format(PyExc_SystemError, - "unexpected expression in assignment %d (line %d)", - e->kind, e->lineno); - return NULL; - } -} - -/* Set the context ctx for expr_ty e, recursively traversing e. - - Only sets context for expr kinds that "can appear in assignment context" - (according to ../Parser/Python.asdl). For other expr kinds, it sets - an appropriate syntax error and returns false. -*/ - -static int -set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) -{ - asdl_seq *s = NULL; - - /* Expressions in an augmented assignment have a Store context. */ - - switch (e->kind) { - case Attribute_kind: - e->v.Attribute.ctx = ctx; - if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1)) - return 0; - break; - case Subscript_kind: - e->v.Subscript.ctx = ctx; - break; - case Starred_kind: - e->v.Starred.ctx = ctx; - if (!set_context(c, e->v.Starred.value, ctx, n)) - return 0; - break; - case Name_kind: - if (ctx == Store) { - if (forbidden_name(c, e->v.Name.id, n, 0)) - return 0; /* forbidden_name() calls ast_error() */ - } - e->v.Name.ctx = ctx; - break; - case List_kind: - e->v.List.ctx = ctx; - s = e->v.List.elts; - break; - case Tuple_kind: - e->v.Tuple.ctx = ctx; - s = e->v.Tuple.elts; - break; - default: { - const char *expr_name = get_expr_name(e); - if (expr_name != NULL) { - ast_error(c, n, "cannot %s %s", - ctx == Store ? "assign to" : "delete", - expr_name); - } - return 0; - } - } - - /* If the LHS is a list or tuple, we need to set the assignment - context for all the contained elements. - */ - if (s) { - Py_ssize_t i; - - for (i = 0; i < asdl_seq_LEN(s); i++) { - if (!set_context(c, (expr_ty)asdl_seq_GET(s, i), ctx, n)) - return 0; - } - } - return 1; -} - -static operator_ty -ast_for_augassign(struct compiling *c, const node *n) -{ - REQ(n, augassign); - n = CHILD(n, 0); - switch (STR(n)[0]) { - case '+': - return Add; - case '-': - return Sub; - case '/': - if (STR(n)[1] == '/') - return FloorDiv; - else - return Div; - case '%': - return Mod; - case '<': - return LShift; - case '>': - return RShift; - case '&': - return BitAnd; - case '^': - return BitXor; - case '|': - return BitOr; - case '*': - if (STR(n)[1] == '*') - return Pow; - else - return Mult; - case '@': - if (c->c_feature_version < 5) { - ast_error(c, n, - "The '@' operator is only supported in Python 3.5 and greater"); - return (operator_ty)0; - } - return MatMult; - default: - PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n)); - return (operator_ty)0; - } -} - -static cmpop_ty -ast_for_comp_op(struct compiling *c, const node *n) -{ - /* comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is' - |'is' 'not' - */ - REQ(n, comp_op); - if (NCH(n) == 1) { - n = CHILD(n, 0); - switch (TYPE(n)) { - case LESS: - return Lt; - case GREATER: - return Gt; - case EQEQUAL: /* == */ - return Eq; - case LESSEQUAL: - return LtE; - case GREATEREQUAL: - return GtE; - case NOTEQUAL: - return NotEq; - case NAME: - if (strcmp(STR(n), "in") == 0) - return In; - if (strcmp(STR(n), "is") == 0) - return Is; - /* fall through */ - default: - PyErr_Format(PyExc_SystemError, "invalid comp_op: %s", - STR(n)); - return (cmpop_ty)0; - } - } - else if (NCH(n) == 2) { - /* handle "not in" and "is not" */ - switch (TYPE(CHILD(n, 0))) { - case NAME: - if (strcmp(STR(CHILD(n, 1)), "in") == 0) - return NotIn; - if (strcmp(STR(CHILD(n, 0)), "is") == 0) - return IsNot; - /* fall through */ - default: - PyErr_Format(PyExc_SystemError, "invalid comp_op: %s %s", - STR(CHILD(n, 0)), STR(CHILD(n, 1))); - return (cmpop_ty)0; - } - } - PyErr_Format(PyExc_SystemError, "invalid comp_op: has %d children", - NCH(n)); - return (cmpop_ty)0; -} - -static asdl_seq * -seq_for_testlist(struct compiling *c, const node *n) -{ - /* testlist: test (',' test)* [','] - testlist_star_expr: test|star_expr (',' test|star_expr)* [','] - */ - asdl_seq *seq; - expr_ty expression; - int i; - assert(TYPE(n) == testlist || TYPE(n) == testlist_star_expr || TYPE(n) == testlist_comp); - - seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); - if (!seq) - return NULL; - - for (i = 0; i < NCH(n); i += 2) { - const node *ch = CHILD(n, i); - assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr || TYPE(ch) == namedexpr_test); - - expression = ast_for_expr(c, ch); - if (!expression) - return NULL; - - assert(i / 2 < seq->size); - asdl_seq_SET(seq, i / 2, expression); - } - return seq; -} - -static arg_ty -ast_for_arg(struct compiling *c, const node *n) -{ - identifier name; - expr_ty annotation = NULL; - node *ch; - arg_ty ret; - - assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef); - ch = CHILD(n, 0); - name = NEW_IDENTIFIER(ch); - if (!name) - return NULL; - if (forbidden_name(c, name, ch, 0)) - return NULL; - - if (NCH(n) == 3 && TYPE(CHILD(n, 1)) == COLON) { - annotation = ast_for_expr(c, CHILD(n, 2)); - if (!annotation) - return NULL; - } - - ret = arg(name, annotation, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - if (!ret) - return NULL; - return ret; -} - -/* returns -1 if failed to handle keyword only arguments - returns new position to keep processing if successful - (',' tfpdef ['=' test])* - ^^^ - start pointing here - */ -static int -handle_keywordonly_args(struct compiling *c, const node *n, int start, - asdl_seq *kwonlyargs, asdl_seq *kwdefaults) -{ - PyObject *argname; - node *ch; - expr_ty expression, annotation; - arg_ty arg = NULL; - int i = start; - int j = 0; /* index for kwdefaults and kwonlyargs */ - - if (kwonlyargs == NULL) { - ast_error(c, CHILD(n, start), "named arguments must follow bare *"); - return -1; - } - assert(kwdefaults != NULL); - while (i < NCH(n)) { - ch = CHILD(n, i); - switch (TYPE(ch)) { - case vfpdef: - case tfpdef: - if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { - expression = ast_for_expr(c, CHILD(n, i + 2)); - if (!expression) - goto error; - asdl_seq_SET(kwdefaults, j, expression); - i += 2; /* '=' and test */ - } - else { /* setting NULL if no default value exists */ - asdl_seq_SET(kwdefaults, j, NULL); - } - if (NCH(ch) == 3) { - /* ch is NAME ':' test */ - annotation = ast_for_expr(c, CHILD(ch, 2)); - if (!annotation) - goto error; - } - else { - annotation = NULL; - } - ch = CHILD(ch, 0); - argname = NEW_IDENTIFIER(ch); - if (!argname) - goto error; - if (forbidden_name(c, argname, ch, 0)) - goto error; - arg = arg(argname, annotation, NULL, LINENO(ch), ch->n_col_offset, - ch->n_end_lineno, ch->n_end_col_offset, - c->c_arena); - if (!arg) - goto error; - asdl_seq_SET(kwonlyargs, j++, arg); - i += 1; /* the name */ - if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) - i += 1; /* the comma, if present */ - break; - case TYPE_COMMENT: - /* arg will be equal to the last argument processed */ - arg->type_comment = NEW_TYPE_COMMENT(ch); - if (!arg->type_comment) - goto error; - i += 1; - break; - case DOUBLESTAR: - return i; - default: - ast_error(c, ch, "unexpected node"); - goto error; - } - } - return i; - error: - return -1; -} - -/* Create AST for argument list. */ - -static arguments_ty -ast_for_arguments(struct compiling *c, const node *n) -{ - /* This function handles both typedargslist (function definition) - and varargslist (lambda definition). - - parameters: '(' [typedargslist] ')' - - The following definition for typedarglist is equivalent to this set of rules: - - arguments = argument (',' [TYPE_COMMENT] argument)* - argument = tfpdef ['=' test] - kwargs = '**' tfpdef [','] [TYPE_COMMENT] - args = '*' [tfpdef] - kwonly_kwargs = (',' [TYPE_COMMENT] argument)* (TYPE_COMMENT | [',' - [TYPE_COMMENT] [kwargs]]) - args_kwonly_kwargs = args kwonly_kwargs | kwargs - poskeyword_args_kwonly_kwargs = arguments ( TYPE_COMMENT | [',' - [TYPE_COMMENT] [args_kwonly_kwargs]]) - typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs - typedarglist = (arguments ',' [TYPE_COMMENT] '/' [',' [[TYPE_COMMENT] - typedargslist_no_posonly]])|(typedargslist_no_posonly)" - - typedargslist: ( (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])* - ',' [TYPE_COMMENT] '/' [',' [ [TYPE_COMMENT] tfpdef ['=' test] ( ',' - [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*' - [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' - [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] - [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* - (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | - '**' tfpdef [','] [TYPE_COMMENT]]] ) | (tfpdef ['=' test] (',' - [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*' - [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' - [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] - [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* - (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | - '**' tfpdef [','] [TYPE_COMMENT])) - - tfpdef: NAME [':' test] - - The following definition for varargslist is equivalent to this set of rules: - - arguments = argument (',' argument )* - argument = vfpdef ['=' test] - kwargs = '**' vfpdef [','] - args = '*' [vfpdef] - kwonly_kwargs = (',' argument )* [',' [kwargs]] - args_kwonly_kwargs = args kwonly_kwargs | kwargs - poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]] - vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs - varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | - (vararglist_no_posonly) - - varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ (vfpdef ['=' - test] (',' vfpdef ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' - ['**' vfpdef [',']]] | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* - [',' ['**' vfpdef [',']]] | '**' vfpdef [',']) ]] | (vfpdef ['=' test] (',' vfpdef - ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] - | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef - [',']]] | '**' vfpdef [',']) - - vfpdef: NAME - - */ - int i, j, k, l, nposonlyargs=0, nposargs = 0, nkwonlyargs = 0; - int nposdefaults = 0, found_default = 0; - asdl_seq *posonlyargs, *posargs, *posdefaults, *kwonlyargs, *kwdefaults; - arg_ty vararg = NULL, kwarg = NULL; - arg_ty arg = NULL; - node *ch; - - if (TYPE(n) == parameters) { - if (NCH(n) == 2) /* () as argument list */ - return arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); - n = CHILD(n, 1); - } - assert(TYPE(n) == typedargslist || TYPE(n) == varargslist); - - /* First count the number of positional args & defaults. The - variable i is the loop index for this for loop and the next. - The next loop picks up where the first leaves off. - */ - for (i = 0; i < NCH(n); i++) { - ch = CHILD(n, i); - if (TYPE(ch) == STAR) { - /* skip star */ - i++; - if (i < NCH(n) && /* skip argument following star */ - (TYPE(CHILD(n, i)) == tfpdef || - TYPE(CHILD(n, i)) == vfpdef)) { - i++; - } - break; - } - if (TYPE(ch) == DOUBLESTAR) break; - if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++; - if (TYPE(ch) == EQUAL) nposdefaults++; - if (TYPE(ch) == SLASH ) { - nposonlyargs = nposargs; - nposargs = 0; - } - } - /* count the number of keyword only args & - defaults for keyword only args */ - for ( ; i < NCH(n); ++i) { - ch = CHILD(n, i); - if (TYPE(ch) == DOUBLESTAR) break; - if (TYPE(ch) == tfpdef || TYPE(ch) == vfpdef) nkwonlyargs++; - } - posonlyargs = (nposonlyargs ? _Py_asdl_seq_new(nposonlyargs, c->c_arena) : NULL); - if (!posonlyargs && nposonlyargs) { - return NULL; - } - posargs = (nposargs ? _Py_asdl_seq_new(nposargs, c->c_arena) : NULL); - if (!posargs && nposargs) - return NULL; - kwonlyargs = (nkwonlyargs ? - _Py_asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); - if (!kwonlyargs && nkwonlyargs) - return NULL; - posdefaults = (nposdefaults ? - _Py_asdl_seq_new(nposdefaults, c->c_arena) : NULL); - if (!posdefaults && nposdefaults) - return NULL; - /* The length of kwonlyargs and kwdefaults are same - since we set NULL as default for keyword only argument w/o default - - we have sequence data structure, but no dictionary */ - kwdefaults = (nkwonlyargs ? - _Py_asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); - if (!kwdefaults && nkwonlyargs) - return NULL; - - /* tfpdef: NAME [':' test] - vfpdef: NAME - */ - i = 0; - j = 0; /* index for defaults */ - k = 0; /* index for args */ - l = 0; /* index for posonlyargs */ - while (i < NCH(n)) { - ch = CHILD(n, i); - switch (TYPE(ch)) { - case tfpdef: - case vfpdef: - /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is - anything other than EQUAL or a comma? */ - /* XXX Should NCH(n) check be made a separate check? */ - if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { - expr_ty expression = ast_for_expr(c, CHILD(n, i + 2)); - if (!expression) - return NULL; - assert(posdefaults != NULL); - asdl_seq_SET(posdefaults, j++, expression); - i += 2; - found_default = 1; - } - else if (found_default) { - ast_error(c, n, - "non-default argument follows default argument"); - return NULL; - } - arg = ast_for_arg(c, ch); - if (!arg) - return NULL; - if (l < nposonlyargs) { - asdl_seq_SET(posonlyargs, l++, arg); - } else { - asdl_seq_SET(posargs, k++, arg); - } - i += 1; /* the name */ - if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) - i += 1; /* the comma, if present */ - break; - case SLASH: - /* Advance the slash and the comma. If there are more names - * after the slash there will be a comma so we are advancing - * the correct number of nodes. If the slash is the last item, - * we will be advancing an extra token but then * i > NCH(n) - * and the enclosing while will finish correctly. */ - i += 2; - break; - case STAR: - if (i+1 >= NCH(n) || - (i+2 == NCH(n) && (TYPE(CHILD(n, i+1)) == COMMA - || TYPE(CHILD(n, i+1)) == TYPE_COMMENT))) { - ast_error(c, CHILD(n, i), - "named arguments must follow bare *"); - return NULL; - } - ch = CHILD(n, i+1); /* tfpdef or COMMA */ - if (TYPE(ch) == COMMA) { - int res = 0; - i += 2; /* now follows keyword only arguments */ - - if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) { - ast_error(c, CHILD(n, i), - "bare * has associated type comment"); - return NULL; - } - - res = handle_keywordonly_args(c, n, i, - kwonlyargs, kwdefaults); - if (res == -1) return NULL; - i = res; /* res has new position to process */ - } - else { - vararg = ast_for_arg(c, ch); - if (!vararg) - return NULL; - - i += 2; /* the star and the name */ - if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) - i += 1; /* the comma, if present */ - - if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) { - vararg->type_comment = NEW_TYPE_COMMENT(CHILD(n, i)); - if (!vararg->type_comment) - return NULL; - i += 1; - } - - if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef - || TYPE(CHILD(n, i)) == vfpdef)) { - int res = 0; - res = handle_keywordonly_args(c, n, i, - kwonlyargs, kwdefaults); - if (res == -1) return NULL; - i = res; /* res has new position to process */ - } - } - break; - case DOUBLESTAR: - ch = CHILD(n, i+1); /* tfpdef */ - assert(TYPE(ch) == tfpdef || TYPE(ch) == vfpdef); - kwarg = ast_for_arg(c, ch); - if (!kwarg) - return NULL; - i += 2; /* the double star and the name */ - if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) - i += 1; /* the comma, if present */ - break; - case TYPE_COMMENT: - assert(i); - - if (kwarg) - arg = kwarg; - - /* arg will be equal to the last argument processed */ - arg->type_comment = NEW_TYPE_COMMENT(ch); - if (!arg->type_comment) - return NULL; - i += 1; - break; - default: - PyErr_Format(PyExc_SystemError, - "unexpected node in varargslist: %d @ %d", - TYPE(ch), i); - return NULL; - } - } - return arguments(posonlyargs, posargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena); -} - -static expr_ty -ast_for_decorator(struct compiling *c, const node *n) -{ - /* decorator: '@' namedexpr_test NEWLINE */ - - REQ(n, decorator); - REQ(CHILD(n, 0), AT); - REQ(CHILD(n, 2), NEWLINE); - - return ast_for_expr(c, CHILD(n, 1)); -} - -static asdl_seq* -ast_for_decorators(struct compiling *c, const node *n) -{ - asdl_seq* decorator_seq; - expr_ty d; - int i; - - REQ(n, decorators); - decorator_seq = _Py_asdl_seq_new(NCH(n), c->c_arena); - if (!decorator_seq) - return NULL; - - for (i = 0; i < NCH(n); i++) { - d = ast_for_decorator(c, CHILD(n, i)); - if (!d) - return NULL; - asdl_seq_SET(decorator_seq, i, d); - } - return decorator_seq; -} - -static stmt_ty -ast_for_funcdef_impl(struct compiling *c, const node *n0, - asdl_seq *decorator_seq, bool is_async) -{ - /* funcdef: 'def' NAME parameters ['->' test] ':' [TYPE_COMMENT] suite */ - const node * const n = is_async ? CHILD(n0, 1) : n0; - identifier name; - arguments_ty args; - asdl_seq *body; - expr_ty returns = NULL; - int name_i = 1; - int end_lineno, end_col_offset; - node *tc; - string type_comment = NULL; - - if (is_async && c->c_feature_version < 5) { - ast_error(c, n, - "Async functions are only supported in Python 3.5 and greater"); - return NULL; - } - - REQ(n, funcdef); - - name = NEW_IDENTIFIER(CHILD(n, name_i)); - if (!name) - return NULL; - if (forbidden_name(c, name, CHILD(n, name_i), 0)) - return NULL; - args = ast_for_arguments(c, CHILD(n, name_i + 1)); - if (!args) - return NULL; - if (TYPE(CHILD(n, name_i+2)) == RARROW) { - returns = ast_for_expr(c, CHILD(n, name_i + 3)); - if (!returns) - return NULL; - name_i += 2; - } - if (TYPE(CHILD(n, name_i + 3)) == TYPE_COMMENT) { - type_comment = NEW_TYPE_COMMENT(CHILD(n, name_i + 3)); - if (!type_comment) - return NULL; - name_i += 1; - } - body = ast_for_suite(c, CHILD(n, name_i + 3)); - if (!body) - return NULL; - get_last_end_pos(body, &end_lineno, &end_col_offset); - - if (NCH(CHILD(n, name_i + 3)) > 1) { - /* Check if the suite has a type comment in it. */ - tc = CHILD(CHILD(n, name_i + 3), 1); - - if (TYPE(tc) == TYPE_COMMENT) { - if (type_comment != NULL) { - ast_error(c, n, "Cannot have two type comments on def"); - return NULL; - } - type_comment = NEW_TYPE_COMMENT(tc); - if (!type_comment) - return NULL; - } - } - - if (is_async) - return AsyncFunctionDef(name, args, body, decorator_seq, returns, type_comment, - LINENO(n0), n0->n_col_offset, end_lineno, end_col_offset, c->c_arena); - else - return FunctionDef(name, args, body, decorator_seq, returns, type_comment, - LINENO(n), n->n_col_offset, end_lineno, end_col_offset, c->c_arena); -} - -static stmt_ty -ast_for_async_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) -{ - /* async_funcdef: ASYNC funcdef */ - REQ(n, async_funcdef); - REQ(CHILD(n, 0), ASYNC); - REQ(CHILD(n, 1), funcdef); - - return ast_for_funcdef_impl(c, n, decorator_seq, - true /* is_async */); -} - -static stmt_ty -ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) -{ - /* funcdef: 'def' NAME parameters ['->' test] ':' suite */ - return ast_for_funcdef_impl(c, n, decorator_seq, - false /* is_async */); -} - - -static stmt_ty -ast_for_async_stmt(struct compiling *c, const node *n) -{ - /* async_stmt: ASYNC (funcdef | with_stmt | for_stmt) */ - REQ(n, async_stmt); - REQ(CHILD(n, 0), ASYNC); - - switch (TYPE(CHILD(n, 1))) { - case funcdef: - return ast_for_funcdef_impl(c, n, NULL, - true /* is_async */); - case with_stmt: - return ast_for_with_stmt(c, n, - true /* is_async */); - - case for_stmt: - return ast_for_for_stmt(c, n, - true /* is_async */); - - default: - PyErr_Format(PyExc_SystemError, - "invalid async stament: %s", - STR(CHILD(n, 1))); - return NULL; - } -} - -static stmt_ty -ast_for_decorated(struct compiling *c, const node *n) -{ - /* decorated: decorators (classdef | funcdef | async_funcdef) */ - stmt_ty thing = NULL; - asdl_seq *decorator_seq = NULL; - - REQ(n, decorated); - - decorator_seq = ast_for_decorators(c, CHILD(n, 0)); - if (!decorator_seq) - return NULL; - - assert(TYPE(CHILD(n, 1)) == funcdef || - TYPE(CHILD(n, 1)) == async_funcdef || - TYPE(CHILD(n, 1)) == classdef); - - if (TYPE(CHILD(n, 1)) == funcdef) { - thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq); - } else if (TYPE(CHILD(n, 1)) == classdef) { - thing = ast_for_classdef(c, CHILD(n, 1), decorator_seq); - } else if (TYPE(CHILD(n, 1)) == async_funcdef) { - thing = ast_for_async_funcdef(c, CHILD(n, 1), decorator_seq); - } - return thing; -} - -static expr_ty -ast_for_namedexpr(struct compiling *c, const node *n) -{ - /* namedexpr_test: test [':=' test] - argument: ( test [comp_for] | - test ':=' test | - test '=' test | - '**' test | - '*' test ) - */ - expr_ty target, value; - - target = ast_for_expr(c, CHILD(n, 0)); - if (!target) - return NULL; - - value = ast_for_expr(c, CHILD(n, 2)); - if (!value) - return NULL; - - if (target->kind != Name_kind) { - const char *expr_name = get_expr_name(target); - if (expr_name != NULL) { - ast_error(c, n, "cannot use assignment expressions with %s", expr_name); - } - return NULL; - } - - if (!set_context(c, target, Store, n)) - return NULL; - - return NamedExpr(target, value, LINENO(n), n->n_col_offset, n->n_end_lineno, - n->n_end_col_offset, c->c_arena); -} - -static expr_ty -ast_for_lambdef(struct compiling *c, const node *n) -{ - /* lambdef: 'lambda' [varargslist] ':' test - lambdef_nocond: 'lambda' [varargslist] ':' test_nocond */ - arguments_ty args; - expr_ty expression; - - if (NCH(n) == 3) { - args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); - if (!args) - return NULL; - expression = ast_for_expr(c, CHILD(n, 2)); - if (!expression) - return NULL; - } - else { - args = ast_for_arguments(c, CHILD(n, 1)); - if (!args) - return NULL; - expression = ast_for_expr(c, CHILD(n, 3)); - if (!expression) - return NULL; - } - - return Lambda(args, expression, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static expr_ty -ast_for_ifexpr(struct compiling *c, const node *n) -{ - /* test: or_test 'if' or_test 'else' test */ - expr_ty expression, body, orelse; - - assert(NCH(n) == 5); - body = ast_for_expr(c, CHILD(n, 0)); - if (!body) - return NULL; - expression = ast_for_expr(c, CHILD(n, 2)); - if (!expression) - return NULL; - orelse = ast_for_expr(c, CHILD(n, 4)); - if (!orelse) - return NULL; - return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - c->c_arena); -} - -/* - Count the number of 'for' loops in a comprehension. - - Helper for ast_for_comprehension(). -*/ - -static int -count_comp_fors(struct compiling *c, const node *n) -{ - int n_fors = 0; - - count_comp_for: - n_fors++; - REQ(n, comp_for); - if (NCH(n) == 2) { - REQ(CHILD(n, 0), ASYNC); - n = CHILD(n, 1); - } - else if (NCH(n) == 1) { - n = CHILD(n, 0); - } - else { - goto error; - } - if (NCH(n) == (5)) { - n = CHILD(n, 4); - } - else { - return n_fors; - } - count_comp_iter: - REQ(n, comp_iter); - n = CHILD(n, 0); - if (TYPE(n) == comp_for) - goto count_comp_for; - else if (TYPE(n) == comp_if) { - if (NCH(n) == 3) { - n = CHILD(n, 2); - goto count_comp_iter; - } - else - return n_fors; - } - - error: - /* Should never be reached */ - PyErr_SetString(PyExc_SystemError, - "logic error in count_comp_fors"); - return -1; -} - -/* Count the number of 'if' statements in a comprehension. - - Helper for ast_for_comprehension(). -*/ - -static int -count_comp_ifs(struct compiling *c, const node *n) -{ - int n_ifs = 0; - - while (1) { - REQ(n, comp_iter); - if (TYPE(CHILD(n, 0)) == comp_for) - return n_ifs; - n = CHILD(n, 0); - REQ(n, comp_if); - n_ifs++; - if (NCH(n) == 2) - return n_ifs; - n = CHILD(n, 2); - } -} - -static asdl_seq * -ast_for_comprehension(struct compiling *c, const node *n) -{ - int i, n_fors; - asdl_seq *comps; - - n_fors = count_comp_fors(c, n); - if (n_fors == -1) - return NULL; - - comps = _Py_asdl_seq_new(n_fors, c->c_arena); - if (!comps) - return NULL; - - for (i = 0; i < n_fors; i++) { - comprehension_ty comp; - asdl_seq *t; - expr_ty expression, first; - node *for_ch; - node *sync_n; - int is_async = 0; - - REQ(n, comp_for); - - if (NCH(n) == 2) { - is_async = 1; - REQ(CHILD(n, 0), ASYNC); - sync_n = CHILD(n, 1); - } - else { - sync_n = CHILD(n, 0); - } - REQ(sync_n, sync_comp_for); - - /* Async comprehensions only allowed in Python 3.6 and greater */ - if (is_async && c->c_feature_version < 6) { - ast_error(c, n, - "Async comprehensions are only supported in Python 3.6 and greater"); - return NULL; - } - - for_ch = CHILD(sync_n, 1); - t = ast_for_exprlist(c, for_ch, Store); - if (!t) - return NULL; - expression = ast_for_expr(c, CHILD(sync_n, 3)); - if (!expression) - return NULL; - - /* Check the # of children rather than the length of t, since - (x for x, in ...) has 1 element in t, but still requires a Tuple. */ - first = (expr_ty)asdl_seq_GET(t, 0); - if (NCH(for_ch) == 1) - comp = comprehension(first, expression, NULL, - is_async, c->c_arena); - else - comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset, - for_ch->n_end_lineno, for_ch->n_end_col_offset, - c->c_arena), - expression, NULL, is_async, c->c_arena); - if (!comp) - return NULL; - - if (NCH(sync_n) == 5) { - int j, n_ifs; - asdl_seq *ifs; - - n = CHILD(sync_n, 4); - n_ifs = count_comp_ifs(c, n); - if (n_ifs == -1) - return NULL; - - ifs = _Py_asdl_seq_new(n_ifs, c->c_arena); - if (!ifs) - return NULL; - - for (j = 0; j < n_ifs; j++) { - REQ(n, comp_iter); - n = CHILD(n, 0); - REQ(n, comp_if); - - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - asdl_seq_SET(ifs, j, expression); - if (NCH(n) == 3) - n = CHILD(n, 2); - } - /* on exit, must guarantee that n is a comp_for */ - if (TYPE(n) == comp_iter) - n = CHILD(n, 0); - comp->ifs = ifs; - } - asdl_seq_SET(comps, i, comp); - } - return comps; -} - -static expr_ty -ast_for_itercomp(struct compiling *c, const node *n, int type) -{ - /* testlist_comp: (test|star_expr) - * ( comp_for | (',' (test|star_expr))* [','] ) */ - expr_ty elt; - asdl_seq *comps; - node *ch; - - assert(NCH(n) > 1); - - ch = CHILD(n, 0); - elt = ast_for_expr(c, ch); - if (!elt) - return NULL; - if (elt->kind == Starred_kind) { - ast_error(c, ch, "iterable unpacking cannot be used in comprehension"); - return NULL; - } - - comps = ast_for_comprehension(c, CHILD(n, 1)); - if (!comps) - return NULL; - - if (type == COMP_GENEXP) - return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - else if (type == COMP_LISTCOMP) - return ListComp(elt, comps, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - else if (type == COMP_SETCOMP) - return SetComp(elt, comps, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - else - /* Should never happen */ - return NULL; -} - -/* Fills in the key, value pair corresponding to the dict element. In case - * of an unpacking, key is NULL. *i is advanced by the number of ast - * elements. Iff successful, nonzero is returned. - */ -static int -ast_for_dictelement(struct compiling *c, const node *n, int *i, - expr_ty *key, expr_ty *value) -{ - expr_ty expression; - if (TYPE(CHILD(n, *i)) == DOUBLESTAR) { - assert(NCH(n) - *i >= 2); - - expression = ast_for_expr(c, CHILD(n, *i + 1)); - if (!expression) - return 0; - *key = NULL; - *value = expression; - - *i += 2; - } - else { - assert(NCH(n) - *i >= 3); - - expression = ast_for_expr(c, CHILD(n, *i)); - if (!expression) - return 0; - *key = expression; - - REQ(CHILD(n, *i + 1), COLON); - - expression = ast_for_expr(c, CHILD(n, *i + 2)); - if (!expression) - return 0; - *value = expression; - - *i += 3; - } - return 1; -} - -static expr_ty -ast_for_dictcomp(struct compiling *c, const node *n) -{ - expr_ty key, value; - asdl_seq *comps; - int i = 0; - - if (!ast_for_dictelement(c, n, &i, &key, &value)) - return NULL; - assert(key); - assert(NCH(n) - i >= 1); - - comps = ast_for_comprehension(c, CHILD(n, i)); - if (!comps) - return NULL; - - return DictComp(key, value, comps, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static expr_ty -ast_for_dictdisplay(struct compiling *c, const node *n) -{ - int i; - int j; - int size; - asdl_seq *keys, *values; - - size = (NCH(n) + 1) / 3; /* +1 in case no trailing comma */ - keys = _Py_asdl_seq_new(size, c->c_arena); - if (!keys) - return NULL; - - values = _Py_asdl_seq_new(size, c->c_arena); - if (!values) - return NULL; - - j = 0; - for (i = 0; i < NCH(n); i++) { - expr_ty key, value; - - if (!ast_for_dictelement(c, n, &i, &key, &value)) - return NULL; - asdl_seq_SET(keys, j, key); - asdl_seq_SET(values, j, value); - - j++; - } - keys->size = j; - values->size = j; - return Dict(keys, values, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static expr_ty -ast_for_genexp(struct compiling *c, const node *n) -{ - assert(TYPE(n) == (testlist_comp) || TYPE(n) == (argument)); - return ast_for_itercomp(c, n, COMP_GENEXP); -} - -static expr_ty -ast_for_listcomp(struct compiling *c, const node *n) -{ - assert(TYPE(n) == (testlist_comp)); - return ast_for_itercomp(c, n, COMP_LISTCOMP); -} - -static expr_ty -ast_for_setcomp(struct compiling *c, const node *n) -{ - assert(TYPE(n) == (dictorsetmaker)); - return ast_for_itercomp(c, n, COMP_SETCOMP); -} - -static expr_ty -ast_for_setdisplay(struct compiling *c, const node *n) -{ - int i; - int size; - asdl_seq *elts; - - assert(TYPE(n) == (dictorsetmaker)); - size = (NCH(n) + 1) / 2; /* +1 in case no trailing comma */ - elts = _Py_asdl_seq_new(size, c->c_arena); - if (!elts) - return NULL; - for (i = 0; i < NCH(n); i += 2) { - expr_ty expression; - expression = ast_for_expr(c, CHILD(n, i)); - if (!expression) - return NULL; - asdl_seq_SET(elts, i / 2, expression); - } - return Set(elts, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static expr_ty -ast_for_atom(struct compiling *c, const node *n) -{ - /* atom: '(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' - | '{' [dictmaker|testlist_comp] '}' | NAME | NUMBER | STRING+ - | '...' | 'None' | 'True' | 'False' - */ - node *ch = CHILD(n, 0); - - switch (TYPE(ch)) { - case NAME: { - PyObject *name; - const char *s = STR(ch); - size_t len = strlen(s); - if (len >= 4 && len <= 5) { - if (!strcmp(s, "None")) - return Constant(Py_None, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - if (!strcmp(s, "True")) - return Constant(Py_True, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - if (!strcmp(s, "False")) - return Constant(Py_False, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - name = new_identifier(s, c); - if (!name) - return NULL; - /* All names start in Load context, but may later be changed. */ - return Name(name, Load, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - case STRING: { - expr_ty str = parsestrplus(c, n); - if (!str) { - const char *errtype = NULL; - if (PyErr_ExceptionMatches(PyExc_UnicodeError)) - errtype = "unicode error"; - else if (PyErr_ExceptionMatches(PyExc_ValueError)) - errtype = "value error"; - if (errtype) { - PyObject *type, *value, *tback, *errstr; - PyErr_Fetch(&type, &value, &tback); - errstr = PyObject_Str(value); - if (errstr) { - ast_error(c, n, "(%s) %U", errtype, errstr); - Py_DECREF(errstr); - } - else { - PyErr_Clear(); - ast_error(c, n, "(%s) unknown error", errtype); - } - Py_DECREF(type); - Py_XDECREF(value); - Py_XDECREF(tback); - } - return NULL; - } - return str; - } - case NUMBER: { - PyObject *pynum; - /* Underscores in numeric literals are only allowed in Python 3.6 or greater */ - /* Check for underscores here rather than in parse_number so we can report a line number on error */ - if (c->c_feature_version < 6 && strchr(STR(ch), '_') != NULL) { - ast_error(c, ch, - "Underscores in numeric literals are only supported in Python 3.6 and greater"); - return NULL; - } - pynum = parsenumber(c, STR(ch)); - if (!pynum) - return NULL; - - if (PyArena_AddPyObject(c->c_arena, pynum) < 0) { - Py_DECREF(pynum); - return NULL; - } - return Constant(pynum, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - case ELLIPSIS: /* Ellipsis */ - return Constant(Py_Ellipsis, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - case LPAR: /* some parenthesized expressions */ - ch = CHILD(n, 1); - - if (TYPE(ch) == RPAR) - return Tuple(NULL, Load, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - - if (TYPE(ch) == yield_expr) - return ast_for_expr(c, ch); - - /* testlist_comp: test ( comp_for | (',' test)* [','] ) */ - if (NCH(ch) == 1) { - return ast_for_testlist(c, ch); - } - - if (TYPE(CHILD(ch, 1)) == comp_for) { - return copy_location(ast_for_genexp(c, ch), n, n); - } - else { - return copy_location(ast_for_testlist(c, ch), n, n); - } - case LSQB: /* list (or list comprehension) */ - ch = CHILD(n, 1); - - if (TYPE(ch) == RSQB) - return List(NULL, Load, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - - REQ(ch, testlist_comp); - if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { - asdl_seq *elts = seq_for_testlist(c, ch); - if (!elts) - return NULL; - - return List(elts, Load, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else { - return copy_location(ast_for_listcomp(c, ch), n, n); - } - case LBRACE: { - /* dictorsetmaker: ( ((test ':' test | '**' test) - * (comp_for | (',' (test ':' test | '**' test))* [','])) | - * ((test | '*' test) - * (comp_for | (',' (test | '*' test))* [','])) ) */ - expr_ty res; - ch = CHILD(n, 1); - if (TYPE(ch) == RBRACE) { - /* It's an empty dict. */ - return Dict(NULL, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else { - int is_dict = (TYPE(CHILD(ch, 0)) == DOUBLESTAR); - if (NCH(ch) == 1 || - (NCH(ch) > 1 && - TYPE(CHILD(ch, 1)) == COMMA)) { - /* It's a set display. */ - res = ast_for_setdisplay(c, ch); - } - else if (NCH(ch) > 1 && - TYPE(CHILD(ch, 1)) == comp_for) { - /* It's a set comprehension. */ - res = ast_for_setcomp(c, ch); - } - else if (NCH(ch) > 3 - is_dict && - TYPE(CHILD(ch, 3 - is_dict)) == comp_for) { - /* It's a dictionary comprehension. */ - if (is_dict) { - ast_error(c, n, - "dict unpacking cannot be used in dict comprehension"); - return NULL; - } - res = ast_for_dictcomp(c, ch); - } - else { - /* It's a dictionary display. */ - res = ast_for_dictdisplay(c, ch); - } - return copy_location(res, n, n); - } - } - default: - PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch)); - return NULL; - } -} - -static expr_ty -ast_for_slice(struct compiling *c, const node *n) -{ - node *ch; - expr_ty lower = NULL, upper = NULL, step = NULL; - - REQ(n, subscript); - - /* - subscript: test | [test] ':' [test] [sliceop] - sliceop: ':' [test] - */ - ch = CHILD(n, 0); - if (NCH(n) == 1 && TYPE(ch) == test) { - return ast_for_expr(c, ch); - } - - if (TYPE(ch) == test) { - lower = ast_for_expr(c, ch); - if (!lower) - return NULL; - } - - /* If there's an upper bound it's in the second or third position. */ - if (TYPE(ch) == COLON) { - if (NCH(n) > 1) { - node *n2 = CHILD(n, 1); - - if (TYPE(n2) == test) { - upper = ast_for_expr(c, n2); - if (!upper) - return NULL; - } - } - } else if (NCH(n) > 2) { - node *n2 = CHILD(n, 2); - - if (TYPE(n2) == test) { - upper = ast_for_expr(c, n2); - if (!upper) - return NULL; - } - } - - ch = CHILD(n, NCH(n) - 1); - if (TYPE(ch) == sliceop) { - if (NCH(ch) != 1) { - ch = CHILD(ch, 1); - if (TYPE(ch) == test) { - step = ast_for_expr(c, ch); - if (!step) - return NULL; - } - } - } - - return Slice(lower, upper, step, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static expr_ty -ast_for_binop(struct compiling *c, const node *n) -{ - /* Must account for a sequence of expressions. - How should A op B op C by represented? - BinOp(BinOp(A, op, B), op, C). - */ - - int i, nops; - expr_ty expr1, expr2, result; - operator_ty newoperator; - - expr1 = ast_for_expr(c, CHILD(n, 0)); - if (!expr1) - return NULL; - - expr2 = ast_for_expr(c, CHILD(n, 2)); - if (!expr2) - return NULL; - - newoperator = get_operator(c, CHILD(n, 1)); - if (!newoperator) - return NULL; - - result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, - CHILD(n, 2)->n_end_lineno, CHILD(n, 2)->n_end_col_offset, - c->c_arena); - if (!result) - return NULL; - - nops = (NCH(n) - 1) / 2; - for (i = 1; i < nops; i++) { - expr_ty tmp_result, tmp; - const node* next_oper = CHILD(n, i * 2 + 1); - - newoperator = get_operator(c, next_oper); - if (!newoperator) - return NULL; - - tmp = ast_for_expr(c, CHILD(n, i * 2 + 2)); - if (!tmp) - return NULL; - - tmp_result = BinOp(result, newoperator, tmp, - LINENO(n), n->n_col_offset, - CHILD(n, i * 2 + 2)->n_end_lineno, - CHILD(n, i * 2 + 2)->n_end_col_offset, - c->c_arena); - if (!tmp_result) - return NULL; - result = tmp_result; - } - return result; -} - -static expr_ty -ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr, const node *start) -{ - /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME - subscriptlist: subscript (',' subscript)* [','] - subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] - */ - const node *n_copy = n; - REQ(n, trailer); - if (TYPE(CHILD(n, 0)) == LPAR) { - if (NCH(n) == 2) - return Call(left_expr, NULL, NULL, LINENO(start), start->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - else - return ast_for_call(c, CHILD(n, 1), left_expr, - start, CHILD(n, 0), CHILD(n, 2)); - } - else if (TYPE(CHILD(n, 0)) == DOT) { - PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1)); - if (!attr_id) - return NULL; - return Attribute(left_expr, attr_id, Load, - LINENO(start), start->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else { - REQ(CHILD(n, 0), LSQB); - REQ(CHILD(n, 2), RSQB); - n = CHILD(n, 1); - if (NCH(n) == 1) { - expr_ty slc = ast_for_slice(c, CHILD(n, 0)); - if (!slc) - return NULL; - return Subscript(left_expr, slc, Load, LINENO(start), start->n_col_offset, - n_copy->n_end_lineno, n_copy->n_end_col_offset, - c->c_arena); - } - else { - int j; - expr_ty slc, e; - asdl_seq *elts; - elts = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); - if (!elts) - return NULL; - for (j = 0; j < NCH(n); j += 2) { - slc = ast_for_slice(c, CHILD(n, j)); - if (!slc) - return NULL; - asdl_seq_SET(elts, j / 2, slc); - } - e = Tuple(elts, Load, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - c->c_arena); - if (!e) - return NULL; - return Subscript(left_expr, e, - Load, LINENO(start), start->n_col_offset, - n_copy->n_end_lineno, n_copy->n_end_col_offset, - c->c_arena); - } - } -} - -static expr_ty -ast_for_factor(struct compiling *c, const node *n) -{ - expr_ty expression; - - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - - switch (TYPE(CHILD(n, 0))) { - case PLUS: - return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - c->c_arena); - case MINUS: - return UnaryOp(USub, expression, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - c->c_arena); - case TILDE: - return UnaryOp(Invert, expression, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - c->c_arena); - } - PyErr_Format(PyExc_SystemError, "unhandled factor: %d", - TYPE(CHILD(n, 0))); - return NULL; -} - -static expr_ty -ast_for_atom_expr(struct compiling *c, const node *n) -{ - int i, nch, start = 0; - expr_ty e; - - REQ(n, atom_expr); - nch = NCH(n); - - if (TYPE(CHILD(n, 0)) == AWAIT) { - if (c->c_feature_version < 5) { - ast_error(c, n, - "Await expressions are only supported in Python 3.5 and greater"); - return NULL; - } - start = 1; - assert(nch > 1); - } - - e = ast_for_atom(c, CHILD(n, start)); - if (!e) - return NULL; - if (nch == 1) - return e; - if (start && nch == 2) { - return Await(e, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - - for (i = start + 1; i < nch; i++) { - node *ch = CHILD(n, i); - if (TYPE(ch) != trailer) - break; - e = ast_for_trailer(c, ch, e, CHILD(n, start)); - if (!e) - return NULL; - } - - if (start) { - /* there was an 'await' */ - return Await(e, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else { - return e; - } -} - -static expr_ty -ast_for_power(struct compiling *c, const node *n) -{ - /* power: atom trailer* ('**' factor)* - */ - expr_ty e; - REQ(n, power); - e = ast_for_atom_expr(c, CHILD(n, 0)); - if (!e) - return NULL; - if (NCH(n) == 1) - return e; - if (TYPE(CHILD(n, NCH(n) - 1)) == factor) { - expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1)); - if (!f) - return NULL; - e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - return e; -} - -static expr_ty -ast_for_starred(struct compiling *c, const node *n) -{ - expr_ty tmp; - REQ(n, star_expr); - - tmp = ast_for_expr(c, CHILD(n, 1)); - if (!tmp) - return NULL; - - /* The Load context is changed later. */ - return Starred(tmp, Load, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - - -/* Do not name a variable 'expr'! Will cause a compile error. -*/ - -static expr_ty -ast_for_expr(struct compiling *c, const node *n) -{ - /* handle the full range of simple expressions - namedexpr_test: test [':=' test] - test: or_test ['if' or_test 'else' test] | lambdef - test_nocond: or_test | lambdef_nocond - or_test: and_test ('or' and_test)* - and_test: not_test ('and' not_test)* - not_test: 'not' not_test | comparison - comparison: expr (comp_op expr)* - expr: xor_expr ('|' xor_expr)* - xor_expr: and_expr ('^' and_expr)* - and_expr: shift_expr ('&' shift_expr)* - shift_expr: arith_expr (('<<'|'>>') arith_expr)* - arith_expr: term (('+'|'-') term)* - term: factor (('*'|'@'|'/'|'%'|'//') factor)* - factor: ('+'|'-'|'~') factor | power - power: atom_expr ['**' factor] - atom_expr: [AWAIT] atom trailer* - yield_expr: 'yield' [yield_arg] - */ - - asdl_seq *seq; - int i; - - loop: - switch (TYPE(n)) { - case namedexpr_test: - if (NCH(n) == 3) - return ast_for_namedexpr(c, n); - /* Fallthrough */ - case test: - case test_nocond: - if (TYPE(CHILD(n, 0)) == lambdef || - TYPE(CHILD(n, 0)) == lambdef_nocond) - return ast_for_lambdef(c, CHILD(n, 0)); - else if (NCH(n) > 1) - return ast_for_ifexpr(c, n); - /* Fallthrough */ - case or_test: - case and_test: - if (NCH(n) == 1) { - n = CHILD(n, 0); - goto loop; - } - seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); - if (!seq) - return NULL; - for (i = 0; i < NCH(n); i += 2) { - expr_ty e = ast_for_expr(c, CHILD(n, i)); - if (!e) - return NULL; - asdl_seq_SET(seq, i / 2, e); - } - if (!strcmp(STR(CHILD(n, 1)), "and")) - return BoolOp(And, seq, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - c->c_arena); - assert(!strcmp(STR(CHILD(n, 1)), "or")); - return BoolOp(Or, seq, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - case not_test: - if (NCH(n) == 1) { - n = CHILD(n, 0); - goto loop; - } - else { - expr_ty expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - - return UnaryOp(Not, expression, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, - c->c_arena); - } - case comparison: - if (NCH(n) == 1) { - n = CHILD(n, 0); - goto loop; - } - else { - expr_ty expression; - asdl_int_seq *ops; - asdl_seq *cmps; - ops = _Py_asdl_int_seq_new(NCH(n) / 2, c->c_arena); - if (!ops) - return NULL; - cmps = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena); - if (!cmps) { - return NULL; - } - for (i = 1; i < NCH(n); i += 2) { - cmpop_ty newoperator; - - newoperator = ast_for_comp_op(c, CHILD(n, i)); - if (!newoperator) { - return NULL; - } - - expression = ast_for_expr(c, CHILD(n, i + 1)); - if (!expression) { - return NULL; - } - - asdl_seq_SET(ops, i / 2, newoperator); - asdl_seq_SET(cmps, i / 2, expression); - } - expression = ast_for_expr(c, CHILD(n, 0)); - if (!expression) { - return NULL; - } - - return Compare(expression, ops, cmps, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - - case star_expr: - return ast_for_starred(c, n); - /* The next five cases all handle BinOps. The main body of code - is the same in each case, but the switch turned inside out to - reuse the code for each type of operator. - */ - case expr: - case xor_expr: - case and_expr: - case shift_expr: - case arith_expr: - case term: - if (NCH(n) == 1) { - n = CHILD(n, 0); - goto loop; - } - return ast_for_binop(c, n); - case yield_expr: { - node *an = NULL; - node *en = NULL; - int is_from = 0; - expr_ty exp = NULL; - if (NCH(n) > 1) - an = CHILD(n, 1); /* yield_arg */ - if (an) { - en = CHILD(an, NCH(an) - 1); - if (NCH(an) == 2) { - is_from = 1; - exp = ast_for_expr(c, en); - } - else - exp = ast_for_testlist(c, en); - if (!exp) - return NULL; - } - if (is_from) - return YieldFrom(exp, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - return Yield(exp, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - case factor: - if (NCH(n) == 1) { - n = CHILD(n, 0); - goto loop; - } - return ast_for_factor(c, n); - case power: - return ast_for_power(c, n); - default: - PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n)); - return NULL; - } - /* should never get here unless if error is set */ - return NULL; -} - -static expr_ty -ast_for_call(struct compiling *c, const node *n, expr_ty func, - const node *start, const node *maybegenbeg, const node *closepar) -{ - /* - arglist: argument (',' argument)* [','] - argument: ( test [comp_for] | '*' test | test '=' test | '**' test ) - */ - - int i, nargs, nkeywords; - int ndoublestars; - asdl_seq *args; - asdl_seq *keywords; - - REQ(n, arglist); - - nargs = 0; - nkeywords = 0; - for (i = 0; i < NCH(n); i++) { - node *ch = CHILD(n, i); - if (TYPE(ch) == argument) { - if (NCH(ch) == 1) - nargs++; - else if (TYPE(CHILD(ch, 1)) == comp_for) { - nargs++; - if (!maybegenbeg) { - ast_error(c, ch, "invalid syntax"); - return NULL; - } - if (NCH(n) > 1) { - ast_error(c, ch, "Generator expression must be parenthesized"); - return NULL; - } - } - else if (TYPE(CHILD(ch, 0)) == STAR) - nargs++; - else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) { - nargs++; - } - else - /* TYPE(CHILD(ch, 0)) == DOUBLESTAR or keyword argument */ - nkeywords++; - } - } - - args = _Py_asdl_seq_new(nargs, c->c_arena); - if (!args) - return NULL; - keywords = _Py_asdl_seq_new(nkeywords, c->c_arena); - if (!keywords) - return NULL; - - nargs = 0; /* positional arguments + iterable argument unpackings */ - nkeywords = 0; /* keyword arguments + keyword argument unpackings */ - ndoublestars = 0; /* just keyword argument unpackings */ - for (i = 0; i < NCH(n); i++) { - node *ch = CHILD(n, i); - if (TYPE(ch) == argument) { - expr_ty e; - node *chch = CHILD(ch, 0); - if (NCH(ch) == 1) { - /* a positional argument */ - if (nkeywords) { - if (ndoublestars) { - ast_error(c, chch, - "positional argument follows " - "keyword argument unpacking"); - } - else { - ast_error(c, chch, - "positional argument follows " - "keyword argument"); - } - return NULL; - } - e = ast_for_expr(c, chch); - if (!e) - return NULL; - asdl_seq_SET(args, nargs++, e); - } - else if (TYPE(chch) == STAR) { - /* an iterable argument unpacking */ - expr_ty starred; - if (ndoublestars) { - ast_error(c, chch, - "iterable argument unpacking follows " - "keyword argument unpacking"); - return NULL; - } - e = ast_for_expr(c, CHILD(ch, 1)); - if (!e) - return NULL; - starred = Starred(e, Load, LINENO(chch), - chch->n_col_offset, - e->end_lineno, e->end_col_offset, - c->c_arena); - if (!starred) - return NULL; - asdl_seq_SET(args, nargs++, starred); - - } - else if (TYPE(chch) == DOUBLESTAR) { - /* a keyword argument unpacking */ - keyword_ty kw; - i++; - e = ast_for_expr(c, CHILD(ch, 1)); - if (!e) - return NULL; - kw = keyword(NULL, e, chch->n_lineno, chch->n_col_offset, - e->end_lineno, e->end_col_offset, c->c_arena); - asdl_seq_SET(keywords, nkeywords++, kw); - ndoublestars++; - } - else if (TYPE(CHILD(ch, 1)) == comp_for) { - /* the lone generator expression */ - e = copy_location(ast_for_genexp(c, ch), maybegenbeg, closepar); - if (!e) - return NULL; - asdl_seq_SET(args, nargs++, e); - } - else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) { - /* treat colon equal as positional argument */ - if (nkeywords) { - if (ndoublestars) { - ast_error(c, chch, - "positional argument follows " - "keyword argument unpacking"); - } - else { - ast_error(c, chch, - "positional argument follows " - "keyword argument"); - } - return NULL; - } - e = ast_for_namedexpr(c, ch); - if (!e) - return NULL; - asdl_seq_SET(args, nargs++, e); - } - else { - /* a keyword argument */ - keyword_ty kw; - identifier key; - - // To remain LL(1), the grammar accepts any test (basically, any - // expression) in the keyword slot of a call site. So, we need - // to manually enforce that the keyword is a NAME here. - static const int name_tree[] = { - test, - or_test, - and_test, - not_test, - comparison, - expr, - xor_expr, - and_expr, - shift_expr, - arith_expr, - term, - factor, - power, - atom_expr, - atom, - 0, - }; - node *expr_node = chch; - for (int i = 0; name_tree[i]; i++) { - if (TYPE(expr_node) != name_tree[i]) - break; - if (NCH(expr_node) != 1) - break; - expr_node = CHILD(expr_node, 0); - } - if (TYPE(expr_node) != NAME) { - ast_error(c, chch, - "expression cannot contain assignment, " - "perhaps you meant \"==\"?"); - return NULL; - } - key = new_identifier(STR(expr_node), c); - if (key == NULL) { - return NULL; - } - if (forbidden_name(c, key, chch, 1)) { - return NULL; - } - e = ast_for_expr(c, CHILD(ch, 2)); - if (!e) - return NULL; - kw = keyword(key, e, chch->n_lineno, chch->n_col_offset, - e->end_lineno, e->end_col_offset, c->c_arena); - - if (!kw) - return NULL; - asdl_seq_SET(keywords, nkeywords++, kw); - } - } - } - - return Call(func, args, keywords, LINENO(start), start->n_col_offset, - closepar->n_end_lineno, closepar->n_end_col_offset, c->c_arena); -} - -static expr_ty -ast_for_testlist(struct compiling *c, const node* n) -{ - /* testlist_comp: test (comp_for | (',' test)* [',']) */ - /* testlist: test (',' test)* [','] */ - assert(NCH(n) > 0); - if (TYPE(n) == testlist_comp) { - if (NCH(n) > 1) - assert(TYPE(CHILD(n, 1)) != comp_for); - } - else { - assert(TYPE(n) == testlist || - TYPE(n) == testlist_star_expr); - } - if (NCH(n) == 1) - return ast_for_expr(c, CHILD(n, 0)); - else { - asdl_seq *tmp = seq_for_testlist(c, n); - if (!tmp) - return NULL; - return Tuple(tmp, Load, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } -} - -static stmt_ty -ast_for_expr_stmt(struct compiling *c, const node *n) -{ - REQ(n, expr_stmt); - /* expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | - [('=' (yield_expr|testlist_star_expr))+ [TYPE_COMMENT]] ) - annassign: ':' test ['=' (yield_expr|testlist)] - testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] - augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | - '<<=' | '>>=' | '**=' | '//=') - test: ... here starts the operator precedence dance - */ - int num = NCH(n); - - if (num == 1) { - expr_ty e = ast_for_testlist(c, CHILD(n, 0)); - if (!e) - return NULL; - - return Expr(e, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else if (TYPE(CHILD(n, 1)) == augassign) { - expr_ty expr1, expr2; - operator_ty newoperator; - node *ch = CHILD(n, 0); - - expr1 = ast_for_testlist(c, ch); - if (!expr1) - return NULL; - /* Augmented assignments can only have a name, a subscript, or an - attribute on the left, though, so we have to explicitly check for - those. */ - switch (expr1->kind) { - case Name_kind: - case Attribute_kind: - case Subscript_kind: - break; - default: - ast_error(c, ch, "'%s' is an illegal expression for augmented assignment", - get_expr_name(expr1)); - return NULL; - } - - /* set_context checks that most expressions are not the left side. */ - if(!set_context(c, expr1, Store, ch)) { - return NULL; - } - - ch = CHILD(n, 2); - if (TYPE(ch) == testlist) - expr2 = ast_for_testlist(c, ch); - else - expr2 = ast_for_expr(c, ch); - if (!expr2) - return NULL; - - newoperator = ast_for_augassign(c, CHILD(n, 1)); - if (!newoperator) - return NULL; - - return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else if (TYPE(CHILD(n, 1)) == annassign) { - expr_ty expr1, expr2, expr3; - node *ch = CHILD(n, 0); - node *deep, *ann = CHILD(n, 1); - int simple = 1; - - /* AnnAssigns are only allowed in Python 3.6 or greater */ - if (c->c_feature_version < 6) { - ast_error(c, ch, - "Variable annotation syntax is only supported in Python 3.6 and greater"); - return NULL; - } - - /* we keep track of parens to qualify (x) as expression not name */ - deep = ch; - while (NCH(deep) == 1) { - deep = CHILD(deep, 0); - } - if (NCH(deep) > 0 && TYPE(CHILD(deep, 0)) == LPAR) { - simple = 0; - } - expr1 = ast_for_testlist(c, ch); - if (!expr1) { - return NULL; - } - switch (expr1->kind) { - case Name_kind: - if (forbidden_name(c, expr1->v.Name.id, n, 0)) { - return NULL; - } - expr1->v.Name.ctx = Store; - break; - case Attribute_kind: - if (forbidden_name(c, expr1->v.Attribute.attr, n, 1)) { - return NULL; - } - expr1->v.Attribute.ctx = Store; - break; - case Subscript_kind: - expr1->v.Subscript.ctx = Store; - break; - case List_kind: - ast_error(c, ch, - "only single target (not list) can be annotated"); - return NULL; - case Tuple_kind: - ast_error(c, ch, - "only single target (not tuple) can be annotated"); - return NULL; - default: - ast_error(c, ch, - "illegal target for annotation"); - return NULL; - } - - if (expr1->kind != Name_kind) { - simple = 0; - } - ch = CHILD(ann, 1); - expr2 = ast_for_expr(c, ch); - if (!expr2) { - return NULL; - } - if (NCH(ann) == 2) { - return AnnAssign(expr1, expr2, NULL, simple, - LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else { - ch = CHILD(ann, 3); - if (TYPE(ch) == testlist_star_expr) { - expr3 = ast_for_testlist(c, ch); - } - else { - expr3 = ast_for_expr(c, ch); - } - if (!expr3) { - return NULL; - } - return AnnAssign(expr1, expr2, expr3, simple, - LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - } - else { - int i, nch_minus_type, has_type_comment; - asdl_seq *targets; - node *value; - expr_ty expression; - string type_comment; - - /* a normal assignment */ - REQ(CHILD(n, 1), EQUAL); - - has_type_comment = TYPE(CHILD(n, num - 1)) == TYPE_COMMENT; - nch_minus_type = num - has_type_comment; - - targets = _Py_asdl_seq_new(nch_minus_type / 2, c->c_arena); - if (!targets) - return NULL; - for (i = 0; i < nch_minus_type - 2; i += 2) { - expr_ty e; - node *ch = CHILD(n, i); - if (TYPE(ch) == yield_expr) { - ast_error(c, ch, "assignment to yield expression not possible"); - return NULL; - } - e = ast_for_testlist(c, ch); - if (!e) - return NULL; - - /* set context to assign */ - if (!set_context(c, e, Store, CHILD(n, i))) - return NULL; - - asdl_seq_SET(targets, i / 2, e); - } - value = CHILD(n, nch_minus_type - 1); - if (TYPE(value) == testlist_star_expr) - expression = ast_for_testlist(c, value); - else - expression = ast_for_expr(c, value); - if (!expression) - return NULL; - if (has_type_comment) { - type_comment = NEW_TYPE_COMMENT(CHILD(n, nch_minus_type)); - if (!type_comment) - return NULL; - } - else - type_comment = NULL; - return Assign(targets, expression, type_comment, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } -} - - -static asdl_seq * -ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context) -{ - asdl_seq *seq; - int i; - expr_ty e; - - REQ(n, exprlist); - - seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); - if (!seq) - return NULL; - for (i = 0; i < NCH(n); i += 2) { - e = ast_for_expr(c, CHILD(n, i)); - if (!e) - return NULL; - asdl_seq_SET(seq, i / 2, e); - if (context && !set_context(c, e, context, CHILD(n, i))) - return NULL; - } - return seq; -} - -static stmt_ty -ast_for_del_stmt(struct compiling *c, const node *n) -{ - asdl_seq *expr_list; - - /* del_stmt: 'del' exprlist */ - REQ(n, del_stmt); - - expr_list = ast_for_exprlist(c, CHILD(n, 1), Del); - if (!expr_list) - return NULL; - return Delete(expr_list, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static stmt_ty -ast_for_flow_stmt(struct compiling *c, const node *n) -{ - /* - flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt - | yield_stmt - break_stmt: 'break' - continue_stmt: 'continue' - return_stmt: 'return' [testlist] - yield_stmt: yield_expr - yield_expr: 'yield' testlist | 'yield' 'from' test - raise_stmt: 'raise' [test [',' test [',' test]]] - */ - node *ch; - - REQ(n, flow_stmt); - ch = CHILD(n, 0); - switch (TYPE(ch)) { - case break_stmt: - return Break(LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - case continue_stmt: - return Continue(LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - case yield_stmt: { /* will reduce to yield_expr */ - expr_ty exp = ast_for_expr(c, CHILD(ch, 0)); - if (!exp) - return NULL; - return Expr(exp, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - case return_stmt: - if (NCH(ch) == 1) - return Return(NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - else { - expr_ty expression = ast_for_testlist(c, CHILD(ch, 1)); - if (!expression) - return NULL; - return Return(expression, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - case raise_stmt: - if (NCH(ch) == 1) - return Raise(NULL, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - else if (NCH(ch) >= 2) { - expr_ty cause = NULL; - expr_ty expression = ast_for_expr(c, CHILD(ch, 1)); - if (!expression) - return NULL; - if (NCH(ch) == 4) { - cause = ast_for_expr(c, CHILD(ch, 3)); - if (!cause) - return NULL; - } - return Raise(expression, cause, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - /* fall through */ - default: - PyErr_Format(PyExc_SystemError, - "unexpected flow_stmt: %d", TYPE(ch)); - return NULL; - } -} - -static alias_ty -alias_for_import_name(struct compiling *c, const node *n, int store) -{ - /* - import_as_name: NAME ['as' NAME] - dotted_as_name: dotted_name ['as' NAME] - dotted_name: NAME ('.' NAME)* - */ - identifier str, name; - - loop: - switch (TYPE(n)) { - case import_as_name: { - node *name_node = CHILD(n, 0); - str = NULL; - name = NEW_IDENTIFIER(name_node); - if (!name) - return NULL; - if (NCH(n) == 3) { - node *str_node = CHILD(n, 2); - str = NEW_IDENTIFIER(str_node); - if (!str) - return NULL; - if (store && forbidden_name(c, str, str_node, 0)) - return NULL; - } - else { - if (forbidden_name(c, name, name_node, 0)) - return NULL; - } - return alias(name, str, c->c_arena); - } - case dotted_as_name: - if (NCH(n) == 1) { - n = CHILD(n, 0); - goto loop; - } - else { - node *asname_node = CHILD(n, 2); - alias_ty a = alias_for_import_name(c, CHILD(n, 0), 0); - if (!a) - return NULL; - assert(!a->asname); - a->asname = NEW_IDENTIFIER(asname_node); - if (!a->asname) - return NULL; - if (forbidden_name(c, a->asname, asname_node, 0)) - return NULL; - return a; - } - case dotted_name: - if (NCH(n) == 1) { - node *name_node = CHILD(n, 0); - name = NEW_IDENTIFIER(name_node); - if (!name) - return NULL; - if (store && forbidden_name(c, name, name_node, 0)) - return NULL; - return alias(name, NULL, c->c_arena); - } - else { - /* Create a string of the form "a.b.c" */ - int i; - size_t len; - char *s; - PyObject *uni; - - len = 0; - for (i = 0; i < NCH(n); i += 2) - /* length of string plus one for the dot */ - len += strlen(STR(CHILD(n, i))) + 1; - len--; /* the last name doesn't have a dot */ - str = PyBytes_FromStringAndSize(NULL, len); - if (!str) - return NULL; - s = PyBytes_AS_STRING(str); - if (!s) - return NULL; - for (i = 0; i < NCH(n); i += 2) { - char *sch = STR(CHILD(n, i)); - strcpy(s, STR(CHILD(n, i))); - s += strlen(sch); - *s++ = '.'; - } - --s; - *s = '\0'; - uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), - PyBytes_GET_SIZE(str), - NULL); - Py_DECREF(str); - if (!uni) - return NULL; - str = uni; - PyUnicode_InternInPlace(&str); - if (PyArena_AddPyObject(c->c_arena, str) < 0) { - Py_DECREF(str); - return NULL; - } - return alias(str, NULL, c->c_arena); - } - case STAR: - str = PyUnicode_InternFromString("*"); - if (!str) - return NULL; - if (PyArena_AddPyObject(c->c_arena, str) < 0) { - Py_DECREF(str); - return NULL; - } - return alias(str, NULL, c->c_arena); - default: - PyErr_Format(PyExc_SystemError, - "unexpected import name: %d", TYPE(n)); - return NULL; - } -} - -static stmt_ty -ast_for_import_stmt(struct compiling *c, const node *n) -{ - /* - import_stmt: import_name | import_from - import_name: 'import' dotted_as_names - import_from: 'from' (('.' | '...')* dotted_name | ('.' | '...')+) - 'import' ('*' | '(' import_as_names ')' | import_as_names) - */ - int lineno; - int col_offset; - int i; - asdl_seq *aliases; - - REQ(n, import_stmt); - lineno = LINENO(n); - col_offset = n->n_col_offset; - n = CHILD(n, 0); - if (TYPE(n) == import_name) { - n = CHILD(n, 1); - REQ(n, dotted_as_names); - aliases = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); - if (!aliases) - return NULL; - for (i = 0; i < NCH(n); i += 2) { - alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); - if (!import_alias) - return NULL; - asdl_seq_SET(aliases, i / 2, import_alias); - } - // Even though n is modified above, the end position is not changed - return Import(aliases, lineno, col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else if (TYPE(n) == import_from) { - int n_children; - int idx, ndots = 0; - const node *n_copy = n; - alias_ty mod = NULL; - identifier modname = NULL; - - /* Count the number of dots (for relative imports) and check for the - optional module name */ - for (idx = 1; idx < NCH(n); idx++) { - if (TYPE(CHILD(n, idx)) == dotted_name) { - mod = alias_for_import_name(c, CHILD(n, idx), 0); - if (!mod) - return NULL; - idx++; - break; - } else if (TYPE(CHILD(n, idx)) == ELLIPSIS) { - /* three consecutive dots are tokenized as one ELLIPSIS */ - ndots += 3; - continue; - } else if (TYPE(CHILD(n, idx)) != DOT) { - break; - } - ndots++; - } - idx++; /* skip over the 'import' keyword */ - switch (TYPE(CHILD(n, idx))) { - case STAR: - /* from ... import * */ - n = CHILD(n, idx); - n_children = 1; - break; - case LPAR: - /* from ... import (x, y, z) */ - n = CHILD(n, idx + 1); - n_children = NCH(n); - break; - case import_as_names: - /* from ... import x, y, z */ - n = CHILD(n, idx); - n_children = NCH(n); - if (n_children % 2 == 0) { - ast_error(c, n, - "trailing comma not allowed without" - " surrounding parentheses"); - return NULL; - } - break; - default: - ast_error(c, n, "Unexpected node-type in from-import"); - return NULL; - } - - aliases = _Py_asdl_seq_new((n_children + 1) / 2, c->c_arena); - if (!aliases) - return NULL; - - /* handle "from ... import *" special b/c there's no children */ - if (TYPE(n) == STAR) { - alias_ty import_alias = alias_for_import_name(c, n, 1); - if (!import_alias) - return NULL; - asdl_seq_SET(aliases, 0, import_alias); - } - else { - for (i = 0; i < NCH(n); i += 2) { - alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); - if (!import_alias) - return NULL; - asdl_seq_SET(aliases, i / 2, import_alias); - } - } - if (mod != NULL) - modname = mod->name; - return ImportFrom(modname, aliases, ndots, lineno, col_offset, - n_copy->n_end_lineno, n_copy->n_end_col_offset, - c->c_arena); - } - PyErr_Format(PyExc_SystemError, - "unknown import statement: starts with command '%s'", - STR(CHILD(n, 0))); - return NULL; -} - -static stmt_ty -ast_for_global_stmt(struct compiling *c, const node *n) -{ - /* global_stmt: 'global' NAME (',' NAME)* */ - identifier name; - asdl_seq *s; - int i; - - REQ(n, global_stmt); - s = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena); - if (!s) - return NULL; - for (i = 1; i < NCH(n); i += 2) { - name = NEW_IDENTIFIER(CHILD(n, i)); - if (!name) - return NULL; - asdl_seq_SET(s, i / 2, name); - } - return Global(s, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static stmt_ty -ast_for_nonlocal_stmt(struct compiling *c, const node *n) -{ - /* nonlocal_stmt: 'nonlocal' NAME (',' NAME)* */ - identifier name; - asdl_seq *s; - int i; - - REQ(n, nonlocal_stmt); - s = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena); - if (!s) - return NULL; - for (i = 1; i < NCH(n); i += 2) { - name = NEW_IDENTIFIER(CHILD(n, i)); - if (!name) - return NULL; - asdl_seq_SET(s, i / 2, name); - } - return Nonlocal(s, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -static stmt_ty -ast_for_assert_stmt(struct compiling *c, const node *n) -{ - /* assert_stmt: 'assert' test [',' test] */ - REQ(n, assert_stmt); - if (NCH(n) == 2) { - expr_ty expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - return Assert(expression, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - else if (NCH(n) == 4) { - expr_ty expr1, expr2; - - expr1 = ast_for_expr(c, CHILD(n, 1)); - if (!expr1) - return NULL; - expr2 = ast_for_expr(c, CHILD(n, 3)); - if (!expr2) - return NULL; - - return Assert(expr1, expr2, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - PyErr_Format(PyExc_SystemError, - "improper number of parts to 'assert' statement: %d", - NCH(n)); - return NULL; -} - -static asdl_seq * -ast_for_suite(struct compiling *c, const node *n) -{ - /* suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */ - asdl_seq *seq; - stmt_ty s; - int i, total, num, end, pos = 0; - node *ch; - - if (TYPE(n) != func_body_suite) { - REQ(n, suite); - } - - total = num_stmts(n); - seq = _Py_asdl_seq_new(total, c->c_arena); - if (!seq) - return NULL; - if (TYPE(CHILD(n, 0)) == simple_stmt) { - n = CHILD(n, 0); - /* simple_stmt always ends with a NEWLINE, - and may have a trailing SEMI - */ - end = NCH(n) - 1; - if (TYPE(CHILD(n, end - 1)) == SEMI) - end--; - /* loop by 2 to skip semi-colons */ - for (i = 0; i < end; i += 2) { - ch = CHILD(n, i); - s = ast_for_stmt(c, ch); - if (!s) - return NULL; - asdl_seq_SET(seq, pos++, s); - } - } - else { - i = 2; - if (TYPE(CHILD(n, 1)) == TYPE_COMMENT) { - i += 2; - REQ(CHILD(n, 2), NEWLINE); - } - - for (; i < (NCH(n) - 1); i++) { - ch = CHILD(n, i); - REQ(ch, stmt); - num = num_stmts(ch); - if (num == 1) { - /* small_stmt or compound_stmt with only one child */ - s = ast_for_stmt(c, ch); - if (!s) - return NULL; - asdl_seq_SET(seq, pos++, s); - } - else { - int j; - ch = CHILD(ch, 0); - REQ(ch, simple_stmt); - for (j = 0; j < NCH(ch); j += 2) { - /* statement terminates with a semi-colon ';' */ - if (NCH(CHILD(ch, j)) == 0) { - assert((j + 1) == NCH(ch)); - break; - } - s = ast_for_stmt(c, CHILD(ch, j)); - if (!s) - return NULL; - asdl_seq_SET(seq, pos++, s); - } - } - } - } - assert(pos == seq->size); - return seq; -} - -static void -get_last_end_pos(asdl_seq *s, int *end_lineno, int *end_col_offset) -{ - Py_ssize_t tot = asdl_seq_LEN(s); - // There must be no empty suites. - assert(tot > 0); - stmt_ty last = asdl_seq_GET(s, tot - 1); - *end_lineno = last->end_lineno; - *end_col_offset = last->end_col_offset; -} - -static stmt_ty -ast_for_if_stmt(struct compiling *c, const node *n) -{ - /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)* - ['else' ':' suite] - */ - char *s; - int end_lineno, end_col_offset; - - REQ(n, if_stmt); - - if (NCH(n) == 4) { - expr_ty expression; - asdl_seq *suite_seq; - - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, CHILD(n, 3)); - if (!suite_seq) - return NULL; - get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); - - return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - - s = STR(CHILD(n, 4)); - /* s[2], the third character in the string, will be - 's' for el_s_e, or - 'i' for el_i_f - */ - if (s[2] == 's') { - expr_ty expression; - asdl_seq *seq1, *seq2; - - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - seq1 = ast_for_suite(c, CHILD(n, 3)); - if (!seq1) - return NULL; - seq2 = ast_for_suite(c, CHILD(n, 6)); - if (!seq2) - return NULL; - get_last_end_pos(seq2, &end_lineno, &end_col_offset); - - return If(expression, seq1, seq2, LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - else if (s[2] == 'i') { - int i, n_elif, has_else = 0; - expr_ty expression; - asdl_seq *suite_seq; - asdl_seq *orelse = NULL; - n_elif = NCH(n) - 4; - /* must reference the child n_elif+1 since 'else' token is third, - not fourth, child from the end. */ - if (TYPE(CHILD(n, (n_elif + 1))) == NAME - && STR(CHILD(n, (n_elif + 1)))[2] == 's') { - has_else = 1; - n_elif -= 3; - } - n_elif /= 4; - - if (has_else) { - asdl_seq *suite_seq2; - - orelse = _Py_asdl_seq_new(1, c->c_arena); - if (!orelse) - return NULL; - expression = ast_for_expr(c, CHILD(n, NCH(n) - 6)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4)); - if (!suite_seq) - return NULL; - suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1)); - if (!suite_seq2) - return NULL; - get_last_end_pos(suite_seq2, &end_lineno, &end_col_offset); - - asdl_seq_SET(orelse, 0, - If(expression, suite_seq, suite_seq2, - LINENO(CHILD(n, NCH(n) - 7)), - CHILD(n, NCH(n) - 7)->n_col_offset, - end_lineno, end_col_offset, c->c_arena)); - /* the just-created orelse handled the last elif */ - n_elif--; - } - - for (i = 0; i < n_elif; i++) { - int off = 5 + (n_elif - i - 1) * 4; - asdl_seq *newobj = _Py_asdl_seq_new(1, c->c_arena); - if (!newobj) - return NULL; - expression = ast_for_expr(c, CHILD(n, off)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, CHILD(n, off + 2)); - if (!suite_seq) - return NULL; - - if (orelse != NULL) { - get_last_end_pos(orelse, &end_lineno, &end_col_offset); - } else { - get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); - } - asdl_seq_SET(newobj, 0, - If(expression, suite_seq, orelse, - LINENO(CHILD(n, off - 1)), - CHILD(n, off - 1)->n_col_offset, - end_lineno, end_col_offset, c->c_arena)); - orelse = newobj; - } - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, CHILD(n, 3)); - if (!suite_seq) - return NULL; - get_last_end_pos(orelse, &end_lineno, &end_col_offset); - return If(expression, suite_seq, orelse, - LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - - PyErr_Format(PyExc_SystemError, - "unexpected token in 'if' statement: %s", s); - return NULL; -} - -static stmt_ty -ast_for_while_stmt(struct compiling *c, const node *n) -{ - /* while_stmt: 'while' test ':' suite ['else' ':' suite] */ - REQ(n, while_stmt); - int end_lineno, end_col_offset; - - if (NCH(n) == 4) { - expr_ty expression; - asdl_seq *suite_seq; - - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, CHILD(n, 3)); - if (!suite_seq) - return NULL; - get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); - return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - else if (NCH(n) == 7) { - expr_ty expression; - asdl_seq *seq1, *seq2; - - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - seq1 = ast_for_suite(c, CHILD(n, 3)); - if (!seq1) - return NULL; - seq2 = ast_for_suite(c, CHILD(n, 6)); - if (!seq2) - return NULL; - get_last_end_pos(seq2, &end_lineno, &end_col_offset); - - return While(expression, seq1, seq2, LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - - PyErr_Format(PyExc_SystemError, - "wrong number of tokens for 'while' statement: %d", - NCH(n)); - return NULL; -} - -static stmt_ty -ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async) -{ - const node * const n = is_async ? CHILD(n0, 1) : n0; - asdl_seq *_target, *seq = NULL, *suite_seq; - expr_ty expression; - expr_ty target, first; - const node *node_target; - int end_lineno, end_col_offset; - int has_type_comment; - string type_comment; - - if (is_async && c->c_feature_version < 5) { - ast_error(c, n, - "Async for loops are only supported in Python 3.5 and greater"); - return NULL; - } - - /* for_stmt: 'for' exprlist 'in' testlist ':' [TYPE_COMMENT] suite ['else' ':' suite] */ - REQ(n, for_stmt); - - has_type_comment = TYPE(CHILD(n, 5)) == TYPE_COMMENT; - - if (NCH(n) == 9 + has_type_comment) { - seq = ast_for_suite(c, CHILD(n, 8 + has_type_comment)); - if (!seq) - return NULL; - } - - node_target = CHILD(n, 1); - _target = ast_for_exprlist(c, node_target, Store); - if (!_target) - return NULL; - /* Check the # of children rather than the length of _target, since - for x, in ... has 1 element in _target, but still requires a Tuple. */ - first = (expr_ty)asdl_seq_GET(_target, 0); - if (NCH(node_target) == 1) - target = first; - else - target = Tuple(_target, Store, first->lineno, first->col_offset, - node_target->n_end_lineno, node_target->n_end_col_offset, - c->c_arena); - - expression = ast_for_testlist(c, CHILD(n, 3)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, CHILD(n, 5 + has_type_comment)); - if (!suite_seq) - return NULL; - - if (seq != NULL) { - get_last_end_pos(seq, &end_lineno, &end_col_offset); - } else { - get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); - } - - if (has_type_comment) { - type_comment = NEW_TYPE_COMMENT(CHILD(n, 5)); - if (!type_comment) - return NULL; - } - else - type_comment = NULL; - - if (is_async) - return AsyncFor(target, expression, suite_seq, seq, type_comment, - LINENO(n0), n0->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - else - return For(target, expression, suite_seq, seq, type_comment, - LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); -} - -static excepthandler_ty -ast_for_except_clause(struct compiling *c, const node *exc, node *body) -{ - /* except_clause: 'except' [test ['as' test]] */ - int end_lineno, end_col_offset; - REQ(exc, except_clause); - REQ(body, suite); - - if (NCH(exc) == 1) { - asdl_seq *suite_seq = ast_for_suite(c, body); - if (!suite_seq) - return NULL; - get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); - - return ExceptHandler(NULL, NULL, suite_seq, LINENO(exc), - exc->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - else if (NCH(exc) == 2) { - expr_ty expression; - asdl_seq *suite_seq; - - expression = ast_for_expr(c, CHILD(exc, 1)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, body); - if (!suite_seq) - return NULL; - get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); - - return ExceptHandler(expression, NULL, suite_seq, LINENO(exc), - exc->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - else if (NCH(exc) == 4) { - asdl_seq *suite_seq; - expr_ty expression; - identifier e = NEW_IDENTIFIER(CHILD(exc, 3)); - if (!e) - return NULL; - if (forbidden_name(c, e, CHILD(exc, 3), 0)) - return NULL; - expression = ast_for_expr(c, CHILD(exc, 1)); - if (!expression) - return NULL; - suite_seq = ast_for_suite(c, body); - if (!suite_seq) - return NULL; - get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); - - return ExceptHandler(expression, e, suite_seq, LINENO(exc), - exc->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - - PyErr_Format(PyExc_SystemError, - "wrong number of children for 'except' clause: %d", - NCH(exc)); - return NULL; -} - -static stmt_ty -ast_for_try_stmt(struct compiling *c, const node *n) -{ - const int nch = NCH(n); - int end_lineno, end_col_offset, n_except = (nch - 3)/3; - asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL; - excepthandler_ty last_handler; - - REQ(n, try_stmt); - - body = ast_for_suite(c, CHILD(n, 2)); - if (body == NULL) - return NULL; - - if (TYPE(CHILD(n, nch - 3)) == NAME) { - if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) { - if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) { - /* we can assume it's an "else", - because nch >= 9 for try-else-finally and - it would otherwise have a type of except_clause */ - orelse = ast_for_suite(c, CHILD(n, nch - 4)); - if (orelse == NULL) - return NULL; - n_except--; - } - - finally = ast_for_suite(c, CHILD(n, nch - 1)); - if (finally == NULL) - return NULL; - n_except--; - } - else { - /* we can assume it's an "else", - otherwise it would have a type of except_clause */ - orelse = ast_for_suite(c, CHILD(n, nch - 1)); - if (orelse == NULL) - return NULL; - n_except--; - } - } - else if (TYPE(CHILD(n, nch - 3)) != except_clause) { - ast_error(c, n, "malformed 'try' statement"); - return NULL; - } - - if (n_except > 0) { - int i; - /* process except statements to create a try ... except */ - handlers = _Py_asdl_seq_new(n_except, c->c_arena); - if (handlers == NULL) - return NULL; - - for (i = 0; i < n_except; i++) { - excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3), - CHILD(n, 5 + i * 3)); - if (!e) - return NULL; - asdl_seq_SET(handlers, i, e); - } - } - - assert(finally != NULL || asdl_seq_LEN(handlers)); - if (finally != NULL) { - // finally is always last - get_last_end_pos(finally, &end_lineno, &end_col_offset); - } else if (orelse != NULL) { - // otherwise else is last - get_last_end_pos(orelse, &end_lineno, &end_col_offset); - } else { - // inline the get_last_end_pos logic due to layout mismatch - last_handler = (excepthandler_ty) asdl_seq_GET(handlers, n_except - 1); - end_lineno = last_handler->end_lineno; - end_col_offset = last_handler->end_col_offset; - } - return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); -} - -/* with_item: test ['as' expr] */ -static withitem_ty -ast_for_with_item(struct compiling *c, const node *n) -{ - expr_ty context_expr, optional_vars = NULL; - - REQ(n, with_item); - context_expr = ast_for_expr(c, CHILD(n, 0)); - if (!context_expr) - return NULL; - if (NCH(n) == 3) { - optional_vars = ast_for_expr(c, CHILD(n, 2)); - - if (!optional_vars) { - return NULL; - } - if (!set_context(c, optional_vars, Store, n)) { - return NULL; - } - } - - return withitem(context_expr, optional_vars, c->c_arena); -} - -/* with_stmt: 'with' with_item (',' with_item)* ':' [TYPE_COMMENT] suite */ -static stmt_ty -ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async) -{ - const node * const n = is_async ? CHILD(n0, 1) : n0; - int i, n_items, nch_minus_type, has_type_comment, end_lineno, end_col_offset; - asdl_seq *items, *body; - string type_comment; - - if (is_async && c->c_feature_version < 5) { - ast_error(c, n, - "Async with statements are only supported in Python 3.5 and greater"); - return NULL; - } - - REQ(n, with_stmt); - - has_type_comment = TYPE(CHILD(n, NCH(n) - 2)) == TYPE_COMMENT; - nch_minus_type = NCH(n) - has_type_comment; - - n_items = (nch_minus_type - 2) / 2; - items = _Py_asdl_seq_new(n_items, c->c_arena); - if (!items) - return NULL; - for (i = 1; i < nch_minus_type - 2; i += 2) { - withitem_ty item = ast_for_with_item(c, CHILD(n, i)); - if (!item) - return NULL; - asdl_seq_SET(items, (i - 1) / 2, item); - } - - body = ast_for_suite(c, CHILD(n, NCH(n) - 1)); - if (!body) - return NULL; - get_last_end_pos(body, &end_lineno, &end_col_offset); - - if (has_type_comment) { - type_comment = NEW_TYPE_COMMENT(CHILD(n, NCH(n) - 2)); - if (!type_comment) - return NULL; - } - else - type_comment = NULL; - - if (is_async) - return AsyncWith(items, body, type_comment, LINENO(n0), n0->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - else - return With(items, body, type_comment, LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); -} - -static stmt_ty -ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) -{ - /* classdef: 'class' NAME ['(' arglist ')'] ':' suite */ - PyObject *classname; - asdl_seq *s; - expr_ty call; - int end_lineno, end_col_offset; - - REQ(n, classdef); - - if (NCH(n) == 4) { /* class NAME ':' suite */ - s = ast_for_suite(c, CHILD(n, 3)); - if (!s) - return NULL; - get_last_end_pos(s, &end_lineno, &end_col_offset); - - classname = NEW_IDENTIFIER(CHILD(n, 1)); - if (!classname) - return NULL; - if (forbidden_name(c, classname, CHILD(n, 3), 0)) - return NULL; - return ClassDef(classname, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - - if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */ - s = ast_for_suite(c, CHILD(n, 5)); - if (!s) - return NULL; - get_last_end_pos(s, &end_lineno, &end_col_offset); - - classname = NEW_IDENTIFIER(CHILD(n, 1)); - if (!classname) - return NULL; - if (forbidden_name(c, classname, CHILD(n, 3), 0)) - return NULL; - return ClassDef(classname, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); - } - - /* class NAME '(' arglist ')' ':' suite */ - /* build up a fake Call node so we can extract its pieces */ - { - PyObject *dummy_name; - expr_ty dummy; - dummy_name = NEW_IDENTIFIER(CHILD(n, 1)); - if (!dummy_name) - return NULL; - dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, - CHILD(n, 1)->n_end_lineno, CHILD(n, 1)->n_end_col_offset, - c->c_arena); - call = ast_for_call(c, CHILD(n, 3), dummy, - CHILD(n, 1), NULL, CHILD(n, 4)); - if (!call) - return NULL; - } - s = ast_for_suite(c, CHILD(n, 6)); - if (!s) - return NULL; - get_last_end_pos(s, &end_lineno, &end_col_offset); - - classname = NEW_IDENTIFIER(CHILD(n, 1)); - if (!classname) - return NULL; - if (forbidden_name(c, classname, CHILD(n, 1), 0)) - return NULL; - - return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s, - decorator_seq, LINENO(n), n->n_col_offset, - end_lineno, end_col_offset, c->c_arena); -} - -static stmt_ty -ast_for_stmt(struct compiling *c, const node *n) -{ - if (TYPE(n) == stmt) { - assert(NCH(n) == 1); - n = CHILD(n, 0); - } - if (TYPE(n) == simple_stmt) { - assert(num_stmts(n) == 1); - n = CHILD(n, 0); - } - if (TYPE(n) == small_stmt) { - n = CHILD(n, 0); - /* small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt - | import_stmt | global_stmt | nonlocal_stmt | assert_stmt - */ - switch (TYPE(n)) { - case expr_stmt: - return ast_for_expr_stmt(c, n); - case del_stmt: - return ast_for_del_stmt(c, n); - case pass_stmt: - return Pass(LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - case flow_stmt: - return ast_for_flow_stmt(c, n); - case import_stmt: - return ast_for_import_stmt(c, n); - case global_stmt: - return ast_for_global_stmt(c, n); - case nonlocal_stmt: - return ast_for_nonlocal_stmt(c, n); - case assert_stmt: - return ast_for_assert_stmt(c, n); - default: - PyErr_Format(PyExc_SystemError, - "unhandled small_stmt: TYPE=%d NCH=%d\n", - TYPE(n), NCH(n)); - return NULL; - } - } - else { - /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt - | funcdef | classdef | decorated | async_stmt - */ - node *ch = CHILD(n, 0); - REQ(n, compound_stmt); - switch (TYPE(ch)) { - case if_stmt: - return ast_for_if_stmt(c, ch); - case while_stmt: - return ast_for_while_stmt(c, ch); - case for_stmt: - return ast_for_for_stmt(c, ch, 0); - case try_stmt: - return ast_for_try_stmt(c, ch); - case with_stmt: - return ast_for_with_stmt(c, ch, 0); - case funcdef: - return ast_for_funcdef(c, ch, NULL); - case classdef: - return ast_for_classdef(c, ch, NULL); - case decorated: - return ast_for_decorated(c, ch); - case async_stmt: - return ast_for_async_stmt(c, ch); - default: - PyErr_Format(PyExc_SystemError, - "unhandled compound_stmt: TYPE=%d NCH=%d\n", - TYPE(n), NCH(n)); - return NULL; - } - } -} - -static PyObject * -parsenumber_raw(struct compiling *c, const char *s) -{ - const char *end; - long x; - double dx; - Py_complex compl; - int imflag; - - assert(s != NULL); - errno = 0; - end = s + strlen(s) - 1; - imflag = *end == 'j' || *end == 'J'; - if (s[0] == '0') { - x = (long) PyOS_strtoul(s, (char **)&end, 0); - if (x < 0 && errno == 0) { - return PyLong_FromString(s, (char **)0, 0); - } - } - else - x = PyOS_strtol(s, (char **)&end, 0); - if (*end == '\0') { - if (errno != 0) - return PyLong_FromString(s, (char **)0, 0); - return PyLong_FromLong(x); - } - /* XXX Huge floats may silently fail */ - if (imflag) { - compl.real = 0.; - compl.imag = PyOS_string_to_double(s, (char **)&end, NULL); - if (compl.imag == -1.0 && PyErr_Occurred()) - return NULL; - return PyComplex_FromCComplex(compl); - } - else - { - dx = PyOS_string_to_double(s, NULL, NULL); - if (dx == -1.0 && PyErr_Occurred()) - return NULL; - return PyFloat_FromDouble(dx); - } -} - -static PyObject * -parsenumber(struct compiling *c, const char *s) -{ - char *dup, *end; - PyObject *res = NULL; - - assert(s != NULL); - - if (strchr(s, '_') == NULL) { - return parsenumber_raw(c, s); - } - /* Create a duplicate without underscores. */ - dup = PyMem_Malloc(strlen(s) + 1); - if (dup == NULL) { - return PyErr_NoMemory(); - } - end = dup; - for (; *s; s++) { - if (*s != '_') { - *end++ = *s; - } - } - *end = '\0'; - res = parsenumber_raw(c, dup); - PyMem_Free(dup); - return res; -} - -static PyObject * -decode_utf8(struct compiling *c, const char **sPtr, const char *end) -{ - const char *s, *t; - t = s = *sPtr; - /* while (s < end && *s != '\\') s++; */ /* inefficient for u".." */ - while (s < end && (*s & 0x80)) s++; - *sPtr = s; - return PyUnicode_DecodeUTF8(t, s - t, NULL); -} - -static int -warn_invalid_escape_sequence(struct compiling *c, const node *n, - unsigned char first_invalid_escape_char) -{ - PyObject *msg = PyUnicode_FromFormat("invalid escape sequence \\%c", - first_invalid_escape_char); - if (msg == NULL) { - return -1; - } - if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg, - c->c_filename, LINENO(n), - NULL, NULL) < 0) - { - if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { - /* Replace the DeprecationWarning exception with a SyntaxError - to get a more accurate error report */ - PyErr_Clear(); - ast_error(c, n, "%U", msg); - } - Py_DECREF(msg); - return -1; - } - Py_DECREF(msg); - return 0; -} - -static PyObject * -decode_unicode_with_escapes(struct compiling *c, const node *n, const char *s, - size_t len) -{ - PyObject *v, *u; - char *buf; - char *p; - const char *end; - - /* check for integer overflow */ - if (len > SIZE_MAX / 6) - return NULL; - /* "ä" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5 - "\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */ - u = PyBytes_FromStringAndSize((char *)NULL, len * 6); - if (u == NULL) - return NULL; - p = buf = PyBytes_AsString(u); - end = s + len; - while (s < end) { - if (*s == '\\') { - *p++ = *s++; - if (s >= end || *s & 0x80) { - strcpy(p, "u005c"); - p += 5; - if (s >= end) - break; - } - } - if (*s & 0x80) { /* XXX inefficient */ - PyObject *w; - int kind; - const void *data; - Py_ssize_t len, i; - w = decode_utf8(c, &s, end); - if (w == NULL) { - Py_DECREF(u); - return NULL; - } - kind = PyUnicode_KIND(w); - data = PyUnicode_DATA(w); - len = PyUnicode_GET_LENGTH(w); - for (i = 0; i < len; i++) { - Py_UCS4 chr = PyUnicode_READ(kind, data, i); - sprintf(p, "\\U%08x", chr); - p += 10; - } - /* Should be impossible to overflow */ - assert(p - buf <= PyBytes_GET_SIZE(u)); - Py_DECREF(w); - } else { - *p++ = *s++; - } - } - len = p - buf; - s = buf; - - const char *first_invalid_escape; - v = _PyUnicode_DecodeUnicodeEscapeInternal(s, len, NULL, NULL, &first_invalid_escape); - - if (v != NULL && first_invalid_escape != NULL) { - if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) { - /* We have not decref u before because first_invalid_escape points - inside u. */ - Py_XDECREF(u); - Py_DECREF(v); - return NULL; - } - } - Py_XDECREF(u); - return v; -} - -static PyObject * -decode_bytes_with_escapes(struct compiling *c, const node *n, const char *s, - size_t len) -{ - const char *first_invalid_escape; - PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, - &first_invalid_escape); - if (result == NULL) - return NULL; - - if (first_invalid_escape != NULL) { - if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) { - Py_DECREF(result); - return NULL; - } - } - return result; -} - -/* Shift locations for the given node and all its children by adding `lineno` - and `col_offset` to existing locations. */ -static void fstring_shift_node_locations(node *n, int lineno, int col_offset) -{ - n->n_col_offset = n->n_col_offset + col_offset; - n->n_end_col_offset = n->n_end_col_offset + col_offset; - for (int i = 0; i < NCH(n); ++i) { - if (n->n_lineno && n->n_lineno < CHILD(n, i)->n_lineno) { - /* Shifting column offsets unnecessary if there's been newlines. */ - col_offset = 0; - } - fstring_shift_node_locations(CHILD(n, i), lineno, col_offset); - } - n->n_lineno = n->n_lineno + lineno; - n->n_end_lineno = n->n_end_lineno + lineno; -} - -/* Fix locations for the given node and its children. - - `parent` is the enclosing node. - `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 void -fstring_fix_node_location(const node *parent, node *n, char *expr_str) -{ - char *substr = NULL; - char *start; - int lines = LINENO(parent) - 1; - int cols = parent->n_col_offset; - /* Find the full fstring to fix location information in `n`. */ - while (parent && parent->n_type != STRING) - parent = parent->n_child; - if (parent && parent->n_str) { - substr = strstr(parent->n_str, expr_str); - if (substr) { - start = substr; - while (start > parent->n_str) { - if (start[0] == '\n') - break; - start--; - } - cols += (int)(substr - start); - /* adjust the start based on the number of newlines encountered - before the f-string expression */ - for (char* p = parent->n_str; p < substr; p++) { - if (*p == '\n') { - lines++; - } - } - } - } - fstring_shift_node_locations(n, lines, cols); -} - -/* 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(const char *expr_start, const char *expr_end, - struct compiling *c, const node *n) - -{ - node *mod_n; - mod_ty mod; - char *str; - Py_ssize_t len; - const char *s; - - 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) { - ast_error(c, n, "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_Malloc(len + 3); - if (str == NULL) { - PyErr_NoMemory(); - return NULL; - } - - str[0] = '('; - memcpy(str+1, expr_start, len); - str[len+1] = ')'; - str[len+2] = 0; - - PyCompilerFlags cf = _PyCompilerFlags_INIT; - cf.cf_flags = PyCF_ONLY_AST; - mod_n = PyParser_SimpleParseStringFlagsFilename(str, "", - Py_eval_input, 0); - if (!mod_n) { - PyMem_Free(str); - return NULL; - } - /* Reuse str to find the correct column offset. */ - str[0] = '{'; - str[len+1] = '}'; - fstring_fix_node_location(n, mod_n, str); - mod = PyAST_FromNode(mod_n, &cf, "", c->c_arena); - PyMem_Free(str); - PyNode_Free(mod_n); - if (!mod) - return NULL; - return mod->v.Expression.body; -} - -/* 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(const char **str, const char *end, int raw, - PyObject **literal, int recurse_lvl, - struct compiling *c, const node *n) -{ - /* 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') { - if (s < end && *s++ == '{') { - while (s < end && *s++ != '}') { - } - continue; - } - break; - } - if (ch == '{' && warn_invalid_escape_sequence(c, n, ch) < 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; - ast_error(c, n, "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(c, n, literal_start, - s - literal_start); - if (!*literal) - return -1; - } - return result; -} - -/* Forward declaration because parsing is recursive. */ -static expr_ty -fstring_parse(const char **str, const char *end, int raw, int recurse_lvl, - struct compiling *c, const node *n); - -/* 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(const char **str, const char *end, int raw, int recurse_lvl, - PyObject **expr_text, expr_ty *expression, - struct compiling *c, const node *n) -{ - /* 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) { - ast_error(c, n, "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. */ - ast_error(c, n, - "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) { - ast_error(c, n, "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. */ - ast_error(c, n, "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) { - ast_error(c, n, "f-string: unmatched '%c'", ch); - goto error; - } - nested_depth--; - int opening = parenstack[nested_depth]; - if (!((opening == '(' && ch == ')') || - (opening == '[' && ch == ']') || - (opening == '{' && ch == '}'))) - { - ast_error(c, n, - "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 this loop in a string or with mismatched parens, we - don't 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) { - ast_error(c, n, "f-string: unterminated string"); - goto error; - } - if (nested_depth) { - int opening = parenstack[nested_depth - 1]; - ast_error(c, n, "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(expr_start, expr_end, c, n); - if (!simple_expression) - goto error; - - /* Check for =, which puts the text value of the expression in - expr_text. */ - if (**str == '=') { - if (c->c_feature_version < 8) { - ast_error(c, n, - "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; - } - - /* 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 = **str; - *str += 1; - - /* Validate the conversion. */ - if (!(conversion == 's' || conversion == 'r' || conversion == 'a')) { - ast_error(c, n, - "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(str, end, raw, recurse_lvl+1, c, n); - 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. */ - *expression = FormattedValue(simple_expression, conversion, - format_spec, LINENO(n), - n->n_col_offset, n->n_end_lineno, - n->n_end_col_offset, c->c_arena); - if (!*expression) - goto error; - - return 0; - -unexpected_end_of_string: - ast_error(c, n, "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(const char **str, const char *end, int raw, - int recurse_lvl, PyObject **literal, - PyObject **expr_text, expr_ty *expression, - struct compiling *c, const node *n) -{ - int result; - - assert(*literal == NULL && *expression == NULL); - - /* Get any literal string. */ - result = fstring_find_literal(str, end, raw, literal, recurse_lvl, c, n); - 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(str, end, raw, recurse_lvl, expr_text, - expression, c, n) < 0) - goto error; - - return 0; - -error: - Py_CLEAR(*literal); - return -1; -} - -#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; - -#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_seq * -ExprList_Finish(ExprList *l, PyArena *arena) -{ - asdl_seq *seq; - - ExprList_check_invariants(l); - - /* Allocate the asdl_seq and copy the expressions in to it. */ - seq = _Py_asdl_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; -} - -/* 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; - -#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 - -static void -FstringParser_Init(FstringParser *state) -{ - state->last_str = NULL; - state->fmode = 0; - ExprList_Init(&state->expr_list); - FstringParser_check_invariants(state); -} - -static void -FstringParser_Dealloc(FstringParser *state) -{ - FstringParser_check_invariants(state); - - Py_XDECREF(state->last_str); - ExprList_Dealloc(&state->expr_list); -} - -/* Constants for the following */ -static PyObject *u_kind; - -/* Compute 'kind' field for string Constant (either 'u' or None) */ -static PyObject * -make_kind(struct compiling *c, const node *n) -{ - char *s = NULL; - PyObject *kind = NULL; - - /* Find the first string literal, if any */ - while (TYPE(n) != STRING) { - if (NCH(n) == 0) - return NULL; - n = CHILD(n, 0); - } - REQ(n, STRING); - - /* If it starts with 'u', return a PyUnicode "u" string */ - s = STR(n); - if (s && *s == 'u') { - if (!u_kind) { - u_kind = PyUnicode_InternFromString("u"); - if (!u_kind) - return NULL; - } - kind = u_kind; - if (PyArena_AddPyObject(c->c_arena, kind) < 0) { - return NULL; - } - Py_INCREF(kind); - } - return kind; -} - -/* Make a Constant node, but decref the PyUnicode object being added. */ -static expr_ty -make_str_node_and_del(PyObject **str, struct compiling *c, const node* n) -{ - PyObject *s = *str; - PyObject *kind = NULL; - *str = NULL; - assert(PyUnicode_CheckExact(s)); - if (PyArena_AddPyObject(c->c_arena, s) < 0) { - Py_DECREF(s); - return NULL; - } - kind = make_kind(c, n); - if (kind == NULL && PyErr_Occurred()) - return NULL; - return Constant(s, kind, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); -} - -/* Add a non-f-string (that is, a regular literal string). str is - decref'd. */ -static int -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. */ -static int -FstringParser_ConcatFstring(FstringParser *state, const char **str, - const char *end, int raw, int recurse_lvl, - struct compiling *c, const node *n) -{ - 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(str, end, raw, recurse_lvl, - &literal, &expr_text, - &expression, c, n); - if (result < 0) - return -1; - - /* Add the literal, if any. */ - if (literal && FstringParser_ConcatAndDel(state, literal) < 0) { - Py_XDECREF(expr_text); - return -1; - } - /* Add the expr_text, if any. */ - if (expr_text && 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) { - /* Do nothing. No previous literal. */ - } else { - /* Convert the existing last_str literal to a Constant node. */ - expr_ty str = make_str_node_and_del(&state->last_str, c, n); - if (!str || ExprList_Append(&state->expr_list, 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) { - ast_error(c, n, "f-string: unexpected end of string"); - return -1; - } - if (recurse_lvl != 0 && **str != '}') { - ast_error(c, n, "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. */ -static expr_ty -FstringParser_Finish(FstringParser *state, struct compiling *c, - const node *n) -{ - asdl_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 make_str_node_and_del(&state->last_str, c, n); - } - - /* 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(&state->last_str, c, n); - if (!str || ExprList_Append(&state->expr_list, str) < 0) - goto error; - } - /* This has already been freed. */ - assert(state->last_str == NULL); - - seq = ExprList_Finish(&state->expr_list, c->c_arena); - if (!seq) - goto error; - - return JoinedStr(seq, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - -error: - 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(const char **str, const char *end, int raw, int recurse_lvl, - struct compiling *c, const node *n) -{ - FstringParser state; - - FstringParser_Init(&state); - if (FstringParser_ConcatFstring(&state, str, end, raw, recurse_lvl, - c, n) < 0) { - FstringParser_Dealloc(&state); - return NULL; - } - - return FstringParser_Finish(&state, c, n); -} - -/* n is a Python string literal, including the bracketing quote - characters, and r, b, u, &/or f prefixes (if any), and embedded - escape sequences (if any). 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. -*/ -static int -parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode, - PyObject **result, const char **fstr, Py_ssize_t *fstrlen) -{ - size_t len; - const char *s = STR(n); - int quote = Py_CHARMASK(*s); - int fmode = 0; - *bytesmode = 0; - *rawmode = 0; - *result = NULL; - *fstr = NULL; - if (Py_ISALPHA(quote)) { - while (!*bytesmode || !*rawmode) { - if (quote == 'b' || quote == 'B') { - quote = *++s; - *bytesmode = 1; - } - else if (quote == 'u' || quote == 'U') { - quote = *++s; - } - else if (quote == 'r' || quote == 'R') { - quote = *++s; - *rawmode = 1; - } - else if (quote == 'f' || quote == 'F') { - quote = *++s; - fmode = 1; - } - else { - break; - } - } - } - - /* fstrings are only allowed in Python 3.6 and greater */ - if (fmode && c->c_feature_version < 6) { - ast_error(c, n, "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; - } - /* 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; - } - if (s[--len] != quote) { - /* Last quote char must match the first. */ - PyErr_BadInternalCall(); - return -1; - } - if (len >= 4 && s[0] == quote && s[1] == quote) { - /* A triple quoted string. We've already skipped one quote at - the start and one at the end of the string. Now skip the - two at the start. */ - s += 2; - len -= 2; - /* And check that the last two match. */ - if (s[--len] != quote || s[--len] != quote) { - PyErr_BadInternalCall(); - return -1; - } - } - - 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) { - /* Disallow non-ASCII characters. */ - const char *ch; - for (ch = s; *ch; ch++) { - if (Py_CHARMASK(*ch) >= 0x80) { - ast_error(c, n, - "bytes can only contain ASCII " - "literal characters."); - return -1; - } - } - if (*rawmode) - *result = PyBytes_FromStringAndSize(s, len); - else - *result = decode_bytes_with_escapes(c, n, s, len); - } else { - if (*rawmode) - *result = PyUnicode_DecodeUTF8Stateful(s, len, NULL, NULL); - else - *result = decode_unicode_with_escapes(c, n, s, len); - } - return *result == NULL ? -1 : 0; -} - -/* Accepts a STRING+ atom, and produces an expr_ty node. Run through - each STRING atom, and process it as needed. For bytes, just - concatenate them together, and the result will be a Constant node. For - normal strings and f-strings, concatenate them together. The result - will be a Constant node if there were no f-strings; a FormattedValue - node if there's just an f-string (with no leading or trailing - literals), or a JoinedStr node if there are multiple f-strings or - any literals involved. */ -static expr_ty -parsestrplus(struct compiling *c, const node *n) -{ - int bytesmode = 0; - PyObject *bytes_str = NULL; - int i; - - FstringParser state; - FstringParser_Init(&state); - - for (i = 0; i < NCH(n); i++) { - int this_bytesmode; - int this_rawmode; - PyObject *s; - const char *fstr; - Py_ssize_t fstrlen = -1; /* Silence a compiler warning. */ - - REQ(CHILD(n, i), STRING); - if (parsestr(c, CHILD(n, i), &this_bytesmode, &this_rawmode, &s, - &fstr, &fstrlen) != 0) - goto error; - - /* Check that we're not mixing bytes with unicode. */ - if (i != 0 && bytesmode != this_bytesmode) { - ast_error(c, n, "cannot mix bytes and nonbytes literals"); - /* s is NULL if the current string part is an f-string. */ - Py_XDECREF(s); - goto error; - } - bytesmode = this_bytesmode; - - if (fstr != NULL) { - int result; - assert(s == NULL && !bytesmode); - /* This is an f-string. Parse and concatenate it. */ - result = FstringParser_ConcatFstring(&state, &fstr, fstr+fstrlen, - this_rawmode, 0, c, n); - if (result < 0) - goto error; - } else { - /* A string or byte string. */ - assert(s != NULL && fstr == NULL); - - assert(bytesmode ? PyBytes_CheckExact(s) : - PyUnicode_CheckExact(s)); - - if (bytesmode) { - /* For bytes, concat as we go. */ - if (i == 0) { - /* First time, just remember this value. */ - bytes_str = s; - } else { - PyBytes_ConcatAndDel(&bytes_str, s); - if (!bytes_str) - goto error; - } - } else { - /* This is a regular string. Concatenate it. */ - if (FstringParser_ConcatAndDel(&state, s) < 0) - goto error; - } - } - } - if (bytesmode) { - /* Just return the bytes object and we're done. */ - if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0) - goto error; - return Constant(bytes_str, NULL, LINENO(n), n->n_col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); - } - - /* We're not a bytes string, bytes_str should never have been set. */ - assert(bytes_str == NULL); - - return FstringParser_Finish(&state, c, n); - -error: - Py_XDECREF(bytes_str); - FstringParser_Dealloc(&state); - return NULL; -} - PyObject * -_PyAST_GetDocString(asdl_seq *body) +_PyAST_GetDocString(asdl_stmt_seq *body) { if (!asdl_seq_LEN(body)) { return NULL; } - stmt_ty st = (stmt_ty)asdl_seq_GET(body, 0); + stmt_ty st = asdl_seq_GET(body, 0); if (st->kind != Expr_kind) { return NULL; } diff --git a/contrib/tools/python3/src/Python/ast_opt.c b/contrib/tools/python3/src/Python/ast_opt.c index ff786d6f8d6..c1fdea3a88c 100644 --- a/contrib/tools/python3/src/Python/ast_opt.c +++ b/contrib/tools/python3/src/Python/ast_opt.c @@ -1,12 +1,15 @@ /* AST Optimizer */ #include "Python.h" -#include "Python-ast.h" -#include "ast.h" +#include "pycore_ast.h" // _PyAST_GetDocString() +#include "pycore_compile.h" // _PyASTOptimizeState +#include "pycore_pystate.h" // _PyThreadState_GET() static int make_const(expr_ty node, PyObject *val, PyArena *arena) { + // Even if no new value was calculated, make_const may still + // need to clear an error (e.g. for division by zero) if (val == NULL) { if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) { return 0; @@ -14,7 +17,7 @@ make_const(expr_ty node, PyObject *val, PyArena *arena) PyErr_Clear(); return 1; } - if (PyArena_AddPyObject(arena, val) < 0) { + if (_PyArena_AddPyObject(arena, val) < 0) { Py_DECREF(val); return 0; } @@ -49,7 +52,7 @@ fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) of !=. Detecting such cases doesn't seem worthwhile. Python uses for 'is subset'/'is superset' operations on sets. They don't satisfy not folding laws. */ - int op = asdl_seq_GET(arg->v.Compare.ops, 0); + cmpop_ty op = asdl_seq_GET(arg->v.Compare.ops, 0); switch (op) { case Is: op = IsNot; @@ -63,8 +66,17 @@ fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) case NotIn: op = In; break; - default: - op = 0; + // The remaining comparison operators can't be safely inverted + case Eq: + case NotEq: + case Lt: + case LtE: + case Gt: + case GtE: + op = 0; // The AST enums leave "0" free as an "unused" marker + break; + // No default case, so the compiler will emit a warning if new + // comparison operators are added without being handled here } if (op) { asdl_seq_SET(arg->v.Compare.ops, 0, op); @@ -224,7 +236,7 @@ fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) PyObject *lv = lhs->v.Constant.value; PyObject *rv = rhs->v.Constant.value; - PyObject *newval; + PyObject *newval = NULL; switch (node->v.BinOp.op) { case Add: @@ -263,15 +275,18 @@ fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) case BitAnd: newval = PyNumber_And(lv, rv); break; - default: // Unknown operator + // No builtin constants implement the following operators + case MatMult: return 1; + // No default case, so the compiler will emit a warning if new binary + // operators are added without being handled here } return make_const(node, newval, arena); } static PyObject* -make_const_tuple(asdl_seq *elts) +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); @@ -337,7 +352,7 @@ fold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state) PyObject *newval; if (arg->kind == List_kind) { /* First change a list into tuple. */ - asdl_seq *elts = arg->v.List.elts; + asdl_expr_seq *elts = arg->v.List.elts; Py_ssize_t n = asdl_seq_LEN(elts); for (Py_ssize_t i = 0; i < n; i++) { expr_ty e = (expr_ty)asdl_seq_GET(elts, i); @@ -368,7 +383,7 @@ static int fold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) { asdl_int_seq *ops; - asdl_seq *args; + asdl_expr_seq *args; Py_ssize_t i; ops = node->v.Compare.ops; @@ -395,6 +410,9 @@ static int astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState static int astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 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); + #define CALL(FUNC, TYPE, ARG) \ if (!FUNC((ARG), ctx_, state)) \ return 0; @@ -405,9 +423,9 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOp #define CALL_SEQ(FUNC, TYPE, ARG) { \ int i; \ - asdl_seq *seq = (ARG); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \ for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE elt = (TYPE)asdl_seq_GET(seq, i); \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ if (elt != NULL && !FUNC(elt, ctx_, state)) \ return 0; \ } \ @@ -424,19 +442,20 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOp } static int -astfold_body(asdl_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state) +astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state) { int docstring = _PyAST_GetDocString(stmts) != NULL; - CALL_SEQ(astfold_stmt, stmt_ty, stmts); + CALL_SEQ(astfold_stmt, stmt, stmts); if (!docstring && _PyAST_GetDocString(stmts) != NULL) { stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0); - asdl_seq *values = _Py_asdl_seq_new(1, ctx_); + asdl_expr_seq *values = _Py_asdl_expr_seq_new(1, ctx_); if (!values) { return 0; } asdl_seq_SET(values, 0, st->v.Expr.value); - expr_ty expr = JoinedStr(values, st->lineno, st->col_offset, - st->end_lineno, st->end_col_offset, ctx_); + expr_ty expr = _PyAST_JoinedStr(values, st->lineno, st->col_offset, + st->end_lineno, st->end_col_offset, + ctx_); if (!expr) { return 0; } @@ -453,13 +472,16 @@ astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL(astfold_body, asdl_seq, node_->v.Module.body); break; case Interactive_kind: - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Interactive.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.Interactive.body); break; case Expression_kind: CALL(astfold_expr, expr_ty, node_->v.Expression.body); break; - default: + // The following top level nodes don't participate in constant folding + case FunctionType_kind: break; + // No default case, so the compiler will emit a warning if new top level + // compilation nodes are added without being handled here } return 1; } @@ -467,9 +489,14 @@ astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + return 0; + } switch (node_->kind) { case BoolOp_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.BoolOp.values); + CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values); break; case BinOp_kind: CALL(astfold_expr, expr_ty, node_->v.BinOp.left); @@ -490,28 +517,28 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse); break; case Dict_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.keys); - CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.values); + CALL_SEQ(astfold_expr, expr, node_->v.Dict.keys); + CALL_SEQ(astfold_expr, expr, node_->v.Dict.values); break; case Set_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Set.elts); + CALL_SEQ(astfold_expr, expr, node_->v.Set.elts); break; case ListComp_kind: CALL(astfold_expr, expr_ty, node_->v.ListComp.elt); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.ListComp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.ListComp.generators); break; case SetComp_kind: CALL(astfold_expr, expr_ty, node_->v.SetComp.elt); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.SetComp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.SetComp.generators); break; case DictComp_kind: CALL(astfold_expr, expr_ty, node_->v.DictComp.key); CALL(astfold_expr, expr_ty, node_->v.DictComp.value); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.DictComp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.DictComp.generators); break; case GeneratorExp_kind: CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.GeneratorExp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.GeneratorExp.generators); break; case Await_kind: CALL(astfold_expr, expr_ty, node_->v.Await.value); @@ -524,20 +551,20 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) break; case Compare_kind: CALL(astfold_expr, expr_ty, node_->v.Compare.left); - CALL_SEQ(astfold_expr, expr_ty, node_->v.Compare.comparators); + CALL_SEQ(astfold_expr, expr, node_->v.Compare.comparators); CALL(fold_compare, expr_ty, node_); break; case Call_kind: CALL(astfold_expr, expr_ty, node_->v.Call.func); - CALL_SEQ(astfold_expr, expr_ty, node_->v.Call.args); - CALL_SEQ(astfold_keyword, keyword_ty, node_->v.Call.keywords); + CALL_SEQ(astfold_expr, expr, node_->v.Call.args); + CALL_SEQ(astfold_keyword, keyword, node_->v.Call.keywords); break; case FormattedValue_kind: CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value); CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec); break; case JoinedStr_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.JoinedStr.values); + CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values); break; case Attribute_kind: CALL(astfold_expr, expr_ty, node_->v.Attribute.value); @@ -556,21 +583,29 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step); break; case List_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.List.elts); + CALL_SEQ(astfold_expr, expr, node_->v.List.elts); break; case Tuple_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Tuple.elts); + CALL_SEQ(astfold_expr, expr, node_->v.Tuple.elts); CALL(fold_tuple, expr_ty, node_); break; case Name_kind: if (node_->v.Name.ctx == Load && _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) { + state->recursion_depth--; return make_const(node_, PyBool_FromLong(!state->optimize), ctx_); } break; - default: + case NamedExpr_kind: + CALL(astfold_expr, expr_ty, node_->v.NamedExpr.value); + break; + case Constant_kind: + // Already a constant, nothing further to do break; + // No default case, so the compiler will emit a warning if new expression + // kinds are added without being handled here } + state->recursion_depth--; return 1; } @@ -586,7 +621,7 @@ astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState { CALL(astfold_expr, expr_ty, node_->target); CALL(astfold_expr, expr_ty, node_->iter); - CALL_SEQ(astfold_expr, expr_ty, node_->ifs); + CALL_SEQ(astfold_expr, expr, node_->ifs); CALL(fold_iter, expr_ty, node_->iter); return 1; @@ -595,13 +630,13 @@ astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { - CALL_SEQ(astfold_arg, arg_ty, node_->posonlyargs); - CALL_SEQ(astfold_arg, arg_ty, node_->args); + CALL_SEQ(astfold_arg, arg, node_->posonlyargs); + CALL_SEQ(astfold_arg, arg, node_->args); CALL_OPT(astfold_arg, arg_ty, node_->vararg); - CALL_SEQ(astfold_arg, arg_ty, node_->kwonlyargs); - CALL_SEQ(astfold_expr, expr_ty, node_->kw_defaults); + CALL_SEQ(astfold_arg, arg, node_->kwonlyargs); + CALL_SEQ(astfold_expr, expr, node_->kw_defaults); CALL_OPT(astfold_arg, arg_ty, node_->kwarg); - CALL_SEQ(astfold_expr, expr_ty, node_->defaults); + CALL_SEQ(astfold_expr, expr, node_->defaults); return 1; } @@ -617,11 +652,16 @@ astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + return 0; + } switch (node_->kind) { case FunctionDef_kind: CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body); - CALL_SEQ(astfold_expr, expr_ty, node_->v.FunctionDef.decorator_list); + CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list); if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns); } @@ -629,25 +669,25 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case AsyncFunctionDef_kind: CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body); - CALL_SEQ(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.decorator_list); + CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list); if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns); } break; case ClassDef_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.bases); - CALL_SEQ(astfold_keyword, keyword_ty, node_->v.ClassDef.keywords); + 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); - CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.decorator_list); + CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.decorator_list); break; case Return_kind: CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value); break; case Delete_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Delete.targets); + CALL_SEQ(astfold_expr, expr, node_->v.Delete.targets); break; case Assign_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Assign.targets); + CALL_SEQ(astfold_expr, expr, node_->v.Assign.targets); CALL(astfold_expr, expr_ty, node_->v.Assign.value); break; case AugAssign_kind: @@ -664,44 +704,44 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case For_kind: CALL(astfold_expr, expr_ty, node_->v.For.target); CALL(astfold_expr, expr_ty, node_->v.For.iter); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.For.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.For.orelse); CALL(fold_iter, expr_ty, node_->v.For.iter); break; case AsyncFor_kind: CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target); CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.orelse); break; case While_kind: CALL(astfold_expr, expr_ty, node_->v.While.test); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.While.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.While.orelse); break; case If_kind: CALL(astfold_expr, expr_ty, node_->v.If.test); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.If.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.If.orelse); break; case With_kind: - CALL_SEQ(astfold_withitem, withitem_ty, node_->v.With.items); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.With.body); + CALL_SEQ(astfold_withitem, withitem, node_->v.With.items); + CALL_SEQ(astfold_stmt, stmt, node_->v.With.body); break; case AsyncWith_kind: - CALL_SEQ(astfold_withitem, withitem_ty, node_->v.AsyncWith.items); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncWith.body); + CALL_SEQ(astfold_withitem, withitem, node_->v.AsyncWith.items); + CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncWith.body); break; case Raise_kind: CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc); CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause); break; case Try_kind: - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.body); - CALL_SEQ(astfold_excepthandler, excepthandler_ty, node_->v.Try.handlers); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.orelse); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.finalbody); + CALL_SEQ(astfold_stmt, stmt, node_->v.Try.body); + CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.Try.handlers); + CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody); break; case Assert_kind: CALL(astfold_expr, expr_ty, node_->v.Assert.test); @@ -710,9 +750,23 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case Expr_kind: CALL(astfold_expr, expr_ty, node_->v.Expr.value); break; - default: - break; + case Match_kind: + CALL(astfold_expr, expr_ty, node_->v.Match.subject); + CALL_SEQ(astfold_match_case, match_case, node_->v.Match.cases); + break; + // The following statements don't contain any subexpressions to be folded + case Import_kind: + case ImportFrom_kind: + case Global_kind: + case Nonlocal_kind: + case Pass_kind: + case Break_kind: + case Continue_kind: + break; + // No default case, so the compiler will emit a warning if new statement + // kinds are added without being handled here } + state->recursion_depth--; return 1; } @@ -722,10 +776,10 @@ astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState switch (node_->kind) { case ExceptHandler_kind: CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.ExceptHandler.body); - break; - default: + CALL_SEQ(astfold_stmt, stmt, node_->v.ExceptHandler.body); break; + // No default case, so the compiler will emit a warning if new handler + // kinds are added without being handled here } return 1; } @@ -738,15 +792,98 @@ astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) return 1; } +static int +astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) +{ + // Currently, this is really only used to form complex/negative numeric + // constants in MatchValue and MatchMapping nodes + // We still recurse into all subexpressions and subpatterns anyway + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + return 0; + } + switch (node_->kind) { + case MatchValue_kind: + CALL(astfold_expr, expr_ty, node_->v.MatchValue.value); + break; + case MatchSingleton_kind: + break; + case MatchSequence_kind: + CALL_SEQ(astfold_pattern, pattern, node_->v.MatchSequence.patterns); + break; + case MatchMapping_kind: + CALL_SEQ(astfold_expr, expr, node_->v.MatchMapping.keys); + CALL_SEQ(astfold_pattern, pattern, node_->v.MatchMapping.patterns); + break; + case MatchClass_kind: + CALL(astfold_expr, expr_ty, node_->v.MatchClass.cls); + CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.patterns); + CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.kwd_patterns); + break; + case MatchStar_kind: + break; + case MatchAs_kind: + if (node_->v.MatchAs.pattern) { + CALL(astfold_pattern, pattern_ty, node_->v.MatchAs.pattern); + } + break; + case MatchOr_kind: + CALL_SEQ(astfold_pattern, pattern, node_->v.MatchOr.patterns); + break; + // No default case, so the compiler will emit a warning if new pattern + // kinds are added without being handled here + } + state->recursion_depth--; + return 1; +} + +static int +astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) +{ + CALL(astfold_pattern, expr_ty, node_->pattern); + CALL_OPT(astfold_expr, expr_ty, node_->guard); + CALL_SEQ(astfold_stmt, stmt, node_->body); + return 1; +} + #undef CALL #undef CALL_OPT #undef CALL_SEQ #undef CALL_INT_SEQ +/* See comments in symtable.c. */ +#define COMPILER_STACK_FRAME_SCALE 3 + 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 */ + tstate = _PyThreadState_GET(); + if (!tstate) { + return 0; + } + /* Be careful here to prevent overflow. */ + starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? + tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; + 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; + int ret = astfold_mod(mod, arena, state); assert(ret || PyErr_Occurred()); + + /* Check that the recursion depth counting balanced correctly */ + if (ret && state->recursion_depth != starting_recursion_depth) { + PyErr_Format(PyExc_SystemError, + "AST optimizer recursion depth mismatch (before=%d, after=%d)", + starting_recursion_depth, state->recursion_depth); + return 0; + } + return ret; } diff --git a/contrib/tools/python3/src/Python/ast_unparse.c b/contrib/tools/python3/src/Python/ast_unparse.c index e699751a05a..126e9047d58 100644 --- a/contrib/tools/python3/src/Python/ast_unparse.c +++ b/contrib/tools/python3/src/Python/ast_unparse.c @@ -1,7 +1,12 @@ -#include /* DBL_MAX_10_EXP */ -#include #include "Python.h" -#include "Python-ast.h" +#include "pycore_ast.h" // expr_ty +#include // DBL_MAX_10_EXP +#include + +/* This limited unparser is used to convert annotations back to strings + * during compilation rather than being a full AST unparser. + * See ast.unparse for a full unparser (written in Python) + */ static PyObject *_str_open_br; static PyObject *_str_dbl_open_br; @@ -117,7 +122,7 @@ static int append_ast_boolop(_PyUnicodeWriter *writer, expr_ty e, int level) { Py_ssize_t i, value_count; - asdl_seq *values; + asdl_expr_seq *values; const char *op = (e->v.BoolOp.op == And) ? " and " : " or "; int pr = (e->v.BoolOp.op == And) ? PR_AND : PR_OR; @@ -398,7 +403,7 @@ append_ast_comprehension(_PyUnicodeWriter *writer, comprehension_ty gen) } static int -append_ast_comprehensions(_PyUnicodeWriter *writer, asdl_seq *comprehensions) +append_ast_comprehensions(_PyUnicodeWriter *writer, asdl_comprehension_seq *comprehensions) { Py_ssize_t i, gen_count; gen_count = asdl_seq_LEN(comprehensions); @@ -453,7 +458,7 @@ append_ast_compare(_PyUnicodeWriter *writer, expr_ty e, int level) { const char *op; Py_ssize_t i, comparator_count; - asdl_seq *comparators; + asdl_expr_seq *comparators; asdl_int_seq *ops; APPEND_STR_IF(level > PR_CMP, "("); @@ -612,7 +617,7 @@ append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) /* Build body separately to enable wrapping the entire stream of Strs, Constants and FormattedValues in one opening and one closing quote. */ static PyObject * -build_fstring_body(asdl_seq *values, bool is_format_spec) +build_fstring_body(asdl_expr_seq *values, bool is_format_spec) { Py_ssize_t i, value_count; _PyUnicodeWriter body_writer; @@ -912,11 +917,11 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) return append_ast_tuple(writer, e, level); case NamedExpr_kind: return append_named_expr(writer, e, level); - default: - PyErr_SetString(PyExc_SystemError, - "unknown expression kind"); - return -1; + // No default so compiler emits a warning for unhandled cases } + PyErr_SetString(PyExc_SystemError, + "unknown expression kind"); + return -1; } static int diff --git a/contrib/tools/python3/src/Python/bltinmodule.c b/contrib/tools/python3/src/Python/bltinmodule.c index 21c70f9a6c7..b0162e5e872 100644 --- a/contrib/tools/python3/src/Python/bltinmodule.c +++ b/contrib/tools/python3/src/Python/bltinmodule.c @@ -2,12 +2,13 @@ #include "Python.h" #include -#include "ast.h" -#undef Yield /* undefine macro conflicting with */ -#include "pycore_object.h" -#include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tupleobject.h" +#include "pycore_ast.h" // _PyAST_Validate() +#include "pycore_compile.h" // _PyAST_Compile() +#include "pycore_object.h" // _Py_AddToAllObjects() +#include "pycore_pyerrors.h" // _PyErr_NoMemory() +#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_tuple.h" // _PyTuple_FromArray() +#include "pycore_ceval.h" // _PyEval_Vector() _Py_IDENTIFIER(__builtins__); _Py_IDENTIFIER(__dict__); @@ -210,9 +211,9 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py_TYPE(ns)->tp_name); goto error; } - cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns, - NULL, 0, NULL, 0, NULL, 0, NULL, - PyFunction_GET_CLOSURE(func)); + PyFrameConstructor *f = PyFunction_AS_FRAME_CONSTRUCTOR(func); + PyThreadState *tstate = PyThreadState_GET(); + cell = _PyEval_Vector(tstate, f, ns, NULL, 0, NULL); if (cell != NULL) { if (bases != orig_bases) { if (PyMapping_SetItemString(ns, "__orig_bases__", orig_bases) < 0) { @@ -523,8 +524,40 @@ filter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + + lz->func = Py_NewRef(func); + lz->it = it; + + return (PyObject *)lz; +} + +static PyObject * +filter_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + PyTypeObject *tp = (PyTypeObject *)type; + if (tp == &PyFilter_Type && !_PyArg_NoKwnames("filter", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("filter", nargs, 2, 2)) { + return NULL; + } + + PyObject *it = PyObject_GetIter(args[1]); + if (it == NULL) { + return NULL; + } + + filterobject *lz = (filterobject *)tp->tp_alloc(tp, 0); + + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + + lz->func = Py_NewRef(args[0]); lz->it = it; return (PyObject *)lz; @@ -643,6 +676,7 @@ PyTypeObject PyFilter_Type = { PyType_GenericAlloc, /* tp_alloc */ filter_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)filter_vectorcall }; @@ -784,21 +818,17 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, PyArena *arena; mod_ty mod; - arena = PyArena_New(); + arena = _PyArena_New(); if (arena == NULL) goto error; mod = PyAST_obj2mod(source, arena, compile_mode); - if (mod == NULL) { - PyArena_Free(arena); + if (mod == NULL || !_PyAST_Validate(mod)) { + _PyArena_Free(arena); goto error; } - if (!PyAST_Validate(mod)) { - PyArena_Free(arena); - goto error; - } - result = (PyObject*)PyAST_CompileObject(mod, filename, - &cf, optimize, arena); - PyArena_Free(arena); + result = (PyObject*)_PyAST_Compile(mod, filename, + &cf, optimize, arena); + _PyArena_Free(arena); } goto finally; } @@ -915,12 +945,12 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, return NULL; } - if (_PyDict_GetItemIdWithError(globals, &PyId___builtins__) == NULL) { - if (_PyDict_SetItemId(globals, &PyId___builtins__, - PyEval_GetBuiltins()) != 0) - return NULL; + int r = _PyDict_ContainsId(globals, &PyId___builtins__); + if (r == 0) { + r = _PyDict_SetItemId(globals, &PyId___builtins__, + PyEval_GetBuiltins()); } - else if (PyErr_Occurred()) { + if (r < 0) { return NULL; } @@ -1003,12 +1033,12 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, Py_TYPE(locals)->tp_name); return NULL; } - if (_PyDict_GetItemIdWithError(globals, &PyId___builtins__) == NULL) { - if (_PyDict_SetItemId(globals, &PyId___builtins__, - PyEval_GetBuiltins()) != 0) - return NULL; + int r = _PyDict_ContainsId(globals, &PyId___builtins__); + if (r == 0) { + r = _PyDict_SetItemId(globals, &PyId___builtins__, + PyEval_GetBuiltins()); } - else if (PyErr_Occurred()) { + if (r < 0) { return NULL; } @@ -1220,8 +1250,48 @@ map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } lz->iters = iters; func = PyTuple_GET_ITEM(args, 0); - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); + + return (PyObject *)lz; +} + +static PyObject * +map_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + PyTypeObject *tp = (PyTypeObject *)type; + if (tp == &PyMap_Type && !_PyArg_NoKwnames("map", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs < 2) { + PyErr_SetString(PyExc_TypeError, + "map() must have at least two arguments."); + return NULL; + } + + PyObject *iters = PyTuple_New(nargs-1); + if (iters == NULL) { + return NULL; + } + + for (int i=1; itp_alloc(tp, 0); + if (lz == NULL) { + Py_DECREF(iters); + return NULL; + } + lz->iters = iters; + lz->func = Py_NewRef(args[0]); return (PyObject *)lz; } @@ -1359,6 +1429,7 @@ PyTypeObject PyMap_Type = { PyType_GenericAlloc, /* tp_alloc */ map_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)map_vectorcall }; @@ -1526,6 +1597,62 @@ 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 + + async_iterable: object + / + +Return an AsyncIterator for an AsyncIterable object. +[clinic start generated code]*/ + +static PyObject * +builtin_aiter(PyObject *module, PyObject *async_iterable) +/*[clinic end generated code: output=1bae108d86f7960e input=473993d0cacc7d23]*/ +{ + return PyObject_GetAIter(async_iterable); +} + +PyObject *PyAnextAwaitable_New(PyObject *, PyObject *); + +/*[clinic input] +anext as builtin_anext + + aiterator: object + default: object = NULL + / + +Return the next item from the async iterator. +[clinic start generated code]*/ + +static PyObject * +builtin_anext_impl(PyObject *module, PyObject *aiterator, + PyObject *default_value) +/*[clinic end generated code: output=f02c060c163a81fa input=699d11f4e38eca24]*/ +{ + PyTypeObject *t; + PyObject *awaitable; + + t = Py_TYPE(aiterator); + if (t->tp_as_async == NULL || t->tp_as_async->am_anext == NULL) { + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not an async iterator", + t->tp_name); + return NULL; + } + + awaitable = (*t->tp_as_async->am_anext)(aiterator); + if (default_value == NULL) { + return awaitable; + } + + PyObject* new_awaitable = PyAnextAwaitable_New( + awaitable, default_value); + Py_DECREF(awaitable); + return new_awaitable; +} + + /*[clinic input] len as builtin_len @@ -2080,7 +2207,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) Py_DECREF(stdin_encoding); Py_DECREF(stdin_errors); Py_XDECREF(po); - PyMem_FREE(s); + PyMem_Free(s); if (result != NULL) { if (PySys_Audit("builtins.input/result", "O", result) < 0) { @@ -2485,17 +2612,17 @@ issubclass as builtin_issubclass class_or_tuple: object / -Return whether 'cls' is a derived from another class or is the same class. +Return whether 'cls' is derived from another class or is the same class. A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B) -or ...`` etc. +or ...``. [clinic start generated code]*/ static PyObject * builtin_issubclass_impl(PyObject *module, PyObject *cls, PyObject *class_or_tuple) -/*[clinic end generated code: output=358412410cd7a250 input=af5f35e9ceaddaf6]*/ +/*[clinic end generated code: output=358412410cd7a250 input=a24b9f3d58c370d6]*/ { int retval; @@ -2508,9 +2635,10 @@ builtin_issubclass_impl(PyObject *module, PyObject *cls, typedef struct { PyObject_HEAD - Py_ssize_t tuplesize; - PyObject *ittuple; /* tuple of iterators */ + Py_ssize_t tuplesize; + PyObject *ittuple; /* tuple of iterators */ PyObject *result; + int strict; } zipobject; static PyObject * @@ -2521,9 +2649,21 @@ zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *ittuple; /* tuple of iterators */ PyObject *result; Py_ssize_t tuplesize; + int strict = 0; - if (type == &PyZip_Type && !_PyArg_NoKeywords("zip", kwds)) - return NULL; + if (kwds) { + PyObject *empty = PyTuple_New(0); + if (empty == NULL) { + return NULL; + } + static char *kwlist[] = {"strict", NULL}; + int parsed = PyArg_ParseTupleAndKeywords( + empty, kwds, "|$p:zip", kwlist, &strict); + Py_DECREF(empty); + if (!parsed) { + return NULL; + } + } /* args must be a tuple */ assert(PyTuple_Check(args)); @@ -2564,6 +2704,7 @@ zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) lz->ittuple = ittuple; lz->tuplesize = tuplesize; lz->result = result; + lz->strict = strict; return (PyObject *)lz; } @@ -2604,6 +2745,9 @@ zip_next(zipobject *lz) item = (*Py_TYPE(it)->tp_iternext)(it); if (item == NULL) { Py_DECREF(result); + if (lz->strict) { + goto check; + } return NULL; } olditem = PyTuple_GET_ITEM(result, i); @@ -2624,28 +2768,85 @@ zip_next(zipobject *lz) item = (*Py_TYPE(it)->tp_iternext)(it); if (item == NULL) { Py_DECREF(result); + if (lz->strict) { + goto check; + } return NULL; } PyTuple_SET_ITEM(result, i, item); } } return result; +check: + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + // next() on argument i raised an exception (not StopIteration) + return NULL; + } + PyErr_Clear(); + } + if (i) { + // ValueError: zip() argument 2 is shorter than argument 1 + // ValueError: zip() argument 3 is shorter than arguments 1-2 + const char* plural = i == 1 ? " " : "s 1-"; + return PyErr_Format(PyExc_ValueError, + "zip() argument %d is shorter than argument%s%d", + i + 1, plural, i); + } + for (i = 1; i < tuplesize; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); + item = (*Py_TYPE(it)->tp_iternext)(it); + if (item) { + Py_DECREF(item); + const char* plural = i == 1 ? " " : "s 1-"; + return PyErr_Format(PyExc_ValueError, + "zip() argument %d is longer than argument%s%d", + i + 1, plural, i); + } + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + // next() on argument i raised an exception (not StopIteration) + return NULL; + } + PyErr_Clear(); + } + // Argument i is exhausted. So far so good... + } + // All arguments are exhausted. Success! + return NULL; } static PyObject * zip_reduce(zipobject *lz, PyObject *Py_UNUSED(ignored)) { /* Just recreate the zip with the internal iterator tuple */ - return Py_BuildValue("OO", Py_TYPE(lz), lz->ittuple); + if (lz->strict) { + return PyTuple_Pack(3, Py_TYPE(lz), lz->ittuple, Py_True); + } + return PyTuple_Pack(2, Py_TYPE(lz), lz->ittuple); +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyObject * +zip_setstate(zipobject *lz, PyObject *state) +{ + int strict = PyObject_IsTrue(state); + if (strict < 0) { + return NULL; + } + lz->strict = strict; + Py_RETURN_NONE; } static PyMethodDef zip_methods[] = { {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc}, - {NULL, NULL} /* sentinel */ + {"__setstate__", (PyCFunction)zip_setstate, METH_O, setstate_doc}, + {NULL} /* sentinel */ }; PyDoc_STRVAR(zip_doc, -"zip(*iterables) --> A zip object yielding tuples until an input is exhausted.\n\ +"zip(*iterables, strict=False) --> Yield tuples until an input is exhausted.\n\ \n\ >>> list(zip('abcdefg', range(3), range(4)))\n\ [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]\n\ @@ -2653,7 +2854,10 @@ PyDoc_STRVAR(zip_doc, The zip object yields n-length tuples, where n is the number of iterables\n\ passed as positional arguments to zip(). The i-th element in every tuple\n\ comes from the i-th iterable argument to zip(). This continues until the\n\ -shortest argument is exhausted."); +shortest argument is exhausted.\n\ +\n\ +If strict is true and one of the arguments is exhausted before the others,\n\ +raise a ValueError."); PyTypeObject PyZip_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -2729,11 +2933,13 @@ static PyMethodDef builtin_methods[] = { BUILTIN_ISINSTANCE_METHODDEF BUILTIN_ISSUBCLASS_METHODDEF {"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc}, + BUILTIN_AITER_METHODDEF BUILTIN_LEN_METHODDEF BUILTIN_LOCALS_METHODDEF {"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, {"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc}, + BUILTIN_ANEXT_METHODDEF BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF BUILTIN_POW_METHODDEF @@ -2766,11 +2972,11 @@ static struct PyModuleDef builtinsmodule = { PyObject * -_PyBuiltin_Init(PyThreadState *tstate) +_PyBuiltin_Init(PyInterpreterState *interp) { PyObject *mod, *dict, *debug; - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); + const PyConfig *config = _PyInterpreterState_GetConfig(interp); if (PyType_Ready(&PyFilter_Type) < 0 || PyType_Ready(&PyMap_Type) < 0 || diff --git a/contrib/tools/python3/src/Python/bootstrap_hash.c b/contrib/tools/python3/src/Python/bootstrap_hash.c index e189ce0d901..77ccbee18d4 100644 --- a/contrib/tools/python3/src/Python/bootstrap_hash.c +++ b/contrib/tools/python3/src/Python/bootstrap_hash.c @@ -144,6 +144,11 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) else { n = getrandom(dest, n, flags); } +# ifdef _Py_MEMORY_SANITIZER + if (n > 0) { + __msan_unpoison(dest, n); + } +# endif #else /* On Linux, use the syscall() function because the GNU libc doesn't expose the Linux getrandom() syscall yet. See: diff --git a/contrib/tools/python3/src/Python/ceval.c b/contrib/tools/python3/src/Python/ceval.c index 9a61f8a3c3c..21674e0be13 100644 --- a/contrib/tools/python3/src/Python/ceval.c +++ b/contrib/tools/python3/src/Python/ceval.c @@ -1,4 +1,3 @@ - /* Execute compiled code */ /* XXX TO DO: @@ -7,21 +6,22 @@ */ /* enable more aggressive intra-module optimizations, where available */ +/* affects both release and debug builds - see bpo-43271 */ #define PY_LOCAL_AGGRESSIVE #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_call.h" -#include "pycore_ceval.h" -#include "pycore_code.h" -#include "pycore_initconfig.h" -#include "pycore_object.h" -#include "pycore_pyerrors.h" -#include "pycore_pylifecycle.h" +#include "pycore_call.h" // _PyObject_FastCallDictTstate() +#include "pycore_ceval.h" // _PyEval_SignalAsyncExc() +#include "pycore_code.h" // _PyCode_InitOpcache() +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pylifecycle.h" // _PyErr_Print() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_sysmodule.h" -#include "pycore_tupleobject.h" +#include "pycore_sysmodule.h" // _PySys_Audit() +#include "pycore_tuple.h" // _PyTuple_ITEMS() #include "code.h" #include "dictobject.h" @@ -29,9 +29,17 @@ #include "opcode.h" #include "pydtrace.h" #include "setobject.h" +#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX #include +typedef struct { + PyCodeObject *code; // The code object for the bounds. May be NULL. + PyCodeAddressRange bounds; // Only valid if code != NULL. + CFrame cframe; +} PyTraceInfo; + + #ifdef Py_DEBUG /* For debugging the interpreter: */ #define LLTRACE 1 /* Low-level trace feature */ @@ -46,10 +54,10 @@ _Py_IDENTIFIER(__name__); /* Forward declarations */ Py_LOCAL_INLINE(PyObject *) call_function( - PyThreadState *tstate, PyObject ***pp_stack, + PyThreadState *tstate, PyTraceInfo *, PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames); static PyObject * do_call_core( - PyThreadState *tstate, PyObject *func, + PyThreadState *tstate, PyTraceInfo *, PyObject *func, PyObject *callargs, PyObject *kwdict); #ifdef LLTRACE @@ -58,16 +66,19 @@ static int prtrace(PyThreadState *, PyObject *, const char *); #endif static int call_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, + PyTraceInfo *, int, PyObject *); static int call_trace_protected(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, + PyTraceInfo *, int, PyObject *); static void call_exc_trace(Py_tracefunc, PyObject *, - PyThreadState *, PyFrameObject *); + PyThreadState *, PyFrameObject *, + PyTraceInfo *trace_info); static int maybe_call_line_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, - int *, int *, int *); -static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *); + PyTraceInfo *, int); +static void maybe_dtrace_line(PyFrameObject *, PyTraceInfo *, int); static void dtrace_function_entry(PyFrameObject *); static void dtrace_function_return(PyFrameObject *); @@ -103,16 +114,19 @@ static long dxp[256]; #endif /* per opcode cache */ -#ifdef Py_DEBUG -// --with-pydebug is used to find memory leak. opcache makes it harder. -// So we disable opcache when Py_DEBUG is defined. -// See bpo-37146 -#define OPCACHE_MIN_RUNS 0 /* disable opcache */ -#else -#define OPCACHE_MIN_RUNS 1024 /* create opcache when code executed this time */ -#endif +static int opcache_min_runs = 1024; /* create opcache when code executed this many times */ +#define OPCODE_CACHE_MAX_TRIES 20 #define OPCACHE_STATS 0 /* Enable stats */ +// This function allows to deactivate the opcode cache. As different cache mechanisms may hold +// references, this can mess with the reference leak detector functionality so the cache needs +// to be deactivated in such scenarios to avoid false positives. See bpo-3714 for more information. +void +_PyEval_DeactivateOpCache(void) +{ + opcache_min_runs = 0; +} + #if OPCACHE_STATS static size_t opcache_code_objects = 0; static size_t opcache_code_objects_extra_mem = 0; @@ -120,6 +134,12 @@ static size_t opcache_code_objects_extra_mem = 0; static size_t opcache_global_opts = 0; static size_t opcache_global_hits = 0; static size_t opcache_global_misses = 0; + +static size_t opcache_attr_opts = 0; +static size_t opcache_attr_hits = 0; +static size_t opcache_attr_misses = 0; +static size_t opcache_attr_deopts = 0; +static size_t opcache_attr_total = 0; #endif @@ -254,7 +274,21 @@ _Py_FatalError_TstateNULL(const char *func) "(the current Python thread state is NULL)"); } +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS +int +_PyEval_ThreadsInitialized(PyInterpreterState *interp) +{ + return gil_created(&interp->ceval.gil); +} +int +PyEval_ThreadsInitialized(void) +{ + // Fatal error if there is no current interpreter + PyInterpreterState *interp = PyInterpreterState_Get(); + return _PyEval_ThreadsInitialized(interp); +} +#else int _PyEval_ThreadsInitialized(_PyRuntimeState *runtime) { @@ -267,18 +301,25 @@ PyEval_ThreadsInitialized(void) _PyRuntimeState *runtime = &_PyRuntime; return _PyEval_ThreadsInitialized(runtime); } +#endif PyStatus _PyEval_InitGIL(PyThreadState *tstate) { - if (!_Py_IsMainInterpreter(tstate)) { +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + 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(); } +#endif +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; +#else struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; +#endif assert(!gil_created(gil)); PyThread_init_thread(); @@ -291,16 +332,22 @@ _PyEval_InitGIL(PyThreadState *tstate) } void -_PyEval_FiniGIL(PyThreadState *tstate) +_PyEval_FiniGIL(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(tstate)) { +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + 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; } +#endif - struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + struct _gil_runtime_state *gil = &interp->ceval.gil; +#else + struct _gil_runtime_state *gil = &interp->runtime->ceval.gil; +#endif if (!gil_created(gil)) { /* First Py_InitializeFromConfig() call: the GIL doesn't exist yet: do nothing. */ @@ -343,6 +390,25 @@ _PyEval_Fini(void) opcache_global_opts); fprintf(stderr, "\n"); + + fprintf(stderr, "-- Opcode cache LOAD_ATTR hits = %zd (%d%%)\n", + opcache_attr_hits, + (int) (100.0 * opcache_attr_hits / + opcache_attr_total)); + + fprintf(stderr, "-- Opcode cache LOAD_ATTR misses = %zd (%d%%)\n", + opcache_attr_misses, + (int) (100.0 * opcache_attr_misses / + opcache_attr_total)); + + fprintf(stderr, "-- Opcode cache LOAD_ATTR opts = %zd\n", + opcache_attr_opts); + + fprintf(stderr, "-- Opcode cache LOAD_ATTR deopts = %zd\n", + opcache_attr_deopts); + + fprintf(stderr, "-- Opcode cache LOAD_ATTR total = %zd\n", + opcache_attr_total); #endif } @@ -385,9 +451,13 @@ PyEval_AcquireThread(PyThreadState *tstate) take_gil(tstate); struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + (void)_PyThreadState_Swap(gilstate, tstate); +#else if (_PyThreadState_Swap(gilstate, tstate) != NULL) { Py_FatalError("non-NULL old thread state"); } +#endif } void @@ -407,19 +477,20 @@ PyEval_ReleaseThread(PyThreadState *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. - */ - -void -_PyEval_ReInitThreads(_PyRuntimeState *runtime) + which are not running in the child process, and clear internal locks + which might be held by those threads. */ +PyStatus +_PyEval_ReInitThreads(PyThreadState *tstate) { - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - _Py_EnsureTstateNotNULL(tstate); + _PyRuntimeState *runtime = tstate->interp->runtime; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; +#else struct _gil_runtime_state *gil = &runtime->ceval.gil; +#endif if (!gil_created(gil)) { - return; + return _PyStatus_OK(); } recreate_gil(gil); @@ -427,11 +498,12 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) struct _pending_calls *pending = &tstate->interp->ceval.pending; if (_PyThread_at_fork_reinit(&pending->lock) < 0) { - Py_FatalError("Can't initialize threads for pending calls"); + return _PyStatus_ERR("Can't reinitialize pending calls lock"); } /* Destroy all threads except the current one */ _PyThreadState_DeleteExcept(runtime, tstate); + return _PyStatus_OK(); } #endif @@ -439,22 +511,30 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) raised. */ void -_PyEval_SignalAsyncExc(PyThreadState *tstate) +_PyEval_SignalAsyncExc(PyInterpreterState *interp) { - assert(is_tstate_valid(tstate)); - SIGNAL_ASYNC_EXC(tstate->interp); + SIGNAL_ASYNC_EXC(interp); } PyThreadState * PyEval_SaveThread(void) { _PyRuntimeState *runtime = &_PyRuntime; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + PyThreadState *old_tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, old_tstate); +#else PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); +#endif _Py_EnsureTstateNotNULL(tstate); struct _ceval_runtime_state *ceval = &runtime->ceval; struct _ceval_state *ceval2 = &tstate->interp->ceval; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + assert(gil_created(&ceval2->gil)); +#else assert(gil_created(&ceval->gil)); +#endif drop_gil(ceval, ceval2, tstate); return tstate; } @@ -618,10 +698,8 @@ handle_signals(PyThreadState *tstate) } static int -make_pending_calls(PyThreadState *tstate) +make_pending_calls(PyInterpreterState *interp) { - assert(is_tstate_valid(tstate)); - /* only execute pending calls on main thread */ if (!_Py_ThreadCanHandlePendingCalls()) { return 0; @@ -636,11 +714,11 @@ make_pending_calls(PyThreadState *tstate) /* unsignal before starting to call callbacks, so that any callback added in-between re-signals */ - UNSIGNAL_PENDING_CALLS(tstate->interp); + UNSIGNAL_PENDING_CALLS(interp); int res = 0; /* perform a bounded number of calls, in case of recursion */ - struct _pending_calls *pending = &tstate->interp->ceval.pending; + struct _pending_calls *pending = &interp->ceval.pending; for (int i=0; iinterp); + SIGNAL_PENDING_CALLS(interp); return res; } @@ -673,6 +751,7 @@ void _Py_FinishPendingCalls(PyThreadState *tstate) { assert(PyGILState_Check()); + assert(is_tstate_valid(tstate)); struct _pending_calls *pending = &tstate->interp->ceval.pending; @@ -680,7 +759,7 @@ _Py_FinishPendingCalls(PyThreadState *tstate) return; } - if (make_pending_calls(tstate) < 0) { + if (make_pending_calls(tstate->interp) < 0) { PyObject *exc, *val, *tb; _PyErr_Fetch(tstate, &exc, &val, &tb); PyErr_BadInternalCall(); @@ -697,6 +776,7 @@ Py_MakePendingCalls(void) 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(). */ @@ -705,7 +785,7 @@ Py_MakePendingCalls(void) return res; } - res = make_pending_calls(tstate); + res = make_pending_calls(tstate->interp); if (res != 0) { return res; } @@ -716,16 +796,15 @@ Py_MakePendingCalls(void) /* The interpreter's recursion limit */ #ifndef Py_DEFAULT_RECURSION_LIMIT -#define Py_DEFAULT_RECURSION_LIMIT 1000 +# define Py_DEFAULT_RECURSION_LIMIT 1000 #endif -int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; - void _PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) { - _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS _gil_initialize(&ceval->gil); +#endif } int @@ -741,6 +820,10 @@ _PyEval_InitState(struct _ceval_state *ceval) return -1; } +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + _gil_initialize(&ceval->gil); +#endif + return 0; } @@ -757,8 +840,8 @@ _PyEval_FiniState(struct _ceval_state *ceval) int Py_GetRecursionLimit(void) { - PyThreadState *tstate = _PyThreadState_GET(); - return tstate->interp->ceval.recursion_limit; + PyInterpreterState *interp = _PyInterpreterState_GET(); + return interp->ceval.recursion_limit; } void @@ -766,14 +849,11 @@ Py_SetRecursionLimit(int new_limit) { PyThreadState *tstate = _PyThreadState_GET(); tstate->interp->ceval.recursion_limit = new_limit; - if (_Py_IsMainInterpreter(tstate)) { - _Py_CheckRecursionLimit = new_limit; - } } /* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() - if the recursion_depth reaches _Py_CheckRecursionLimit. - If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit + if the recursion_depth reaches recursion_limit. + If USE_STACKCHECK, the macro decrements recursion_limit to guarantee that _Py_CheckRecursiveCall() is regularly called. Without USE_STACKCHECK, there is no need for this. */ int @@ -788,27 +868,20 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); return -1; } - if (_Py_IsMainInterpreter(tstate)) { - /* Needed for ABI backwards-compatibility (see bpo-31857) */ - _Py_CheckRecursionLimit = recursion_limit; - } #endif - if (tstate->recursion_critical) - /* Somebody asked that we don't check for recursion. */ - return 0; - if (tstate->overflowed) { - if (tstate->recursion_depth > recursion_limit + 50 || tstate->overflowed > 50) { + if (tstate->recursion_headroom) { + if (tstate->recursion_depth > recursion_limit + 50) { /* Overflowing while handling an overflow. Give up. */ Py_FatalError("Cannot recover from stack overflow."); } } else { if (tstate->recursion_depth > recursion_limit) { - tstate->overflowed++; + tstate->recursion_headroom++; _PyErr_Format(tstate, PyExc_RecursionError, "maximum recursion depth exceeded%s", where); - tstate->overflowed--; + tstate->recursion_headroom--; --tstate->recursion_depth; return -1; } @@ -816,21 +889,249 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) return 0; } + +// 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; + // 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). + _Py_IDENTIFIER(get); + PyObject *get = _PyObject_GetAttrId(map, &PyId_get); + if (get == NULL) { + goto fail; + } + seen = PySet_New(NULL); + if (seen == NULL) { + goto fail; + } + // dummy = object() + dummy = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); + if (dummy == NULL) { + goto fail; + } + values = PyList_New(0); + 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 *value = PyObject_CallFunctionObjArgs(get, key, dummy, 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; + } + PyList_Append(values, value); + Py_DECREF(value); + } + Py_SETREF(values, PyList_AsTuple(values)); + // 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 unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); -#define _Py_TracingPossible(ceval) ((ceval)->tracing_possible) - PyObject * PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) { - return PyEval_EvalCodeEx(co, - globals, locals, - (PyObject **)NULL, 0, - (PyObject **)NULL, 0, - (PyObject **)NULL, 0, - NULL, NULL); + 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 + }; + return _PyEval_Vector(tstate, &desc, locals, NULL, 0, NULL); } @@ -870,7 +1171,7 @@ eval_frame_handle_pending(PyThreadState *tstate) /* Pending calls */ struct _ceval_state *ceval2 = &tstate->interp->ceval; if (_Py_atomic_load_relaxed(&ceval2->pending.calls_to_do)) { - if (make_pending_calls(tstate) != 0) { + if (make_pending_calls(tstate->interp) != 0) { return -1; } } @@ -887,9 +1188,13 @@ eval_frame_handle_pending(PyThreadState *tstate) take_gil(tstate); +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + (void)_PyThreadState_Swap(&runtime->gilstate, tstate); +#else if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("orphan tstate"); } +#endif } /* Check for asynchronous exception. */ @@ -916,41 +1221,6 @@ eval_frame_handle_pending(PyThreadState *tstate) return 0; } -PyObject* _Py_HOT_FUNCTION -_PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) -{ - _Py_EnsureTstateNotNULL(tstate); - -#ifdef DXPAIRS - int lastopcode = 0; -#endif - PyObject **stack_pointer; /* Next free slot in value stack */ - const _Py_CODEUNIT *next_instr; - int opcode; /* Current opcode */ - int oparg; /* Current opcode argument, if any */ - PyObject **fastlocals, **freevars; - PyObject *retval = NULL; /* Return value */ - struct _ceval_state * const ceval2 = &tstate->interp->ceval; - _Py_atomic_int * const eval_breaker = &ceval2->eval_breaker; - PyCodeObject *co; - - /* when tracing we set things up so that - - not (instr_lb <= current_bytecode_offset < instr_ub) - - is true when the line being executed has changed. The - initial values are such as to make this false the first - time it is tested. */ - int instr_ub = -1, instr_lb = 0, instr_prev = -1; - - const _Py_CODEUNIT *first_instr; - PyObject *names; - PyObject *consts; - _PyOpcache *co_opcache; - -#ifdef LLTRACE - _Py_IDENTIFIER(__ltrace__); -#endif /* Computed GOTOs, or the-optimization-commonly-but-improperly-known-as-"threaded code" @@ -991,6 +1261,23 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) -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 LLTRACE +#define OR_LLTRACE || lltrace +#else +#define OR_LLTRACE +#endif + +#ifdef WITH_DTRACE +#define OR_DTRACE_LINE || PyDTrace_LINE_ENABLED() +#else +#define OR_DTRACE_LINE +#endif + #ifdef DYNAMIC_EXECUTION_PROFILE #undef USE_COMPUTED_GOTOS #define USE_COMPUTED_GOTOS 0 @@ -1009,49 +1296,27 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) #endif #if USE_COMPUTED_GOTOS -/* Import the static jump table */ -#include "opcode_targets.h" - -#define TARGET(op) \ - op: \ - TARGET_##op - -#ifdef LLTRACE -#define FAST_DISPATCH() \ +#define TARGET(op) op: TARGET_##op +#define DISPATCH() \ { \ - if (!lltrace && !_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \ - f->f_lasti = INSTR_OFFSET(); \ - NEXTOPARG(); \ - goto *opcode_targets[opcode]; \ + if (trace_info.cframe.use_tracing OR_DTRACE_LINE OR_LLTRACE) { \ + goto tracing_dispatch; \ } \ - goto fast_next_opcode; \ + f->f_lasti = INSTR_OFFSET(); \ + NEXTOPARG(); \ + goto *opcode_targets[opcode]; \ } #else -#define FAST_DISPATCH() \ - { \ - if (!_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \ - f->f_lasti = INSTR_OFFSET(); \ - NEXTOPARG(); \ - goto *opcode_targets[opcode]; \ - } \ - goto fast_next_opcode; \ - } +#define TARGET(op) op +#define DISPATCH() goto predispatch; #endif -#define DISPATCH() \ - { \ - if (!_Py_atomic_load_relaxed(eval_breaker)) { \ - FAST_DISPATCH(); \ - } \ + +#define CHECK_EVAL_BREAKER() \ + if (_Py_atomic_load_relaxed(eval_breaker)) { \ continue; \ } -#else -#define TARGET(op) op -#define FAST_DISPATCH() goto fast_next_opcode -#define DISPATCH() continue -#endif - /* Tuple access macros */ @@ -1064,16 +1329,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) /* Code access macros */ /* The integer overflow is checked by an assertion below. */ -#define INSTR_OFFSET() \ - (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr)) +#define INSTR_OFFSET() ((int)(next_instr - first_instr)) #define NEXTOPARG() do { \ _Py_CODEUNIT word = *next_instr; \ opcode = _Py_OPCODE(word); \ oparg = _Py_OPARG(word); \ next_instr++; \ } while (0) -#define JUMPTO(x) (next_instr = first_instr + (x) / sizeof(_Py_CODEUNIT)) -#define JUMPBY(x) (next_instr += (x) / sizeof(_Py_CODEUNIT)) +#define JUMPTO(x) (next_instr = first_instr + (x)) +#define JUMPBY(x) (next_instr += (x)) /* OpCode prediction macros Some opcodes tend to come in pairs thus making it possible to @@ -1135,7 +1399,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) #define SET_SECOND(v) (stack_pointer[-2] = (v)) #define SET_THIRD(v) (stack_pointer[-3] = (v)) #define SET_FOURTH(v) (stack_pointer[-4] = (v)) -#define SET_VALUE(n, v) (stack_pointer[-(n)] = (v)) #define BASIC_STACKADJ(n) (stack_pointer += n) #define BASIC_PUSH(v) (*stack_pointer++ = (v)) #define BASIC_POP() (*--stack_pointer) @@ -1216,16 +1479,43 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) do { \ co_opcache = NULL; \ if (co->co_opcache != NULL) { \ - unsigned char co_opt_offset = \ + unsigned char co_opcache_offset = \ co->co_opcache_map[next_instr - first_instr]; \ - if (co_opt_offset > 0) { \ - assert(co_opt_offset <= co->co_opcache_size); \ - co_opcache = &co->co_opcache[co_opt_offset - 1]; \ + if (co_opcache_offset > 0) { \ + assert(co_opcache_offset <= co->co_opcache_size); \ + co_opcache = &co->co_opcache[co_opcache_offset - 1]; \ assert(co_opcache != NULL); \ } \ } \ } while (0) +#define OPCACHE_DEOPT() \ + do { \ + if (co_opcache != NULL) { \ + co_opcache->optimized = -1; \ + unsigned char co_opcache_offset = \ + co->co_opcache_map[next_instr - first_instr]; \ + assert(co_opcache_offset <= co->co_opcache_size); \ + co->co_opcache_map[co_opcache_offset] = 0; \ + co_opcache = NULL; \ + } \ + } while (0) + +#define OPCACHE_DEOPT_LOAD_ATTR() \ + do { \ + if (co_opcache != NULL) { \ + OPCACHE_STAT_ATTR_DEOPT(); \ + OPCACHE_DEOPT(); \ + } \ + } while (0) + +#define OPCACHE_MAYBE_DEOPT_LOAD_ATTR() \ + do { \ + if (co_opcache != NULL && --co_opcache->optimized <= 0) { \ + OPCACHE_DEOPT_LOAD_ATTR(); \ + } \ + } while (0) + #if OPCACHE_STATS #define OPCACHE_STAT_GLOBAL_HIT() \ @@ -1243,24 +1533,99 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (co->co_opcache != NULL) opcache_global_opts++; \ } while (0) +#define OPCACHE_STAT_ATTR_HIT() \ + do { \ + if (co->co_opcache != NULL) opcache_attr_hits++; \ + } while (0) + +#define OPCACHE_STAT_ATTR_MISS() \ + do { \ + if (co->co_opcache != NULL) opcache_attr_misses++; \ + } while (0) + +#define OPCACHE_STAT_ATTR_OPT() \ + do { \ + if (co->co_opcache!= NULL) opcache_attr_opts++; \ + } while (0) + +#define OPCACHE_STAT_ATTR_DEOPT() \ + do { \ + if (co->co_opcache != NULL) opcache_attr_deopts++; \ + } while (0) + +#define OPCACHE_STAT_ATTR_TOTAL() \ + do { \ + if (co->co_opcache != NULL) opcache_attr_total++; \ + } while (0) + #else /* OPCACHE_STATS */ #define OPCACHE_STAT_GLOBAL_HIT() #define OPCACHE_STAT_GLOBAL_MISS() #define OPCACHE_STAT_GLOBAL_OPT() +#define OPCACHE_STAT_ATTR_HIT() +#define OPCACHE_STAT_ATTR_MISS() +#define OPCACHE_STAT_ATTR_OPT() +#define OPCACHE_STAT_ATTR_DEOPT() +#define OPCACHE_STAT_ATTR_TOTAL() + #endif -/* Start of code */ - /* push frame */ +PyObject* _Py_HOT_FUNCTION +_PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) +{ + _Py_EnsureTstateNotNULL(tstate); + +#if USE_COMPUTED_GOTOS +/* Import the static jump table */ +#include "opcode_targets.h" +#endif + +#ifdef DXPAIRS + int lastopcode = 0; +#endif + PyObject **stack_pointer; /* Next free slot in value stack */ + const _Py_CODEUNIT *next_instr; + int opcode; /* Current opcode */ + int oparg; /* Current opcode argument, if any */ + PyObject **fastlocals, **freevars; + PyObject *retval = NULL; /* Return value */ + _Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker; + PyCodeObject *co; + + const _Py_CODEUNIT *first_instr; + PyObject *names; + PyObject *consts; + _PyOpcache *co_opcache; + +#ifdef LLTRACE + _Py_IDENTIFIER(__ltrace__); +#endif + if (_Py_EnterRecursiveCall(tstate, "")) { return NULL; } + PyTraceInfo trace_info; + /* Mark trace_info as uninitialized */ + trace_info.code = NULL; + + /* WARNING: Because the CFrame lives on the C stack, + * but can be accessed from a heap allocated object (tstate) + * strict stack discipline must be maintained. + */ + CFrame *prev_cframe = tstate->cframe; + trace_info.cframe.use_tracing = prev_cframe->use_tracing; + trace_info.cframe.previous = prev_cframe; + tstate->cframe = &trace_info.cframe; + + /* push frame */ tstate->frame = f; + co = f->f_code; - if (tstate->use_tracing) { + if (trace_info.cframe.use_tracing) { if (tstate->c_tracefunc != NULL) { /* tstate->c_tracefunc, if defined, is a function that will be called on *every* entry @@ -1277,7 +1642,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) whenever an exception is detected. */ if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - tstate, f, PyTrace_CALL, Py_None)) { + tstate, f, &trace_info, + PyTrace_CALL, Py_None)) { /* Trace function raised an error */ goto exit_eval_frame; } @@ -1287,7 +1653,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) return itself and isn't called for "line" events */ if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, - tstate, f, PyTrace_CALL, Py_None)) { + tstate, f, &trace_info, + PyTrace_CALL, Py_None)) { /* Profile function raised an error */ goto exit_eval_frame; } @@ -1297,7 +1664,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (PyDTrace_FUNCTION_ENTRY_ENABLED()) dtrace_function_entry(f); - co = f->f_code; names = co->co_names; consts = co->co_consts; fastlocals = f->f_localsplus; @@ -1323,19 +1689,20 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) to the beginning of the combined pair.) */ assert(f->f_lasti >= -1); - next_instr = first_instr; - if (f->f_lasti >= 0) { - assert(f->f_lasti % sizeof(_Py_CODEUNIT) == 0); - next_instr += f->f_lasti / sizeof(_Py_CODEUNIT) + 1; - } - stack_pointer = f->f_stacktop; - assert(stack_pointer != NULL); - f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */ - f->f_executing = 1; + next_instr = first_instr + f->f_lasti + 1; + stack_pointer = f->f_valuestack + f->f_stackdepth; + /* Set f->f_stackdepth to -1. + * Update when returning or calling trace function. + Having f_stackdepth <= 0 ensures that invalid + values are not visible to the cycle GC. + We choose -1 rather than 0 to assist debugging. + */ + f->f_stackdepth = -1; + f->f_state = FRAME_EXECUTING; - if (co->co_opcache_flag < OPCACHE_MIN_RUNS) { + if (co->co_opcache_flag < opcache_min_runs) { co->co_opcache_flag++; - if (co->co_opcache_flag == OPCACHE_MIN_RUNS) { + if (co->co_opcache_flag == opcache_min_runs) { if (_PyCode_InitOpcache(co) < 0) { goto exit_eval_frame; } @@ -1349,11 +1716,18 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) } #ifdef LLTRACE - lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL; + { + int r = _PyDict_ContainsId(f->f_globals, &PyId___ltrace__); + if (r < 0) { + goto exit_eval_frame; + } + lltrace = r; + } #endif - if (throwflag) /* support for generator.throw() */ + if (throwflag) { /* support for generator.throw() */ goto error; + } #ifdef Py_DEBUG /* _PyEval_EvalFrameDefault() must not be called with an exception set, @@ -1378,10 +1752,10 @@ main_loop: if (_Py_atomic_load_relaxed(eval_breaker)) { opcode = _Py_OPCODE(*next_instr); - if (opcode == SETUP_FINALLY || - opcode == SETUP_WITH || - opcode == BEFORE_ASYNC_WITH || - opcode == YIELD_FROM) { + if (opcode != SETUP_FINALLY && + opcode != SETUP_WITH && + opcode != BEFORE_ASYNC_WITH && + opcode != YIELD_FROM) { /* Few cases where we skip running signal handlers and other pending calls: - If we're about to enter the 'with:'. It will prevent @@ -1398,55 +1772,45 @@ main_loop: running the signal handler and raising KeyboardInterrupt (see bpo-30039). */ - goto fast_next_opcode; - } - - if (eval_frame_handle_pending(tstate) != 0) { - goto error; - } + if (eval_frame_handle_pending(tstate) != 0) { + goto error; + } + } } - fast_next_opcode: + tracing_dispatch: + { + int instr_prev = f->f_lasti; f->f_lasti = INSTR_OFFSET(); + NEXTOPARG(); if (PyDTrace_LINE_ENABLED()) - maybe_dtrace_line(f, &instr_lb, &instr_ub, &instr_prev); + maybe_dtrace_line(f, &trace_info, instr_prev); /* line-by-line tracing support */ - if (_Py_TracingPossible(ceval2) && + if (trace_info.cframe.use_tracing && tstate->c_tracefunc != NULL && !tstate->tracing) { int err; - /* see maybe_call_line_trace + /* see maybe_call_line_trace() for expository comments */ - f->f_stacktop = stack_pointer; + f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); err = maybe_call_line_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f, - &instr_lb, &instr_ub, &instr_prev); + &trace_info, instr_prev); /* Reload possibly changed frame fields */ JUMPTO(f->f_lasti); - if (f->f_stacktop != NULL) { - stack_pointer = f->f_stacktop; - f->f_stacktop = NULL; - } - if (err) + stack_pointer = f->f_valuestack+f->f_stackdepth; + f->f_stackdepth = -1; + if (err) { /* trace function raised an exception */ goto error; + } + NEXTOPARG(); } - - /* Extract opcode and argument */ - - NEXTOPARG(); - dispatch_opcode: -#ifdef DYNAMIC_EXECUTION_PROFILE -#ifdef DXPAIRS - dxpairs[lastopcode][opcode]++; - lastopcode = opcode; -#endif - dxp[opcode]++; -#endif + } #ifdef LLTRACE /* Instruction tracing */ @@ -1462,15 +1826,33 @@ main_loop: } } #endif +#if USE_COMPUTED_GOTOS == 0 + goto dispatch_opcode; + + predispatch: + if (trace_info.cframe.use_tracing OR_DTRACE_LINE OR_LLTRACE) { + goto tracing_dispatch; + } + f->f_lasti = INSTR_OFFSET(); + NEXTOPARG(); +#endif + dispatch_opcode: +#ifdef DYNAMIC_EXECUTION_PROFILE +#ifdef DXPAIRS + dxpairs[lastopcode][opcode]++; + lastopcode = opcode; +#endif + dxp[opcode]++; +#endif switch (opcode) { /* BEWARE! It is essential that any operation that fails must goto error - and that all operation that succeed call [FAST_]DISPATCH() ! */ + and that all operation that succeed call DISPATCH() ! */ case TARGET(NOP): { - FAST_DISPATCH(); + DISPATCH(); } case TARGET(LOAD_FAST): { @@ -1483,7 +1865,7 @@ main_loop: } Py_INCREF(value); PUSH(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(LOAD_CONST): { @@ -1491,20 +1873,20 @@ main_loop: PyObject *value = GETITEM(consts, oparg); Py_INCREF(value); PUSH(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(STORE_FAST): { PREDICTED(STORE_FAST); PyObject *value = POP(); SETLOCAL(oparg, value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(POP_TOP): { PyObject *value = POP(); Py_DECREF(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(ROT_TWO): { @@ -1512,7 +1894,7 @@ main_loop: PyObject *second = SECOND(); SET_TOP(second); SET_SECOND(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(ROT_THREE): { @@ -1522,7 +1904,7 @@ main_loop: SET_TOP(second); SET_SECOND(third); SET_THIRD(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(ROT_FOUR): { @@ -1534,14 +1916,14 @@ main_loop: SET_SECOND(third); SET_THIRD(fourth); SET_FOURTH(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(DUP_TOP): { PyObject *top = TOP(); Py_INCREF(top); PUSH(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(DUP_TOP_TWO): { @@ -1552,7 +1934,7 @@ main_loop: STACK_GROW(2); SET_TOP(top); SET_SECOND(second); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(UNARY_POSITIVE): { @@ -1687,7 +2069,7 @@ main_loop: PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; - /* NOTE(haypo): Please don't try to micro-optimize int+int on + /* NOTE(vstinner): Please don't try to micro-optimize int+int on CPython using bytecode, it is simply worthless. See http://bugs.python.org/issue21955 and http://bugs.python.org/issue10044 for the discussion. In short, @@ -2055,6 +2437,8 @@ main_loop: retval = POP(); assert(f->f_iblock == 0); assert(EMPTY()); + f->f_state = FRAME_RETURNED; + f->f_stackdepth = 0; goto exiting; } @@ -2197,34 +2581,52 @@ main_loop: case TARGET(YIELD_FROM): { PyObject *v = POP(); PyObject *receiver = TOP(); - int err; - if (PyGen_CheckExact(receiver) || PyCoro_CheckExact(receiver)) { - retval = _PyGen_Send((PyGenObject *)receiver, v); + PySendResult gen_status; + if (tstate->c_tracefunc == NULL) { + gen_status = PyIter_Send(receiver, v, &retval); } else { _Py_IDENTIFIER(send); - if (v == Py_None) + if (Py_IsNone(v) && PyIter_Check(receiver)) { retval = Py_TYPE(receiver)->tp_iternext(receiver); - else + } + else { retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_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, f, &trace_info); + if (_PyGen_FetchStopIterationValue(&retval) == 0) { + gen_status = PYGEN_RETURN; + } + else { + gen_status = PYGEN_ERROR; + } + } + else { + gen_status = PYGEN_NEXT; + } } Py_DECREF(v); - if (retval == NULL) { - PyObject *val; - if (tstate->c_tracefunc != NULL - && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); - err = _PyGen_FetchStopIterationValue(&val); - if (err < 0) - goto error; + if (gen_status == PYGEN_ERROR) { + assert (retval == NULL); + goto error; + } + if (gen_status == PYGEN_RETURN) { + assert (retval != NULL); + Py_DECREF(receiver); - SET_TOP(val); + SET_TOP(retval); + retval = NULL; DISPATCH(); } + assert (gen_status == PYGEN_NEXT); /* receiver remains on stack, retval is value to be yielded */ - f->f_stacktop = stack_pointer; /* and repeat... */ - assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT)); - f->f_lasti -= sizeof(_Py_CODEUNIT); + assert(f->f_lasti > 0); + f->f_lasti -= 1; + f->f_state = FRAME_SUSPENDED; + f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); goto exiting; } @@ -2240,11 +2642,19 @@ main_loop: } retval = w; } - - f->f_stacktop = stack_pointer; + f->f_state = FRAME_SUSPENDED; + f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); goto exiting; } + case TARGET(GEN_START): { + PyObject *none = POP(); + assert(none == Py_None); + assert(oparg < 3); + Py_DECREF(none); + DISPATCH(); + } + case TARGET(POP_EXCEPT): { PyObject *type, *value, *traceback; _PyErr_StackItem *exc_info; @@ -2270,12 +2680,15 @@ main_loop: } case TARGET(POP_BLOCK): { - PREDICTED(POP_BLOCK); PyFrame_BlockPop(f); DISPATCH(); } case TARGET(RERAISE): { + assert(f->f_iblock > 0); + if (oparg) { + f->f_lasti = f->f_blockstack[f->f_iblock-1].b_handler; + } PyObject *exc = POP(); PyObject *val = POP(); PyObject *tb = POP(); @@ -2294,7 +2707,7 @@ main_loop: UNWIND_EXCEPT_HANDLER(b); Py_DECREF(POP()); JUMPBY(oparg); - FAST_DISPATCH(); + DISPATCH(); } else { PyObject *val = POP(); @@ -2308,7 +2721,7 @@ main_loop: PyObject *value = PyExc_AssertionError; Py_INCREF(value); PUSH(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(LOAD_BUILD_CLASS): { @@ -2571,7 +2984,7 @@ main_loop: (PyDictObject *)f->f_builtins, name); if (v == NULL) { - if (!_PyErr_OCCURRED()) { + 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, @@ -2993,7 +3406,190 @@ main_loop: case TARGET(LOAD_ATTR): { PyObject *name = GETITEM(names, oparg); PyObject *owner = TOP(); - PyObject *res = PyObject_GetAttr(owner, name); + + PyTypeObject *type = Py_TYPE(owner); + PyObject *res; + PyObject **dictptr; + PyObject *dict; + _PyOpCodeOpt_LoadAttr *la; + + OPCACHE_STAT_ATTR_TOTAL(); + + OPCACHE_CHECK(); + if (co_opcache != NULL && PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + { + if (co_opcache->optimized > 0) { + // Fast path -- cache hit makes LOAD_ATTR ~30% faster. + la = &co_opcache->u.la; + if (la->type == type && la->tp_version_tag == type->tp_version_tag) + { + // Hint >= 0 is a dict index; hint == -1 is a dict miss. + // Hint < -1 is an inverted slot offset: offset is strictly > 0, + // so ~offset is strictly < -1 (assuming 2's complement). + if (la->hint < -1) { + // Even faster path -- slot hint. + Py_ssize_t offset = ~la->hint; + // fprintf(stderr, "Using hint for offset %zd\n", offset); + char *addr = (char *)owner + offset; + res = *(PyObject **)addr; + if (res != NULL) { + Py_INCREF(res); + SET_TOP(res); + Py_DECREF(owner); + DISPATCH(); + } + // Else slot is NULL. Fall through to slow path to raise AttributeError(name). + // Don't DEOPT, since the slot is still there. + } else { + // Fast path for dict. + assert(type->tp_dict != NULL); + assert(type->tp_dictoffset > 0); + + dictptr = (PyObject **) ((char *)owner + type->tp_dictoffset); + dict = *dictptr; + if (dict != NULL && PyDict_CheckExact(dict)) { + Py_ssize_t hint = la->hint; + Py_INCREF(dict); + res = NULL; + assert(!_PyErr_Occurred(tstate)); + la->hint = _PyDict_GetItemHint((PyDictObject*)dict, name, hint, &res); + if (res != NULL) { + assert(la->hint >= 0); + if (la->hint == hint && hint >= 0) { + // Our hint has helped -- cache hit. + OPCACHE_STAT_ATTR_HIT(); + } else { + // The hint we provided didn't work. + // Maybe next time? + OPCACHE_MAYBE_DEOPT_LOAD_ATTR(); + } + + Py_INCREF(res); + SET_TOP(res); + Py_DECREF(owner); + Py_DECREF(dict); + DISPATCH(); + } + else { + _PyErr_Clear(tstate); + // This attribute can be missing sometimes; + // we don't want to optimize this lookup. + OPCACHE_DEOPT_LOAD_ATTR(); + Py_DECREF(dict); + } + } + else { + // There is no dict, or __dict__ doesn't satisfy PyDict_CheckExact. + OPCACHE_DEOPT_LOAD_ATTR(); + } + } + } + else { + // The type of the object has either been updated, + // or is different. Maybe it will stabilize? + OPCACHE_MAYBE_DEOPT_LOAD_ATTR(); + } + OPCACHE_STAT_ATTR_MISS(); + } + + if (co_opcache != NULL && // co_opcache can be NULL after a DEOPT() call. + type->tp_getattro == PyObject_GenericGetAttr) + { + if (type->tp_dict == NULL) { + if (PyType_Ready(type) < 0) { + Py_DECREF(owner); + SET_TOP(NULL); + goto error; + } + } + PyObject *descr = _PyType_Lookup(type, name); + if (descr != NULL) { + // We found an attribute with a data-like descriptor. + PyTypeObject *dtype = Py_TYPE(descr); + if (dtype == &PyMemberDescr_Type) { // It's a slot + PyMemberDescrObject *member = (PyMemberDescrObject *)descr; + struct PyMemberDef *dmem = member->d_member; + if (dmem->type == T_OBJECT_EX) { + Py_ssize_t offset = dmem->offset; + assert(offset > 0); // 0 would be confused with dict hint == -1 (miss). + + if (co_opcache->optimized == 0) { + // First time we optimize this opcode. + OPCACHE_STAT_ATTR_OPT(); + co_opcache->optimized = OPCODE_CACHE_MAX_TRIES; + // fprintf(stderr, "Setting hint for %s, offset %zd\n", dmem->name, offset); + } + + la = &co_opcache->u.la; + la->type = type; + la->tp_version_tag = type->tp_version_tag; + la->hint = ~offset; + + char *addr = (char *)owner + offset; + res = *(PyObject **)addr; + if (res != NULL) { + Py_INCREF(res); + Py_DECREF(owner); + SET_TOP(res); + + DISPATCH(); + } + // Else slot is NULL. Fall through to slow path to raise AttributeError(name). + } + // Else it's a slot of a different type. We don't handle those. + } + // Else it's some other kind of descriptor that we don't handle. + OPCACHE_DEOPT_LOAD_ATTR(); + } + else if (type->tp_dictoffset > 0) { + // We found an instance with a __dict__. + dictptr = (PyObject **) ((char *)owner + type->tp_dictoffset); + dict = *dictptr; + + if (dict != NULL && PyDict_CheckExact(dict)) { + Py_INCREF(dict); + res = NULL; + assert(!_PyErr_Occurred(tstate)); + Py_ssize_t hint = _PyDict_GetItemHint((PyDictObject*)dict, name, -1, &res); + if (res != NULL) { + Py_INCREF(res); + Py_DECREF(dict); + Py_DECREF(owner); + SET_TOP(res); + + if (co_opcache->optimized == 0) { + // First time we optimize this opcode. + OPCACHE_STAT_ATTR_OPT(); + co_opcache->optimized = OPCODE_CACHE_MAX_TRIES; + } + + la = &co_opcache->u.la; + la->type = type; + la->tp_version_tag = type->tp_version_tag; + assert(hint >= 0); + la->hint = hint; + + DISPATCH(); + } + else { + _PyErr_Clear(tstate); + } + Py_DECREF(dict); + } else { + // There is no dict, or __dict__ doesn't satisfy PyDict_CheckExact. + OPCACHE_DEOPT_LOAD_ATTR(); + } + } else { + // The object's class does not have a tp_dictoffset we can use. + OPCACHE_DEOPT_LOAD_ATTR(); + } + } else if (type->tp_getattro != PyObject_GenericGetAttr) { + OPCACHE_DEOPT_LOAD_ATTR(); + } + } + + // Slow path. + res = PyObject_GetAttr(owner, name); Py_DECREF(owner); SET_TOP(res); if (res == NULL) @@ -3019,7 +3615,7 @@ main_loop: case TARGET(IS_OP): { PyObject *right = POP(); PyObject *left = TOP(); - int res = (left == right)^oparg; + int res = Py_Is(left, right) ^ oparg; PyObject *b = res ? Py_True : Py_False; Py_INCREF(b); SET_TOP(b); @@ -3027,7 +3623,7 @@ main_loop: Py_DECREF(right); PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(CONTAINS_OP): { @@ -3044,7 +3640,7 @@ main_loop: PUSH(b); PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); - FAST_DISPATCH(); + DISPATCH(); } #define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ @@ -3141,28 +3737,31 @@ main_loop: case TARGET(JUMP_FORWARD): { JUMPBY(oparg); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(POP_JUMP_IF_FALSE): { PREDICTED(POP_JUMP_IF_FALSE); PyObject *cond = POP(); int err; - if (cond == Py_True) { + if (Py_IsTrue(cond)) { Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } - if (cond == Py_False) { + if (Py_IsFalse(cond)) { Py_DECREF(cond); JUMPTO(oparg); - FAST_DISPATCH(); + CHECK_EVAL_BREAKER(); + DISPATCH(); } err = PyObject_IsTrue(cond); Py_DECREF(cond); if (err > 0) ; - else if (err == 0) + else if (err == 0) { JUMPTO(oparg); + CHECK_EVAL_BREAKER(); + } else goto error; DISPATCH(); @@ -3172,19 +3771,21 @@ main_loop: PREDICTED(POP_JUMP_IF_TRUE); PyObject *cond = POP(); int err; - if (cond == Py_False) { + if (Py_IsFalse(cond)) { Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } - if (cond == Py_True) { + if (Py_IsTrue(cond)) { Py_DECREF(cond); JUMPTO(oparg); - FAST_DISPATCH(); + CHECK_EVAL_BREAKER(); + DISPATCH(); } err = PyObject_IsTrue(cond); Py_DECREF(cond); if (err > 0) { JUMPTO(oparg); + CHECK_EVAL_BREAKER(); } else if (err == 0) ; @@ -3196,14 +3797,14 @@ main_loop: case TARGET(JUMP_IF_FALSE_OR_POP): { PyObject *cond = TOP(); int err; - if (cond == Py_True) { + if (Py_IsTrue(cond)) { STACK_SHRINK(1); Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } - if (cond == Py_False) { + if (Py_IsFalse(cond)) { JUMPTO(oparg); - FAST_DISPATCH(); + DISPATCH(); } err = PyObject_IsTrue(cond); if (err > 0) { @@ -3220,14 +3821,14 @@ main_loop: case TARGET(JUMP_IF_TRUE_OR_POP): { PyObject *cond = TOP(); int err; - if (cond == Py_False) { + if (Py_IsFalse(cond)) { STACK_SHRINK(1); Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } - if (cond == Py_True) { + if (Py_IsTrue(cond)) { JUMPTO(oparg); - FAST_DISPATCH(); + DISPATCH(); } err = PyObject_IsTrue(cond); if (err > 0) { @@ -3245,18 +3846,110 @@ main_loop: case TARGET(JUMP_ABSOLUTE): { PREDICTED(JUMP_ABSOLUTE); JUMPTO(oparg); -#if FAST_LOOPS - /* Enabling this path speeds-up all while and for-loops by bypassing - the per-loop checks for signals. By default, this should be turned-off - because it prevents detection of a control-break in tight loops like - "while 1: pass". Compile with this option turned-on when you need - the speed-up and do not need break checking inside tight loops (ones - that contain only instructions ending with FAST_DISPATCH). - */ - FAST_DISPATCH(); -#else + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + case 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(); + } + + case TARGET(MATCH_CLASS): { + // Pop TOS. On success, set TOS to True and TOS1 to a tuple of + // attributes. On failure, set TOS to False. + PyObject *names = POP(); + PyObject *type = TOP(); + PyObject *subject = SECOND(); + assert(PyTuple_CheckExact(names)); + PyObject *attrs = match_class(tstate, subject, type, oparg, names); + Py_DECREF(names); + if (attrs) { + // Success! + assert(PyTuple_CheckExact(attrs)); + Py_DECREF(subject); + SET_SECOND(attrs); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + Py_DECREF(type); + SET_TOP(PyBool_FromLong(!!attrs)); + DISPATCH(); + } + + case 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); + DISPATCH(); + } + + case 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); + DISPATCH(); + } + + case TARGET(MATCH_KEYS): { + // On successful match for all keys, PUSH(values) and PUSH(True). + // Otherwise, PUSH(None) and PUSH(False). + 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); + if (Py_IsNone(values_or_none)) { + Py_INCREF(Py_False); + PUSH(Py_False); + DISPATCH(); + } + assert(PyTuple_CheckExact(values_or_none)); + Py_INCREF(Py_True); + PUSH(Py_True); + DISPATCH(); + } + + case TARGET(COPY_DICT_WITHOUT_KEYS): { + // rest = dict(TOS1) + // for key in TOS: + // del rest[key] + // SET_TOP(rest) + PyObject *keys = TOP(); + PyObject *subject = SECOND(); + PyObject *rest = PyDict_New(); + if (rest == NULL || PyDict_Update(rest, subject)) { + Py_XDECREF(rest); + goto error; + } + // This may seem a bit inefficient, but keys is rarely big enough to + // actually impact runtime. + assert(PyTuple_CheckExact(keys)); + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(keys); i++) { + if (PyDict_DelItem(rest, PyTuple_GET_ITEM(keys, i))) { + Py_DECREF(rest); + goto error; + } + } + Py_DECREF(keys); + SET_TOP(rest); DISPATCH(); -#endif } case TARGET(GET_ITER): { @@ -3317,7 +4010,7 @@ main_loop: goto error; } else if (tstate->c_tracefunc != NULL) { - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f, &trace_info); } _PyErr_Clear(tstate); } @@ -3325,7 +4018,6 @@ main_loop: STACK_SHRINK(1); Py_DECREF(iter); JUMPBY(oparg); - PREDICT(POP_BLOCK); DISPATCH(); } @@ -3414,7 +4106,7 @@ main_loop: exc = TOP(); val = SECOND(); tb = THIRD(); - assert(exc != Py_None); + assert(!Py_IsNone(exc)); assert(!PyLong_Check(exc)); exit_func = PEEK(7); PyObject *stack[4] = {NULL, exc, val, tb}; @@ -3486,7 +4178,7 @@ main_loop: `callable` will be POPed by call_function. NULL will will be POPed manually later. */ - res = call_function(tstate, &sp, oparg, NULL); + res = call_function(tstate, &trace_info, &sp, oparg, NULL); stack_pointer = sp; (void)POP(); /* POP the NULL. */ } @@ -3503,13 +4195,14 @@ main_loop: We'll be passing `oparg + 1` to call_function, to make it accept the `self` as a first argument. */ - res = call_function(tstate, &sp, oparg + 1, NULL); + res = call_function(tstate, &trace_info, &sp, oparg + 1, NULL); stack_pointer = sp; } PUSH(res); if (res == NULL) goto error; + CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -3517,12 +4210,13 @@ main_loop: PREDICTED(CALL_FUNCTION); PyObject **sp, *res; sp = stack_pointer; - res = call_function(tstate, &sp, oparg, NULL); + res = call_function(tstate, &trace_info, &sp, oparg, NULL); stack_pointer = sp; PUSH(res); if (res == NULL) { goto error; } + CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -3534,7 +4228,7 @@ main_loop: assert(PyTuple_GET_SIZE(names) <= oparg); /* We assume without checking that names contains only strings */ sp = stack_pointer; - res = call_function(tstate, &sp, oparg, names); + res = call_function(tstate, &trace_info, &sp, oparg, names); stack_pointer = sp; PUSH(res); Py_DECREF(names); @@ -3542,6 +4236,7 @@ main_loop: if (res == NULL) { goto error; } + CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -3579,7 +4274,7 @@ main_loop: } assert(PyTuple_CheckExact(callargs)); - result = do_call_core(tstate, func, callargs, kwargs); + result = do_call_core(tstate, &trace_info, func, callargs, kwargs); Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); @@ -3588,6 +4283,7 @@ main_loop: if (result == NULL) { goto error; } + CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -3605,10 +4301,10 @@ main_loop: if (oparg & 0x08) { assert(PyTuple_CheckExact(TOP())); - func ->func_closure = POP(); + func->func_closure = POP(); } if (oparg & 0x04) { - assert(PyDict_CheckExact(TOP())); + assert(PyTuple_CheckExact(TOP())); func->func_annotations = POP(); } if (oparg & 0x02) { @@ -3702,6 +4398,14 @@ main_loop: DISPATCH(); } + case TARGET(ROT_N): { + PyObject *top = TOP(); + memmove(&PEEK(oparg - 1), &PEEK(oparg), + sizeof(PyObject*) * (oparg - 1)); + PEEK(oparg) = top; + DISPATCH(); + } + case TARGET(EXTENDED_ARG): { int oldoparg = oparg; NEXTOPARG(); @@ -3741,11 +4445,15 @@ error: /* Log traceback info. */ PyTraceBack_Here(f); - if (tstate->c_tracefunc != NULL) + if (tstate->c_tracefunc != NULL) { + /* Make sure state is set to FRAME_EXECUTING for tracing */ + assert(f->f_state == FRAME_EXECUTING); + f->f_state = FRAME_UNWINDING; call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, - tstate, f); - + tstate, f, &trace_info); + } exception_unwind: + f->f_state = FRAME_UNWINDING; /* Unwind stacks if an exception occurred */ while (f->f_iblock > 0) { /* Pop the current block. */ @@ -3761,7 +4469,7 @@ exception_unwind: int handler = b->b_handler; _PyErr_StackItem *exc_info = tstate->exc_info; /* Beware, this invalidates all b->b_* fields */ - PyFrame_BlockSetup(f, EXCEPT_HANDLER, -1, STACK_LEVEL()); + PyFrame_BlockSetup(f, EXCEPT_HANDLER, f->f_lasti, STACK_LEVEL()); PUSH(exc_info->exc_traceback); PUSH(exc_info->exc_value); if (exc_info->exc_type != NULL) { @@ -3793,17 +4501,8 @@ exception_unwind: PUSH(val); PUSH(exc); JUMPTO(handler); - if (_Py_TracingPossible(ceval2)) { - int needs_new_execution_window = (f->f_lasti < instr_lb || f->f_lasti >= instr_ub); - int needs_line_update = (f->f_lasti == instr_lb || f->f_lasti < instr_prev); - /* Make sure that we trace line after exception if we are in a new execution - * window or we don't need a line update and we are not in the first instruction - * of the line. */ - if (needs_new_execution_window || (!needs_line_update && instr_lb > 0)) { - instr_prev = INT_MAX; - } - } /* Resume normal execution */ + f->f_state = FRAME_EXECUTING; goto main_loop; } } /* unwind stack */ @@ -3820,18 +4519,19 @@ exception_unwind: PyObject *o = POP(); Py_XDECREF(o); } - + f->f_stackdepth = 0; + f->f_state = FRAME_RAISED; exiting: - if (tstate->use_tracing) { + if (trace_info.cframe.use_tracing) { if (tstate->c_tracefunc) { if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - tstate, f, PyTrace_RETURN, retval)) { + tstate, f, &trace_info, PyTrace_RETURN, retval)) { Py_CLEAR(retval); } } if (tstate->c_profilefunc) { if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, - tstate, f, PyTrace_RETURN, retval)) { + tstate, f, &trace_info, PyTrace_RETURN, retval)) { Py_CLEAR(retval); } } @@ -3839,10 +4539,13 @@ exiting: /* pop frame */ exit_eval_frame: + /* Restore previous cframe */ + tstate->cframe = trace_info.cframe.previous; + tstate->cframe->use_tracing = trace_info.cframe.use_tracing; + if (PyDTrace_FUNCTION_RETURN_ENABLED()) dtrace_function_return(f); _Py_LeaveRecursiveCall(tstate); - f->f_executing = 0; tstate->frame = f->f_back; return _Py_CheckFunctionResult(tstate, NULL, retval, __func__); @@ -3850,7 +4553,7 @@ exit_eval_frame: static void format_missing(PyThreadState *tstate, const char *kind, - PyCodeObject *co, PyObject *names) + PyCodeObject *co, PyObject *names, PyObject *qualname) { int err; Py_ssize_t len = PyList_GET_SIZE(names); @@ -3903,7 +4606,7 @@ format_missing(PyThreadState *tstate, const char *kind, return; _PyErr_Format(tstate, PyExc_TypeError, "%U() missing %i required %s argument%s: %U", - co->co_name, + qualname, len, kind, len == 1 ? "" : "s", @@ -3914,7 +4617,7 @@ format_missing(PyThreadState *tstate, const char *kind, static void missing_arguments(PyThreadState *tstate, PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount, - PyObject **fastlocals) + PyObject **fastlocals, PyObject *qualname) { Py_ssize_t i, j = 0; Py_ssize_t start, end; @@ -3946,14 +4649,14 @@ missing_arguments(PyThreadState *tstate, PyCodeObject *co, } } assert(j == missing); - format_missing(tstate, kind, co, missing_names); + format_missing(tstate, kind, co, missing_names, qualname); Py_DECREF(missing_names); } static void too_many_positional(PyThreadState *tstate, PyCodeObject *co, - Py_ssize_t given, Py_ssize_t defcount, - PyObject **fastlocals) + Py_ssize_t given, PyObject *defaults, + PyObject **fastlocals, PyObject *qualname) { int plural; Py_ssize_t kwonly_given = 0; @@ -3968,6 +4671,7 @@ too_many_positional(PyThreadState *tstate, PyCodeObject *co, kwonly_given++; } } + Py_ssize_t defcount = defaults == NULL ? 0 : PyTuple_GET_SIZE(defaults); if (defcount) { Py_ssize_t atleast = co_argcount - defcount; plural = 1; @@ -3997,7 +4701,7 @@ too_many_positional(PyThreadState *tstate, PyCodeObject *co, } _PyErr_Format(tstate, PyExc_TypeError, "%U() takes %U positional argument%s but %zd%U %s given", - co->co_name, + qualname, sig, plural ? "s" : "", given, @@ -4009,7 +4713,8 @@ too_many_positional(PyThreadState *tstate, PyCodeObject *co, static int positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, - Py_ssize_t kwcount, PyObject* const* kwnames) + Py_ssize_t kwcount, PyObject* kwnames, + PyObject *qualname) { int posonly_conflicts = 0; PyObject* posonly_names = PyList_New(0); @@ -4019,7 +4724,7 @@ positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, for (int k2=0; k2co_name, error_names); + qualname, error_names); Py_DECREF(error_names); goto fail; } @@ -4068,46 +4773,30 @@ fail: } -/* This is gonna seem *real weird*, but if you put some other code between - PyEval_EvalFrame() and _PyEval_EvalFrameDefault() you will need to adjust - the test in the if statements in Misc/gdbinit (pystack and pystackv). */ -PyObject * -_PyEval_EvalCode(PyThreadState *tstate, - PyObject *_co, PyObject *globals, PyObject *locals, +PyFrameObject * +_PyEval_MakeFrameVector(PyThreadState *tstate, + PyFrameConstructor *con, PyObject *locals, PyObject *const *args, Py_ssize_t argcount, - PyObject *const *kwnames, PyObject *const *kwargs, - Py_ssize_t kwcount, int kwstep, - PyObject *const *defs, Py_ssize_t defcount, - PyObject *kwdefs, PyObject *closure, - PyObject *name, PyObject *qualname) + PyObject *kwnames) { assert(is_tstate_valid(tstate)); - PyCodeObject* co = (PyCodeObject*)_co; - PyFrameObject *f; - PyObject *retval = NULL; - PyObject **fastlocals, **freevars; - PyObject *x, *u; + PyCodeObject *co = (PyCodeObject*)con->fc_code; + assert(con->fc_defaults == NULL || PyTuple_CheckExact(con->fc_defaults)); const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; - Py_ssize_t i, j, n; - PyObject *kwdict; - - if (globals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "PyEval_EvalCodeEx: NULL globals"); - return NULL; - } /* Create the frame */ - f = _PyFrame_New_NoTrack(tstate, co, globals, locals); + PyFrameObject *f = _PyFrame_New_NoTrack(tstate, con, locals); if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; - freevars = f->f_localsplus + co->co_nlocals; + PyObject **fastlocals = f->f_localsplus; + PyObject **freevars = f->f_localsplus + co->co_nlocals; /* Create a dictionary for keyword parameters (**kwags) */ + PyObject *kwdict; + Py_ssize_t i; if (co->co_flags & CO_VARKEYWORDS) { kwdict = PyDict_New(); if (kwdict == NULL) @@ -4123,6 +4812,7 @@ _PyEval_EvalCode(PyThreadState *tstate, } /* Copy all positional arguments into local variables */ + Py_ssize_t j, n; if (argcount > co->co_argcount) { n = co->co_argcount; } @@ -4130,97 +4820,102 @@ _PyEval_EvalCode(PyThreadState *tstate, n = argcount; } for (j = 0; j < n; j++) { - x = args[j]; + PyObject *x = args[j]; Py_INCREF(x); SETLOCAL(j, x); } /* Pack other positional arguments into the *args argument */ if (co->co_flags & CO_VARARGS) { - u = _PyTuple_FromArray(args + n, argcount - n); + PyObject *u = _PyTuple_FromArray(args + n, argcount - n); if (u == NULL) { goto fail; } SETLOCAL(total_args, u); } - /* Handle keyword arguments passed as two strided arrays */ - kwcount *= kwstep; - for (i = 0; i < kwcount; i += kwstep) { - PyObject **co_varnames; - PyObject *keyword = kwnames[i]; - PyObject *value = kwargs[i]; - Py_ssize_t j; - - if (keyword == NULL || !PyUnicode_Check(keyword)) { - _PyErr_Format(tstate, PyExc_TypeError, - "%U() keywords must be strings", - co->co_name); - goto fail; - } + /* Handle keyword arguments */ + if (kwnames != NULL) { + Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < kwcount; i++) { + PyObject **co_varnames; + PyObject *keyword = PyTuple_GET_ITEM(kwnames, i); + PyObject *value = args[i+argcount]; + Py_ssize_t j; - /* Speed hack: do raw pointer compares. As names are - normally interned this should almost always hit. */ - co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; - for (j = co->co_posonlyargcount; j < total_args; j++) { - PyObject *name = co_varnames[j]; - if (name == keyword) { - goto kw_found; + if (keyword == NULL || !PyUnicode_Check(keyword)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U() keywords must be strings", + con->fc_qualname); + goto fail; } - } - /* Slow fallback, just in case */ - for (j = co->co_posonlyargcount; j < total_args; j++) { - PyObject *name = co_varnames[j]; - int cmp = PyObject_RichCompareBool( keyword, name, Py_EQ); - if (cmp > 0) { - goto kw_found; + /* Speed hack: do raw pointer compares. As names are + normally interned this should almost always hit. */ + co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; + for (j = co->co_posonlyargcount; j < total_args; j++) { + PyObject *varname = co_varnames[j]; + if (varname == keyword) { + goto kw_found; + } } - else if (cmp < 0) { - goto fail; + + /* Slow fallback, just in case */ + for (j = co->co_posonlyargcount; j < total_args; j++) { + PyObject *varname = co_varnames[j]; + int cmp = PyObject_RichCompareBool( keyword, varname, Py_EQ); + if (cmp > 0) { + goto kw_found; + } + else if (cmp < 0) { + goto fail; + } } - } - assert(j >= total_args); - if (kwdict == NULL) { + assert(j >= total_args); + if (kwdict == NULL) { - if (co->co_posonlyargcount - && positional_only_passed_as_keyword(tstate, co, - kwcount, kwnames)) - { + if (co->co_posonlyargcount + && positional_only_passed_as_keyword(tstate, co, + kwcount, kwnames, + con->fc_qualname)) + { + goto fail; + } + + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got an unexpected keyword argument '%S'", + con->fc_qualname, keyword); goto fail; } - _PyErr_Format(tstate, PyExc_TypeError, - "%U() got an unexpected keyword argument '%S'", - co->co_name, keyword); - goto fail; - } - - if (PyDict_SetItem(kwdict, keyword, value) == -1) { - goto fail; - } - continue; + if (PyDict_SetItem(kwdict, keyword, value) == -1) { + goto fail; + } + continue; - kw_found: - if (GETLOCAL(j) != NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "%U() got multiple values for argument '%S'", - co->co_name, keyword); - goto fail; + kw_found: + if (GETLOCAL(j) != NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got multiple values for argument '%S'", + con->fc_qualname, keyword); + goto fail; + } + Py_INCREF(value); + SETLOCAL(j, value); } - Py_INCREF(value); - SETLOCAL(j, value); } /* Check the number of positional arguments */ if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) { - too_many_positional(tstate, co, argcount, defcount, fastlocals); + too_many_positional(tstate, co, argcount, con->fc_defaults, fastlocals, + con->fc_qualname); goto fail; } /* Add missing positional arguments (copy default values from defs) */ if (argcount < co->co_argcount) { + Py_ssize_t defcount = con->fc_defaults == NULL ? 0 : PyTuple_GET_SIZE(con->fc_defaults); Py_ssize_t m = co->co_argcount - defcount; Py_ssize_t missing = 0; for (i = argcount; i < m; i++) { @@ -4229,18 +4924,22 @@ _PyEval_EvalCode(PyThreadState *tstate, } } if (missing) { - missing_arguments(tstate, co, missing, defcount, fastlocals); + missing_arguments(tstate, co, missing, defcount, fastlocals, + con->fc_qualname); goto fail; } if (n > m) i = n - m; else i = 0; - for (; i < defcount; i++) { - if (GETLOCAL(m+i) == NULL) { - PyObject *def = defs[i]; - Py_INCREF(def); - SETLOCAL(m+i, def); + if (defcount) { + PyObject **defs = &PyTuple_GET_ITEM(con->fc_defaults, 0); + for (; i < defcount; i++) { + if (GETLOCAL(m+i) == NULL) { + PyObject *def = defs[i]; + Py_INCREF(def); + SETLOCAL(m+i, def); + } } } } @@ -4249,12 +4948,11 @@ _PyEval_EvalCode(PyThreadState *tstate, if (co->co_kwonlyargcount > 0) { Py_ssize_t missing = 0; for (i = co->co_argcount; i < total_args; i++) { - PyObject *name; if (GETLOCAL(i) != NULL) continue; - name = PyTuple_GET_ITEM(co->co_varnames, i); - if (kwdefs != NULL) { - PyObject *def = PyDict_GetItemWithError(kwdefs, name); + PyObject *varname = PyTuple_GET_ITEM(co->co_varnames, i); + if (con->fc_kwdefaults != NULL) { + PyObject *def = PyDict_GetItemWithError(con->fc_kwdefaults, varname); if (def) { Py_INCREF(def); SETLOCAL(i, def); @@ -4267,7 +4965,8 @@ _PyEval_EvalCode(PyThreadState *tstate, missing++; } if (missing) { - missing_arguments(tstate, co, missing, -1, fastlocals); + missing_arguments(tstate, co, missing, -1, fastlocals, + con->fc_qualname); goto fail; } } @@ -4294,41 +4993,76 @@ _PyEval_EvalCode(PyThreadState *tstate, /* Copy closure variables to free variables */ for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { - PyObject *o = PyTuple_GET_ITEM(closure, i); + PyObject *o = PyTuple_GET_ITEM(con->fc_closure, i); Py_INCREF(o); freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; } - /* Handle generator/coroutine/asynchronous generator */ - if (co->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - PyObject *gen; - int is_coro = co->co_flags & CO_COROUTINE; + return f; - /* Don't need to keep the reference to f_back, it will be set - * when the generator is resumed. */ - Py_CLEAR(f->f_back); - - /* Create a new generator that owns the ready to run frame - * and return that as the value. */ - if (is_coro) { - gen = PyCoro_New(f, name, qualname); - } else if (co->co_flags & CO_ASYNC_GENERATOR) { - gen = PyAsyncGen_New(f, name, qualname); - } else { - gen = PyGen_NewWithQualName(f, name, qualname); - } - if (gen == NULL) { - return NULL; - } +fail: /* Jump here from prelude on failure */ + /* decref'ing the frame can cause __del__ methods to get invoked, + which can call back into Python. While we're done with the + current Python frame (f), the associated C stack is still in use, + so recursion_depth must be boosted for the duration. + */ + if (Py_REFCNT(f) > 1) { + Py_DECREF(f); _PyObject_GC_TRACK(f); + } + else { + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + } + return NULL; +} - return gen; +static PyObject * +make_coro(PyFrameConstructor *con, PyFrameObject *f) +{ + assert (((PyCodeObject *)con->fc_code)->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)); + PyObject *gen; + int is_coro = ((PyCodeObject *)con->fc_code)->co_flags & CO_COROUTINE; + + /* Don't need to keep the reference to f_back, it will be set + * when the generator is resumed. */ + Py_CLEAR(f->f_back); + + /* Create a new generator that owns the ready to run frame + * and return that as the value. */ + if (is_coro) { + gen = PyCoro_New(f, con->fc_name, con->fc_qualname); + } else if (((PyCodeObject *)con->fc_code)->co_flags & CO_ASYNC_GENERATOR) { + gen = PyAsyncGen_New(f, con->fc_name, con->fc_qualname); + } else { + gen = PyGen_NewWithQualName(f, con->fc_name, con->fc_qualname); + } + if (gen == NULL) { + return NULL; } - retval = _PyEval_EvalFrame(tstate, f, 0); + _PyObject_GC_TRACK(f); -fail: /* Jump here from prelude on failure */ + return gen; +} + +PyObject * +_PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con, + PyObject *locals, + PyObject* const* args, size_t argcount, + PyObject *kwnames) +{ + PyFrameObject *f = _PyEval_MakeFrameVector( + tstate, con, locals, args, argcount, kwnames); + if (f == NULL) { + return NULL; + } + if (((PyCodeObject *)con->fc_code)->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { + return make_coro(con, f); + } + PyObject *retval = _PyEval_EvalFrame(tstate, f, 0); /* decref'ing the frame can cause __del__ methods to get invoked, which can call back into Python. While we're done with the @@ -4347,26 +5081,7 @@ fail: /* Jump here from prelude on failure */ return retval; } - -PyObject * -_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, - PyObject *const *args, Py_ssize_t argcount, - PyObject *const *kwnames, PyObject *const *kwargs, - Py_ssize_t kwcount, int kwstep, - PyObject *const *defs, Py_ssize_t defcount, - PyObject *kwdefs, PyObject *closure, - PyObject *name, PyObject *qualname) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyEval_EvalCode(tstate, _co, globals, locals, - args, argcount, - kwnames, kwargs, - kwcount, kwstep, - defs, defcount, - kwdefs, closure, - name, qualname); -} - +/* Legacy API */ PyObject * PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, PyObject *const *args, int argcount, @@ -4374,15 +5089,70 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, PyObject *const *defs, int defcount, PyObject *kwdefs, PyObject *closure) { - return _PyEval_EvalCodeWithName(_co, globals, locals, - args, argcount, - kws, kws != NULL ? kws + 1 : NULL, - kwcount, 2, - defs, defcount, - kwdefs, closure, - NULL, NULL); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *res = NULL; + PyObject *defaults = _PyTuple_FromArray(defs, defcount); + if (defaults == NULL) { + return NULL; + } + PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref + if (builtins == NULL) { + Py_DECREF(defaults); + return NULL; + } + if (locals == NULL) { + locals = globals; + } + PyObject *kwnames = NULL; + PyObject *const *allargs; + PyObject **newargs = NULL; + if (kwcount == 0) { + allargs = args; + } + else { + kwnames = PyTuple_New(kwcount); + if (kwnames == NULL) { + goto fail; + } + newargs = PyMem_Malloc(sizeof(PyObject *)*(kwcount+argcount)); + if (newargs == NULL) { + goto fail; + } + for (int i = 0; i < argcount; i++) { + newargs[i] = args[i]; + } + for (int i = 0; i < kwcount; i++) { + Py_INCREF(kws[2*i]); + PyTuple_SET_ITEM(kwnames, i, kws[2*i]); + newargs[argcount+i] = kws[2*i+1]; + } + allargs = newargs; + } + for (int i = 0; i < kwcount; i++) { + Py_INCREF(kws[2*i]); + PyTuple_SET_ITEM(kwnames, i, kws[2*i]); + } + PyFrameConstructor constr = { + .fc_globals = globals, + .fc_builtins = builtins, + .fc_name = ((PyCodeObject *)_co)->co_name, + .fc_qualname = ((PyCodeObject *)_co)->co_name, + .fc_code = _co, + .fc_defaults = defaults, + .fc_kwdefaults = kwdefs, + .fc_closure = closure + }; + res = _PyEval_Vector(tstate, &constr, locals, + allargs, argcount, + kwnames); +fail: + Py_XDECREF(kwnames); + PyMem_Free(newargs); + Py_DECREF(defaults); + return res; } + static PyObject * special_lookup(PyThreadState *tstate, PyObject *o, _Py_Identifier *id) { @@ -4410,7 +5180,7 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) type = exc_info->exc_type; value = exc_info->exc_value; tb = exc_info->exc_traceback; - if (type == Py_None || type == NULL) { + if (Py_IsNone(type) || type == NULL) { _PyErr_SetString(tstate, PyExc_RuntimeError, "No active exception to reraise"); return 0; @@ -4468,7 +5238,7 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) else if (PyExceptionInstance_Check(cause)) { fixed_cause = cause; } - else if (cause == Py_None) { + else if (Py_IsNone(cause)) { Py_DECREF(cause); fixed_cause = NULL; } @@ -4594,7 +5364,6 @@ Error: return 0; } - #ifdef LLTRACE static int prtrace(PyThreadState *tstate, PyObject *v, const char *str) @@ -4614,7 +5383,9 @@ prtrace(PyThreadState *tstate, PyObject *v, const char *str) static void call_exc_trace(Py_tracefunc func, PyObject *self, - PyThreadState *tstate, PyFrameObject *f) + PyThreadState *tstate, + PyFrameObject *f, + PyTraceInfo *trace_info) { PyObject *type, *value, *traceback, *orig_traceback, *arg; int err; @@ -4630,7 +5401,7 @@ call_exc_trace(Py_tracefunc func, PyObject *self, _PyErr_Restore(tstate, type, value, orig_traceback); return; } - err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); + err = call_trace(func, self, tstate, f, trace_info, PyTrace_EXCEPTION, arg); Py_DECREF(arg); if (err == 0) { _PyErr_Restore(tstate, type, value, orig_traceback); @@ -4645,12 +5416,13 @@ call_exc_trace(Py_tracefunc func, PyObject *self, static int call_trace_protected(Py_tracefunc func, PyObject *obj, PyThreadState *tstate, PyFrameObject *frame, + PyTraceInfo *trace_info, int what, PyObject *arg) { PyObject *type, *value, *traceback; int err; _PyErr_Fetch(tstate, &type, &value, &traceback); - err = call_trace(func, obj, tstate, frame, what, arg); + err = call_trace(func, obj, tstate, frame, trace_info, what, arg); if (err == 0) { _PyErr_Restore(tstate, type, value, traceback); @@ -4664,18 +5436,36 @@ call_trace_protected(Py_tracefunc func, PyObject *obj, } } +static void +initialize_trace_info(PyTraceInfo *trace_info, PyFrameObject *frame) +{ + if (trace_info->code != frame->f_code) { + trace_info->code = frame->f_code; + _PyCode_InitAddressRange(frame->f_code, &trace_info->bounds); + } +} + static int call_trace(Py_tracefunc func, PyObject *obj, PyThreadState *tstate, PyFrameObject *frame, + PyTraceInfo *trace_info, int what, PyObject *arg) { int result; if (tstate->tracing) return 0; tstate->tracing++; - tstate->use_tracing = 0; + tstate->cframe->use_tracing = 0; + if (frame->f_lasti < 0) { + frame->f_lineno = frame->f_code->co_firstlineno; + } + else { + initialize_trace_info(trace_info, frame); + frame->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &trace_info->bounds); + } result = func(obj, frame, what, arg); - tstate->use_tracing = ((tstate->c_tracefunc != NULL) + frame->f_lineno = 0; + tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL) || (tstate->c_profilefunc != NULL)); tstate->tracing--; return result; @@ -4686,15 +5476,15 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) { PyThreadState *tstate = _PyThreadState_GET(); int save_tracing = tstate->tracing; - int save_use_tracing = tstate->use_tracing; + int save_use_tracing = tstate->cframe->use_tracing; PyObject *result; tstate->tracing = 0; - tstate->use_tracing = ((tstate->c_tracefunc != NULL) + tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL) || (tstate->c_profilefunc != NULL)); result = PyObject_Call(func, args, NULL); tstate->tracing = save_tracing; - tstate->use_tracing = save_use_tracing; + tstate->cframe->use_tracing = save_use_tracing; return result; } @@ -4702,36 +5492,27 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) static int maybe_call_line_trace(Py_tracefunc func, PyObject *obj, PyThreadState *tstate, PyFrameObject *frame, - int *instr_lb, int *instr_ub, int *instr_prev) + PyTraceInfo *trace_info, int instr_prev) { int result = 0; - int line = frame->f_lineno; - /* If the last instruction executed isn't in the current - instruction window, reset the window. - */ - if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) { - PyAddrPair bounds; - line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti, - &bounds); - *instr_lb = bounds.ap_lower; - *instr_ub = bounds.ap_upper; - } /* 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 ((frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev)) { - frame->f_lineno = line; - if (frame->f_trace_lines) { - result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); + initialize_trace_info(trace_info, frame); + int lastline = _PyCode_CheckLineNumber(instr_prev*sizeof(_Py_CODEUNIT), &trace_info->bounds); + int line = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &trace_info->bounds); + if (line != -1 && frame->f_trace_lines) { + /* Trace backward edges or if line number has changed */ + if (frame->f_lasti < instr_prev || line != lastline) { + result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_LINE, Py_None); } } /* Always emit an opcode event if we're tracing all opcodes. */ if (frame->f_trace_opcodes) { - result = call_trace(func, obj, tstate, frame, PyTrace_OPCODE, Py_None); + result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_OPCODE, Py_None); } - *instr_prev = frame->f_lasti; return result; } @@ -4754,7 +5535,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) tstate->c_profilefunc = NULL; tstate->c_profileobj = NULL; /* Must make sure that tracing is not ignored if 'profileobj' is freed */ - tstate->use_tracing = tstate->c_tracefunc != NULL; + tstate->cframe->use_tracing = tstate->c_tracefunc != NULL; Py_XDECREF(profileobj); Py_XINCREF(arg); @@ -4762,7 +5543,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) tstate->c_profilefunc = func; /* Flag that tracing or profiling is turned on */ - tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); + tstate->cframe->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); return 0; } @@ -4790,14 +5571,12 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) return -1; } - struct _ceval_state *ceval2 = &tstate->interp->ceval; PyObject *traceobj = tstate->c_traceobj; - ceval2->tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL); tstate->c_tracefunc = NULL; tstate->c_traceobj = NULL; /* Must make sure that profiling is not ignored if 'traceobj' is freed */ - tstate->use_tracing = (tstate->c_profilefunc != NULL); + tstate->cframe->use_tracing = (tstate->c_profilefunc != NULL); Py_XDECREF(traceobj); Py_XINCREF(arg); @@ -4805,7 +5584,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) tstate->c_tracefunc = func; /* Flag that tracing or profiling is turned on */ - tstate->use_tracing = ((func != NULL) + tstate->cframe->use_tracing = ((func != NULL) || (tstate->c_profilefunc != NULL)); return 0; @@ -4885,15 +5664,21 @@ PyEval_GetFrame(void) return tstate->frame; } +PyObject * +_PyEval_GetBuiltins(PyThreadState *tstate) +{ + PyFrameObject *frame = tstate->frame; + if (frame != NULL) { + return frame->f_builtins; + } + return tstate->interp->builtins; +} + PyObject * PyEval_GetBuiltins(void) { PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *current_frame = tstate->frame; - if (current_frame == NULL) - return tstate->interp->builtins; - else - return current_frame->f_builtins; + return _PyEval_GetBuiltins(tstate); } /* Convenience function to get a builtin from its name */ @@ -4994,9 +5779,9 @@ PyEval_GetFuncDesc(PyObject *func) } #define C_TRACE(x, call) \ -if (tstate->use_tracing && tstate->c_profilefunc) { \ +if (trace_info->cframe.use_tracing && tstate->c_profilefunc) { \ if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \ - tstate, tstate->frame, \ + tstate, tstate->frame, trace_info, \ PyTrace_C_CALL, func)) { \ x = NULL; \ } \ @@ -5006,13 +5791,13 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \ if (x == NULL) { \ call_trace_protected(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate, tstate->frame, \ + tstate, tstate->frame, trace_info, \ PyTrace_C_EXCEPTION, func); \ /* XXX should pass (type, value, tb) */ \ } else { \ if (call_trace(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate, tstate->frame, \ + tstate, tstate->frame, trace_info, \ PyTrace_C_RETURN, func)) { \ Py_DECREF(x); \ x = NULL; \ @@ -5027,6 +5812,7 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \ static PyObject * trace_call_function(PyThreadState *tstate, + PyTraceInfo *trace_info, PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) @@ -5061,7 +5847,11 @@ trace_call_function(PyThreadState *tstate, /* Issue #29227: Inline call_function() into _PyEval_EvalFrameDefault() to reduce the stack consumption. */ Py_LOCAL_INLINE(PyObject *) _Py_HOT_FUNCTION -call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames) +call_function(PyThreadState *tstate, + PyTraceInfo *trace_info, + PyObject ***pp_stack, + Py_ssize_t oparg, + PyObject *kwnames) { PyObject **pfunc = (*pp_stack) - oparg - 1; PyObject *func = *pfunc; @@ -5070,8 +5860,8 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO Py_ssize_t nargs = oparg - nkwargs; PyObject **stack = (*pp_stack) - nargs - nkwargs; - if (tstate->use_tracing) { - x = trace_call_function(tstate, func, stack, nargs, kwnames); + if (trace_info->cframe.use_tracing) { + x = trace_call_function(tstate, trace_info, func, stack, nargs, kwnames); } else { x = PyObject_Vectorcall(func, stack, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); @@ -5089,7 +5879,11 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO } static PyObject * -do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject *kwdict) +do_call_core(PyThreadState *tstate, + PyTraceInfo *trace_info, + PyObject *func, + PyObject *callargs, + PyObject *kwdict) { PyObject *result; @@ -5099,7 +5893,7 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject } else if (Py_IS_TYPE(func, &PyMethodDescr_Type)) { Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); - if (nargs > 0 && tstate->use_tracing) { + if (nargs > 0 && trace_info->cframe.use_tracing) { /* We need to create a temporary bound method as argument for profiling. @@ -5135,7 +5929,7 @@ int _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) { PyThreadState *tstate = _PyThreadState_GET(); - if (v != Py_None) { + if (!Py_IsNone(v)) { Py_ssize_t x; if (_PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); @@ -5459,6 +6253,23 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc, return; _PyErr_Format(tstate, exc, format_str, obj_str); + + if (exc == PyExc_NameError) { + // Include the name in the NameError exceptions to offer suggestions later. + _Py_IDENTIFIER(name); + 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) { + // We do not care if this fails because we are going to restore the + // NameError anyway. + (void)_PyObject_SetAttrId(value, &PyId_name, obj); + } + } + PyErr_Restore(type, value, traceback); + } } static void @@ -5626,7 +6437,7 @@ dtrace_function_entry(PyFrameObject *f) PyCodeObject *code = f->f_code; filename = PyUnicode_AsUTF8(code->co_filename); funcname = PyUnicode_AsUTF8(code->co_name); - lineno = PyCode_Addr2Line(code, f->f_lasti); + lineno = PyFrame_GetLineNumber(f); PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); } @@ -5641,7 +6452,7 @@ dtrace_function_return(PyFrameObject *f) PyCodeObject *code = f->f_code; filename = PyUnicode_AsUTF8(code->co_filename); funcname = PyUnicode_AsUTF8(code->co_name); - lineno = PyCode_Addr2Line(code, f->f_lasti); + lineno = PyFrame_GetLineNumber(f); PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); } @@ -5649,35 +6460,30 @@ dtrace_function_return(PyFrameObject *f) /* DTrace equivalent of maybe_call_line_trace. */ static void maybe_dtrace_line(PyFrameObject *frame, - int *instr_lb, int *instr_ub, int *instr_prev) + PyTraceInfo *trace_info, int instr_prev) { - int line = frame->f_lineno; const char *co_filename, *co_name; /* If the last instruction executed isn't in the current instruction window, reset the window. */ - if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) { - PyAddrPair bounds; - line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti, - &bounds); - *instr_lb = bounds.ap_lower; - *instr_ub = bounds.ap_upper; - } + initialize_trace_info(trace_info, frame); + int line = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &trace_info->bounds); /* 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 call the trace function. */ - if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) { - frame->f_lineno = line; - 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); - } - *instr_prev = frame->f_lasti; + if (line != frame->f_lineno || frame->f_lasti < instr_prev) { + if (line != -1) { + frame->f_lineno = line; + 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); + } + } } diff --git a/contrib/tools/python3/src/Python/ceval_gil.h b/contrib/tools/python3/src/Python/ceval_gil.h index 3510675a69b..9b8b43253f0 100644 --- a/contrib/tools/python3/src/Python/ceval_gil.h +++ b/contrib/tools/python3/src/Python/ceval_gil.h @@ -144,7 +144,11 @@ static void drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, PyThreadState *tstate) { +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + struct _gil_runtime_state *gil = &ceval2->gil; +#else struct _gil_runtime_state *gil = &ceval->gil; +#endif if (!_Py_atomic_load_relaxed(&gil->locked)) { Py_FatalError("drop_gil: GIL is not locked"); } @@ -228,7 +232,11 @@ take_gil(PyThreadState *tstate) PyInterpreterState *interp = tstate->interp; struct _ceval_runtime_state *ceval = &interp->runtime->ceval; struct _ceval_state *ceval2 = &interp->ceval; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + struct _gil_runtime_state *gil = &ceval2->gil; +#else struct _gil_runtime_state *gil = &ceval->gil; +#endif /* Check that _PyEval_InitThreads() was called to create the lock */ assert(gil_created(gil)); @@ -310,7 +318,7 @@ _ready: /* Don't access tstate if the thread must exit */ if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(tstate); + _PyEval_SignalAsyncExc(tstate->interp); } MUTEX_UNLOCK(gil->mutex); @@ -320,12 +328,22 @@ _ready: void _PyEval_SetSwitchInterval(unsigned long microseconds) { +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + PyInterpreterState *interp = PyInterpreterState_Get(); + struct _gil_runtime_state *gil = &interp->ceval.gil; +#else struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; +#endif gil->interval = microseconds; } unsigned long _PyEval_GetSwitchInterval() { +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + PyInterpreterState *interp = PyInterpreterState_Get(); + struct _gil_runtime_state *gil = &interp->ceval.gil; +#else struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; +#endif return gil->interval; } diff --git a/contrib/tools/python3/src/Python/clinic/_warnings.c.h b/contrib/tools/python3/src/Python/clinic/_warnings.c.h index 67ab0e3d9de..ad6b9a8e242 100644 --- a/contrib/tools/python3/src/Python/clinic/_warnings.c.h +++ b/contrib/tools/python3/src/Python/clinic/_warnings.c.h @@ -43,14 +43,9 @@ warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec } } if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } { Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); + PyObject *iobj = _PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -71,4 +66,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=b7bb54c73b5433ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eb9997fa998fdbad input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h b/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h index d15af1f7f37..545f5b53f6e 100644 --- a/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h +++ b/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h @@ -134,11 +134,6 @@ builtin_chr(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int i; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } i = _PyLong_AsInt(arg); if (i == -1 && PyErr_Occurred()) { goto exit; @@ -216,11 +211,6 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } if (args[3]) { - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flags = _PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; @@ -230,11 +220,6 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[4]) { - if (PyFloat_Check(args[4])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } dont_inherit = _PyLong_AsInt(args[4]); if (dont_inherit == -1 && PyErr_Occurred()) { goto exit; @@ -244,11 +229,6 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[5]) { - if (PyFloat_Check(args[5])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } optimize = _PyLong_AsInt(args[5]); if (optimize == -1 && PyErr_Occurred()) { goto exit; @@ -261,11 +241,6 @@ skip_optional_pos: if (!noptargs) { goto skip_optional_kwonly; } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } feature_version = _PyLong_AsInt(args[6]); if (feature_version == -1 && PyErr_Occurred()) { goto exit; @@ -555,6 +530,50 @@ PyDoc_STRVAR(builtin_hex__doc__, #define BUILTIN_HEX_METHODDEF \ {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, +PyDoc_STRVAR(builtin_aiter__doc__, +"aiter($module, async_iterable, /)\n" +"--\n" +"\n" +"Return an AsyncIterator for an AsyncIterable object."); + +#define BUILTIN_AITER_METHODDEF \ + {"aiter", (PyCFunction)builtin_aiter, METH_O, builtin_aiter__doc__}, + +PyDoc_STRVAR(builtin_anext__doc__, +"anext($module, aiterator, default=, /)\n" +"--\n" +"\n" +"Return the next item from the async iterator."); + +#define BUILTIN_ANEXT_METHODDEF \ + {"anext", (PyCFunction)(void(*)(void))builtin_anext, METH_FASTCALL, builtin_anext__doc__}, + +static PyObject * +builtin_anext_impl(PyObject *module, PyObject *aiterator, + PyObject *default_value); + +static PyObject * +builtin_anext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *aiterator; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("anext", nargs, 1, 2)) { + goto exit; + } + aiterator = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = builtin_anext_impl(module, aiterator, default_value); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_len__doc__, "len($module, obj, /)\n" "--\n" @@ -825,11 +844,11 @@ PyDoc_STRVAR(builtin_issubclass__doc__, "issubclass($module, cls, class_or_tuple, /)\n" "--\n" "\n" -"Return whether \'cls\' is a derived from another class or is the same class.\n" +"Return whether \'cls\' is derived from another class or is the same class.\n" "\n" "A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to\n" "check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)\n" -"or ...`` etc."); +"or ...``."); #define BUILTIN_ISSUBCLASS_METHODDEF \ {"issubclass", (PyCFunction)(void(*)(void))builtin_issubclass, METH_FASTCALL, builtin_issubclass__doc__}, @@ -855,4 +874,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=29686a89b739d600 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=da9ae459e9233259 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/import.c.h b/contrib/tools/python3/src/Python/clinic/import.c.h index e4867f34d4e..4e013cc97d6 100644 --- a/contrib/tools/python3/src/Python/clinic/import.c.h +++ b/contrib/tools/python3/src/Python/clinic/import.c.h @@ -420,11 +420,6 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } key = PyLong_AsLong(args[0]); if (key == -1 && PyErr_Occurred()) { goto exit; @@ -454,4 +449,4 @@ exit: #ifndef _IMP_EXEC_DYNAMIC_METHODDEF #define _IMP_EXEC_DYNAMIC_METHODDEF #endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=3dc495e9c64d944e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7c31c433af88af6b input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/marshal.c.h b/contrib/tools/python3/src/Python/clinic/marshal.c.h index 05d4830c4ab..f80d5ef31f2 100644 --- a/contrib/tools/python3/src/Python/clinic/marshal.c.h +++ b/contrib/tools/python3/src/Python/clinic/marshal.c.h @@ -42,11 +42,6 @@ marshal_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } version = _PyLong_AsInt(args[2]); if (version == -1 && PyErr_Occurred()) { goto exit; @@ -111,11 +106,6 @@ marshal_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } version = _PyLong_AsInt(args[1]); if (version == -1 && PyErr_Occurred()) { goto exit; @@ -165,4 +155,4 @@ exit: return return_value; } -/*[clinic end generated code: output=a859dabe8b0afeb6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=68b78f38bfe0c06d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/sysmodule.c.h b/contrib/tools/python3/src/Python/clinic/sysmodule.c.h index 4615ebaab5d..04c84811498 100644 --- a/contrib/tools/python3/src/Python/clinic/sysmodule.c.h +++ b/contrib/tools/python3/src/Python/clinic/sysmodule.c.h @@ -372,11 +372,6 @@ sys_setrecursionlimit(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int new_limit; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } new_limit = _PyLong_AsInt(arg); if (new_limit == -1 && PyErr_Occurred()) { goto exit; @@ -417,11 +412,6 @@ sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, if (!args) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } depth = _PyLong_AsInt(args[0]); if (depth == -1 && PyErr_Occurred()) { goto exit; @@ -590,11 +580,6 @@ sys_setdlopenflags(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int new_val; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } new_val = _PyLong_AsInt(arg); if (new_val == -1 && PyErr_Occurred()) { goto exit; @@ -650,11 +635,6 @@ sys_mdebug(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } flag = _PyLong_AsInt(arg); if (flag == -1 && PyErr_Occurred()) { goto exit; @@ -790,11 +770,6 @@ sys__getframe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } depth = _PyLong_AsInt(args[0]); if (depth == -1 && PyErr_Occurred()) { goto exit; @@ -826,6 +801,26 @@ sys__current_frames(PyObject *module, PyObject *Py_UNUSED(ignored)) return sys__current_frames_impl(module); } +PyDoc_STRVAR(sys__current_exceptions__doc__, +"_current_exceptions($module, /)\n" +"--\n" +"\n" +"Return a dict mapping each thread\'s identifier to its current raised exception.\n" +"\n" +"This function should be used for specialized purposes only."); + +#define SYS__CURRENT_EXCEPTIONS_METHODDEF \ + {"_current_exceptions", (PyCFunction)sys__current_exceptions, METH_NOARGS, sys__current_exceptions__doc__}, + +static PyObject * +sys__current_exceptions_impl(PyObject *module); + +static PyObject * +sys__current_exceptions(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__current_exceptions_impl(module); +} + PyDoc_STRVAR(sys_call_tracing__doc__, "call_tracing($module, func, args, /)\n" "--\n" @@ -943,6 +938,24 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(ANDROID_API_LEVEL) */ +PyDoc_STRVAR(sys__deactivate_opcache__doc__, +"_deactivate_opcache($module, /)\n" +"--\n" +"\n" +"Deactivate the opcode cache permanently"); + +#define SYS__DEACTIVATE_OPCACHE_METHODDEF \ + {"_deactivate_opcache", (PyCFunction)sys__deactivate_opcache, METH_NOARGS, sys__deactivate_opcache__doc__}, + +static PyObject * +sys__deactivate_opcache_impl(PyObject *module); + +static PyObject * +sys__deactivate_opcache(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__deactivate_opcache_impl(module); +} + #ifndef SYS_GETWINDOWSVERSION_METHODDEF #define SYS_GETWINDOWSVERSION_METHODDEF #endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ @@ -970,4 +983,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=39eb34a01fb9a919 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=68c62b9ca317a0c8 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/traceback.c.h b/contrib/tools/python3/src/Python/clinic/traceback.c.h index 04daf2a3766..404a0c416d3 100644 --- a/contrib/tools/python3/src/Python/clinic/traceback.c.h +++ b/contrib/tools/python3/src/Python/clinic/traceback.c.h @@ -36,20 +36,10 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } tb_frame = (PyFrameObject *)fastargs[1]; - if (PyFloat_Check(fastargs[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } tb_lasti = _PyLong_AsInt(fastargs[2]); if (tb_lasti == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(fastargs[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } tb_lineno = _PyLong_AsInt(fastargs[3]); if (tb_lineno == -1 && PyErr_Occurred()) { goto exit; @@ -59,4 +49,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=3def6c06248feed8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=403778d7af5ebef9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/codecs.c b/contrib/tools/python3/src/Python/codecs.c index 0f18c27e5fe..fa329ce2436 100644 --- a/contrib/tools/python3/src/Python/codecs.c +++ b/contrib/tools/python3/src/Python/codecs.c @@ -11,7 +11,7 @@ Copyright (c) Corporation for National Research Initiatives. #include "Python.h" #include "pycore_interp.h" // PyInterpreterState.codec_search_path #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "ucnhash.h" +#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include const char *Py_hexdigits = "0123456789abcdef"; @@ -50,6 +50,31 @@ int PyCodec_Register(PyObject *search_function) return -1; } +int +PyCodec_Unregister(PyObject *search_function) +{ + PyInterpreterState *interp = PyInterpreterState_Get(); + PyObject *codec_search_path = interp->codec_search_path; + /* Do nothing if codec_search_path is not created yet or was cleared. */ + if (codec_search_path == NULL) { + return 0; + } + + assert(PyList_CheckExact(codec_search_path)); + Py_ssize_t n = PyList_GET_SIZE(codec_search_path); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *item = PyList_GET_ITEM(codec_search_path, i); + if (item == search_function) { + if (interp->codec_search_cache != NULL) { + assert(PyDict_CheckExact(interp->codec_search_cache)); + PyDict_Clear(interp->codec_search_cache); + } + return PyList_SetSlice(codec_search_path, i, i+1, NULL); + } + } + return 0; +} + extern int _Py_normalize_encoding(const char *, char *, size_t); /* Convert a string to a normalized Python string(decoded from UTF-8): all characters are @@ -183,31 +208,6 @@ PyObject *_PyCodec_Lookup(const char *encoding) return NULL; } -int _PyCodec_Forget(const char *encoding) -{ - PyObject *v; - int result; - - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->codec_search_path == NULL) { - return -1; - } - - /* Convert the encoding to a normalized Python string: all - characters are converted to lower case, spaces and hyphens are - replaced with underscores. */ - v = normalizestring(encoding); - if (v == NULL) { - return -1; - } - - /* Drop the named codec from the internal cache */ - result = PyDict_DelItem(interp->codec_search_cache, v); - Py_DECREF(v); - - return result; -} - /* Codec registry encoding check API. */ int PyCodec_KnownEncoding(const char *encoding) @@ -954,7 +954,7 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) return Py_BuildValue("(Nn)", res, end); } -static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL; +static _PyUnicode_Name_CAPI *ucnhash_capi = NULL; PyObject *PyCodec_NameReplaceErrors(PyObject *exc) { @@ -976,17 +976,18 @@ PyObject *PyCodec_NameReplaceErrors(PyObject *exc) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; - if (!ucnhash_CAPI) { + if (!ucnhash_capi) { /* load the unicode data module */ - ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import( + ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( PyUnicodeData_CAPSULE_NAME, 1); - if (!ucnhash_CAPI) + if (!ucnhash_capi) { return NULL; + } } for (i = start, ressize = 0; i < end; ++i) { /* object is guaranteed to be "ready" */ c = PyUnicode_READ_CHAR(object, i); - if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) { + if (ucnhash_capi->getname(c, buffer, sizeof(buffer), 1)) { replsize = 1+1+1+(int)strlen(buffer)+1; } else if (c >= 0x10000) { @@ -1009,7 +1010,7 @@ PyObject *PyCodec_NameReplaceErrors(PyObject *exc) i < end; ++i) { c = PyUnicode_READ_CHAR(object, i); *outp++ = '\\'; - if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) { + if (ucnhash_capi->getname(c, buffer, sizeof(buffer), 1)) { *outp++ = 'N'; *outp++ = '{'; strcpy((char *)outp, buffer); diff --git a/contrib/tools/python3/src/Python/compile.c b/contrib/tools/python3/src/Python/compile.c index 28003b66bd4..f012406c066 100644 --- a/contrib/tools/python3/src/Python/compile.c +++ b/contrib/tools/python3/src/Python/compile.c @@ -1,7 +1,7 @@ /* * This file compiles an abstract syntax tree (AST) into Python bytecode. * - * The primary entry point is PyAST_Compile(), which returns a + * The primary entry point is _PyAST_Compile(), which returns a * PyCodeObject. The compiler makes several passes to build the code * object: * 1. Checks for future statements. See future.c @@ -9,7 +9,7 @@ * 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). See peephole.c + * 5. Optimize the byte code (peephole optimizations). * * Note that compiler_mod() suggests module, but the module ast type * (mod_ty) has cases for expressions and interactive statements. @@ -21,14 +21,19 @@ * objects. */ +#include + #include "Python.h" +#include "pycore_ast.h" // _PyAST_GetDocString() +#include "pycore_compile.h" // _PyFuture_FromAST() +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_symtable.h" // PySTEntryObject + +#define NEED_OPCODE_JUMP_TABLES +#include "opcode.h" // EXTENDED_ARG +#include "wordcode_helpers.h" // instrsize() -#include "Python-ast.h" -#include "ast.h" -#include "code.h" -#include "symtable.h" -#include "opcode.h" -#include "wordcode_helpers.h" #define DEFAULT_BLOCK_SIZE 16 #define DEFAULT_BLOCKS 8 @@ -40,19 +45,67 @@ #define COMP_SETCOMP 2 #define COMP_DICTCOMP 3 +/* A soft limit for stack use, to avoid excessive + * memory use for large constants, etc. + * + * The value 30 is plucked out of thin air. + * Code that could use more stack than this is + * rare, so the exact value is unimportant. + */ +#define STACK_USE_GUIDELINE 30 + +/* If we exceed this limit, it should + * be considered a compiler bug. + * Currently it should be impossible + * to exceed STACK_USE_GUIDELINE * 100, + * as 100 is the maximum parse depth. + * For performance reasons we will + * want to reduce this to a + * few hundred in the future. + * + * NOTE: Whatever MAX_ALLOWED_STACK_USE is + * set to, it should never restrict what Python + * we can write, just how we compile it. + */ +#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)) struct instr { - unsigned i_jabs : 1; - unsigned i_jrel : 1; unsigned char i_opcode; int i_oparg; struct basicblock_ *i_target; /* target block (if jump instruction) */ int i_lineno; }; +#define LOG_BITS_PER_INT 5 +#define MASK_LOW_LOG_BITS 31 + +static inline int +is_bit_set_in_table(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. + */ + uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; + return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; +} + +static inline int +is_relative_jump(struct instr *i) +{ + return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode); +} + +static inline int +is_jump(struct instr *i) +{ + return is_bit_set_in_table(_PyOpcode_Jump, i->i_opcode); +} + 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 @@ -67,10 +120,16 @@ typedef struct basicblock_ { /* If b_next is non-NULL, it is a pointer to the next block reached by normal control flow. */ struct basicblock_ *b_next; - /* b_seen is used to perform a DFS of basicblocks. */ - unsigned b_seen : 1; /* b_return is true if a RETURN_VALUE opcode is inserted. */ unsigned b_return : 1; + /* Number of predecssors that a block has. */ + int b_predecessors; + /* Basic block has no fall through (it ends with a return, raise or jump) */ + unsigned b_nofallthrough : 1; + /* Basic block exits scope (it ends with a return or raise) */ + unsigned b_exit : 1; + /* Used by compiler passes to mark whether they have visited a basic block. */ + unsigned b_visited : 1; /* depth of stack upon entry of block, computed by stackdepth() */ int b_startdepth; /* instruction offset for block, computed by assemble_jump_offsets() */ @@ -85,7 +144,8 @@ compiler IR. */ enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, - WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER }; + WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER, + ASYNC_COMPREHENSION_GENERATOR }; struct fblockinfo { enum fblocktype fb_type; @@ -141,6 +201,8 @@ struct compiler_unit { 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 */ }; /* This struct captures the global state of a compilation. @@ -164,12 +226,6 @@ struct compiler { int c_optimize; /* optimization level */ int c_interactive; /* true if in interactive mode */ int c_nestlevel; - int c_do_not_emit_bytecode; /* The compiler won't emit any bytecode - if this value is different from zero. - This can be used to temporarily visit - nodes without emitting bytecode to - check only errors. */ - PyObject *c_const_cache; /* Python dict holding all constants, including names tuple */ struct compiler_unit *u; /* compiler state for current block */ @@ -177,14 +233,40 @@ struct compiler { PyArena *c_arena; /* pointer to memory allocation arena */ }; +typedef struct { + // A list of strings corresponding to name captures. It is used to track: + // - Repeated name assignments in the same pattern. + // - Different name assignments in alternatives. + // - The order of name assignments in alternatives. + PyObject *stores; + // If 0, any name captures against our subject will raise. + int allow_irrefutable; + // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop + // i items off of the stack. The end result looks like this (with each block + // falling through to the next): + // fail_pop[4]: POP_TOP + // fail_pop[3]: POP_TOP + // fail_pop[2]: POP_TOP + // fail_pop[1]: POP_TOP + // fail_pop[0]: NOP + basicblock **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 + // stack. Variable captures go beneath these. All of them will be popped on + // failure. + Py_ssize_t on_top; +} pattern_context; + static int compiler_enter_scope(struct compiler *, identifier, int, void *, int); 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 *, int); -static int compiler_error(struct compiler *, const char *); +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); @@ -198,30 +280,35 @@ static int compiler_subscript(struct compiler *, expr_ty); static int compiler_slice(struct compiler *, expr_ty); static int inplace_binop(operator_ty); -static int are_all_items_const(asdl_seq *, Py_ssize_t, Py_ssize_t); -static int expr_constant(expr_ty); +static int 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 compiler_call_helper(struct compiler *c, int n, - asdl_seq *args, - asdl_seq *keywords); + asdl_expr_seq *args, + asdl_keyword_seq *keywords); static int compiler_try_except(struct compiler *, stmt_ty); static int compiler_set_qualname(struct compiler *); static int compiler_sync_comprehension_generator( struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type); static int compiler_async_comprehension_generator( struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type); +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 PyCodeObject *assemble(struct compiler *, int addNone); static PyObject *__doc__, *__annotations__; @@ -315,8 +402,8 @@ compiler_init(struct compiler *c) } PyCodeObject * -PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, - int optimize, PyArena *arena) +_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, + int optimize, PyArena *arena) { struct compiler c; PyCodeObject *co = NULL; @@ -338,7 +425,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, Py_INCREF(filename); c.c_filename = filename; c.c_arena = arena; - c.c_future = PyFuture_FromASTObject(mod, filename); + c.c_future = _PyFuture_FromAST(mod, filename); if (c.c_future == NULL) goto finally; if (!flags) { @@ -350,7 +437,6 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, c.c_flags = flags; c.c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize; c.c_nestlevel = 0; - c.c_do_not_emit_bytecode = 0; _PyASTOptimizeState state; state.optimize = c.c_optimize; @@ -360,7 +446,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, goto finally; } - c.c_st = PySymtable_BuildObject(mod, filename, c.c_future); + c.c_st = _PySymtable_Build(mod, filename, c.c_future); if (c.c_st == NULL) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_SystemError, "no symtable"); @@ -375,41 +461,11 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, return co; } -PyCodeObject * -PyAST_CompileEx(mod_ty mod, const char *filename_str, PyCompilerFlags *flags, - int optimize, PyArena *arena) -{ - PyObject *filename; - PyCodeObject *co; - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - co = PyAST_CompileObject(mod, filename, flags, optimize, arena); - Py_DECREF(filename); - return co; - -} - -PyCodeObject * -PyNode_Compile(struct _node *n, const char *filename) -{ - PyCodeObject *co = NULL; - mod_ty mod; - PyArena *arena = PyArena_New(); - if (!arena) - return NULL; - mod = PyAST_FromNode(n, NULL, filename, arena); - if (mod) - co = PyAST_Compile(mod, filename, NULL, arena); - PyArena_Free(arena); - return co; -} - static void compiler_free(struct compiler *c) { if (c->c_st) - PySymtable_Free(c->c_st); + _PySymtable_Free(c->c_st); if (c->c_future) PyObject_Free(c->c_future); Py_XDECREF(c->c_filename); @@ -480,8 +536,8 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) /* XXX this should probably be a macro in symtable.h */ long vi; k = PyList_GET_ITEM(sorted_keys, key_i); - v = PyDict_GetItem(src, k); - assert(PyLong_Check(v)); + v = PyDict_GetItemWithError(src, k); + assert(v && PyLong_Check(v)); vi = PyLong_AS_LONG(v); scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK; @@ -511,12 +567,10 @@ compiler_unit_check(struct compiler_unit *u) { basicblock *block; for (block = u->u_blocks; block != NULL; block = block->b_list) { - assert((uintptr_t)block != 0xcbcbcbcbU); - assert((uintptr_t)block != 0xfbfbfbfbU); - assert((uintptr_t)block != 0xdbdbdbdbU); + assert(!_PyMem_IsPtrFreed(block)); if (block->b_instr != NULL) { assert(block->b_ialloc > 0); - assert(block->b_iused > 0); + assert(block->b_iused >= 0); assert(block->b_ialloc >= block->b_iused); } else { @@ -594,7 +648,7 @@ compiler_enter_scope(struct compiler *c, identifier name, compiler_unit_free(u); return 0; } - res = PyDict_SetItem(u->u_cellvars, name, _PyLong_Zero); + res = PyDict_SetItem(u->u_cellvars, name, _PyLong_GetZero()); if (res < 0) { compiler_unit_free(u); return 0; @@ -613,6 +667,8 @@ compiler_enter_scope(struct compiler *c, identifier name, u->u_firstlineno = lineno; u->u_lineno = 0; u->u_col_offset = 0; + u->u_end_lineno = 0; + u->u_end_col_offset = 0; u->u_consts = PyDict_New(); if (!u->u_consts) { compiler_unit_free(u); @@ -658,25 +714,30 @@ compiler_enter_scope(struct compiler *c, identifier name, static void compiler_exit_scope(struct compiler *c) { - Py_ssize_t n; - PyObject *capsule; + // Don't call PySequence_DelItem() with an exception raised + PyObject *exc_type, *exc_val, *exc_tb; + PyErr_Fetch(&exc_type, &exc_val, &exc_tb); c->c_nestlevel--; compiler_unit_free(c->u); /* Restore c->u to the parent unit. */ - n = PyList_GET_SIZE(c->c_stack) - 1; + Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1; if (n >= 0) { - capsule = PyList_GET_ITEM(c->c_stack, n); + PyObject *capsule = PyList_GET_ITEM(c->c_stack, n); c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); assert(c->u); /* we are deleting from a list so this really shouldn't fail */ - if (PySequence_DelItem(c->c_stack, n) < 0) - Py_FatalError("compiler_exit_scope()"); + if (PySequence_DelItem(c->c_stack, n) < 0) { + _PyErr_WriteUnraisableMsg("on removing the last compiler " + "stack item", NULL); + } compiler_unit_check(c->u); } - else + else { c->u = NULL; + } + PyErr_Restore(exc_type, exc_val, exc_tb); } static int @@ -707,7 +768,7 @@ compiler_set_qualname(struct compiler *c) mangled = _Py_Mangle(parent->u_private, u->u_name); if (!mangled) return 0; - scope = PyST_GetScope(parent->u_ste, mangled); + scope = _PyST_GetScope(parent->u_ste, mangled); Py_DECREF(mangled); assert(scope != GLOBAL_IMPLICIT); if (scope == GLOBAL_EXPLICIT) @@ -798,6 +859,29 @@ compiler_use_next_block(struct compiler *c, basicblock *block) 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; + } + 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. @@ -855,7 +939,9 @@ compiler_next_instr(basicblock *b) #define SET_LOC(c, x) \ (c)->u->u_lineno = (x)->lineno; \ - (c)->u->u_col_offset = (x)->col_offset; + (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; /* Return the stack effect of opcode with argument oparg. @@ -866,8 +952,6 @@ compiler_next_instr(basicblock *b) * 1 -- when jump * -1 -- maximal */ -/* XXX Make the stack effect of WITH_CLEANUP_START and - WITH_CLEANUP_FINISH deterministic. */ static int stack_effect(int opcode, int oparg, int jump) { @@ -1111,11 +1195,25 @@ stack_effect(int opcode, int oparg, int jump) return 1; case LIST_TO_TUPLE: return 0; + case GEN_START: + return -1; case LIST_EXTEND: case SET_UPDATE: case DICT_MERGE: case DICT_UPDATE: return -1; + case COPY_DICT_WITHOUT_KEYS: + return 0; + case MATCH_CLASS: + return -1; + case GET_LEN: + case MATCH_MAPPING: + case MATCH_SEQUENCE: + return 1; + case MATCH_KEYS: + return 2; + case ROT_N: + return 0; default: return PY_INVALID_STACK_EFFECT; } @@ -1139,15 +1237,12 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) */ static int -compiler_addop(struct compiler *c, int opcode) +compiler_addop_line(struct compiler *c, int opcode, int line) { basicblock *b; struct instr *i; int off; assert(!HAS_ARG(opcode)); - if (c->c_do_not_emit_bytecode) { - return 1; - } off = compiler_next_instr(c->u->u_curblock); if (off < 0) return 0; @@ -1157,10 +1252,23 @@ compiler_addop(struct compiler *c, int opcode) i->i_oparg = 0; if (opcode == RETURN_VALUE) b->b_return = 1; - i->i_lineno = c->u->u_lineno; + i->i_lineno = line; return 1; } +static int +compiler_addop(struct compiler *c, int opcode) +{ + return compiler_addop_line(c, opcode, c->u->u_lineno); +} + +static int +compiler_addop_noline(struct compiler *c, int opcode) +{ + return compiler_addop_line(c, opcode, -1); +} + + static Py_ssize_t compiler_add_o(PyObject *dict, PyObject *o) { @@ -1301,10 +1409,6 @@ merge_consts_recursive(struct compiler *c, PyObject *o) static Py_ssize_t compiler_add_const(struct compiler *c, PyObject *o) { - if (c->c_do_not_emit_bytecode) { - return 0; - } - PyObject *key = merge_consts_recursive(c, o); if (key == NULL) { return -1; @@ -1318,10 +1422,6 @@ compiler_add_const(struct compiler *c, PyObject *o) static int compiler_addop_load_const(struct compiler *c, PyObject *o) { - if (c->c_do_not_emit_bytecode) { - return 1; - } - Py_ssize_t arg = compiler_add_const(c, o); if (arg < 0) return 0; @@ -1332,10 +1432,6 @@ static int compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { - if (c->c_do_not_emit_bytecode) { - return 1; - } - Py_ssize_t arg = compiler_add_o(dict, o); if (arg < 0) return 0; @@ -1348,10 +1444,6 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, { Py_ssize_t arg; - if (c->c_do_not_emit_bytecode) { - return 1; - } - PyObject *mangled = _Py_Mangle(c->u->u_private, o); if (!mangled) return 0; @@ -1367,15 +1459,11 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, */ static int -compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) +compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, int lineno) { struct instr *i; int off; - if (c->c_do_not_emit_bytecode) { - return 1; - } - /* oparg value is unsigned, but a signed C int is usually used to store it in the C code (like Python/ceval.c). @@ -1392,36 +1480,51 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) i = &c->u->u_curblock->b_instr[off]; i->i_opcode = opcode; i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); - i->i_lineno = c->u->u_lineno; + i->i_lineno = lineno; return 1; } static int -compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) +compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) { - struct instr *i; - int off; + return compiler_addop_i_line(c, opcode, oparg, c->u->u_lineno); +} - if (c->c_do_not_emit_bytecode) { - return 1; - } +static int +compiler_addop_i_noline(struct compiler *c, int opcode, Py_ssize_t oparg) +{ + return compiler_addop_i_line(c, opcode, oparg, -1); +} +static int add_jump_to_block(basicblock *b, int opcode, int lineno, basicblock *target) +{ assert(HAS_ARG(opcode)); assert(b != NULL); - off = compiler_next_instr(c->u->u_curblock); - if (off < 0) + assert(target != NULL); + + int off = compiler_next_instr(b); + struct instr *i = &b->b_instr[off]; + if (off < 0) { return 0; - i = &c->u->u_curblock->b_instr[off]; + } i->i_opcode = opcode; - i->i_target = b; - if (absolute) - i->i_jabs = 1; - else - i->i_jrel = 1; - i->i_lineno = c->u->u_lineno; + i->i_target = target; + i->i_lineno = lineno; return 1; } +static int +compiler_addop_j(struct compiler *c, int opcode, basicblock *b) +{ + return add_jump_to_block(c->u->u_curblock, opcode, c->u->u_lineno, b); +} + +static int +compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) +{ + return add_jump_to_block(c->u->u_curblock, opcode, -1, b); +} + /* NEXT_BLOCK() creates an implicit jump from the current block to the new block. @@ -1438,6 +1541,11 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) return 0; \ } +#define ADDOP_NOLINE(C, OP) { \ + if (!compiler_addop_noline((C), (OP))) \ + return 0; \ +} + #define ADDOP_IN_SCOPE(C, OP) { \ if (!compiler_addop((C), (OP))) { \ compiler_exit_scope(c); \ @@ -1464,12 +1572,14 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) } #define ADDOP_O(C, OP, O, TYPE) { \ + assert((OP) != LOAD_CONST); /* use ADDOP_LOAD_CONST */ \ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ return 0; \ } /* Same as ADDOP_O, but steals a reference. */ #define ADDOP_N(C, OP, O, TYPE) { \ + assert((OP) != LOAD_CONST); /* use ADDOP_LOAD_CONST_NEW */ \ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \ Py_DECREF((O)); \ return 0; \ @@ -1487,16 +1597,23 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) return 0; \ } -#define ADDOP_JABS(C, OP, O) { \ - if (!compiler_addop_j((C), (OP), (O), 1)) \ +#define ADDOP_I_NOLINE(C, OP, O) { \ + if (!compiler_addop_i_noline((C), (OP), (O))) \ return 0; \ } -#define ADDOP_JREL(C, OP, O) { \ - if (!compiler_addop_j((C), (OP), (O), 0)) \ +#define ADDOP_JUMP(C, OP, O) { \ + if (!compiler_addop_j((C), (OP), (O))) \ return 0; \ } +/* 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_COMPARE(C, CMP) { \ if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \ @@ -1526,7 +1643,7 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) #define VISIT_SEQ(C, TYPE, SEQ) { \ int _i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + 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)) \ @@ -1536,7 +1653,7 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ int _i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + 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)) { \ @@ -1546,21 +1663,15 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) } \ } -/* These macros allows to check only for errors and not emmit bytecode - * while visiting nodes. -*/ - -#define BEGIN_DO_NOT_EMIT_BYTECODE { \ - c->c_do_not_emit_bytecode++; - -#define END_DO_NOT_EMIT_BYTECODE \ - c->c_do_not_emit_bytecode--; \ -} +#define RETURN_IF_FALSE(X) \ + if (!(X)) { \ + return 0; \ + } /* Search if variable annotations are present statically in a block. */ static int -find_ann(asdl_seq *stmts) +find_ann(asdl_stmt_seq *stmts) { int i, j, res = 0; stmt_ty st; @@ -1646,7 +1757,7 @@ compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) static int compiler_call_exit_with_nones(struct compiler *c) { - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, DUP_TOP); ADDOP(c, DUP_TOP); ADDOP_I(c, CALL_FUNCTION, 3); @@ -1665,6 +1776,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, switch (info->fb_type) { case WHILE_LOOP: case EXCEPTION_HANDLER: + case ASYNC_COMPREHENSION_GENERATOR: return 1; case FOR_LOOP: @@ -1680,19 +1792,22 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, return 1; case FINALLY_TRY: + /* This POP_BLOCK gets the line number of the unwinding statement */ ADDOP(c, POP_BLOCK); if (preserve_tos) { if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) { return 0; } } - /* Emit the finally block, restoring the line number when done */ - int saved_lineno = c->u->u_lineno; + /* Emit the finally block */ VISIT_SEQ(c, stmt, info->fb_datum); - c->u->u_lineno = saved_lineno; if (preserve_tos) { compiler_pop_fblock(c, POP_VALUE, NULL); } + /* The finally block should appear to execute after the + * statement causing the unwinding, so make the unwinding + * instruction artificial */ + c->u->u_lineno = -1; return 1; case FINALLY_END: @@ -1710,6 +1825,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, case WITH: case ASYNC_WITH: + SET_LOC(c, (stmt_ty)info->fb_datum); ADDOP(c, POP_BLOCK); if (preserve_tos) { ADDOP(c, ROT_TWO); @@ -1723,6 +1839,10 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, ADDOP(c, YIELD_FROM); } ADDOP(c, POP_TOP); + /* The exit block should appear to execute after the + * statement causing the unwinding, so make the unwinding + * instruction artificial */ + c->u->u_lineno = -1; return 1; case HANDLER_CLEANUP: @@ -1778,7 +1898,7 @@ compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblock and for annotations. */ static int -compiler_body(struct compiler *c, asdl_seq *stmts) +compiler_body(struct compiler *c, asdl_stmt_seq *stmts) { int i = 0; stmt_ty st; @@ -1827,7 +1947,7 @@ compiler_mod(struct compiler *c, mod_ty mod) return NULL; } /* Use 0 for firstlineno initially, will fixup in assemble(). */ - if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 0)) + if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 1)) return NULL; switch (mod->kind) { case Module_kind: @@ -1841,8 +1961,7 @@ compiler_mod(struct compiler *c, mod_ty mod) ADDOP(c, SETUP_ANNOTATIONS); } c->c_interactive = 1; - VISIT_SEQ_IN_SCOPE(c, stmt, - mod->v.Interactive.body); + VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); break; case Expression_kind: VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); @@ -1871,19 +1990,17 @@ get_ref_type(struct compiler *c, PyObject *name) if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && _PyUnicode_EqualToASCIIString(name, "__class__")) return CELL; - scope = PyST_GetScope(c->u->u_ste, name); + scope = _PyST_GetScope(c->u->u_ste, name); if (scope == 0) { - _Py_FatalErrorFormat(__func__, - "unknown scope for %.100s in %.100s(%s)\n" - "symbols: %s\nlocals: %s\nglobals: %s", - PyUnicode_AsUTF8(name), - PyUnicode_AsUTF8(c->u->u_name), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names))); + PyErr_Format(PyExc_SystemError, + "_PyST_GetScope(name=%R) failed: " + "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; } - return scope; } @@ -1891,14 +2008,15 @@ static int compiler_lookup_arg(PyObject *dict, PyObject *name) { PyObject *v; - v = PyDict_GetItem(dict, name); + v = PyDict_GetItemWithError(dict, name); if (v == NULL) return -1; 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, PyCodeObject *co, Py_ssize_t flags, + PyObject *qualname) { Py_ssize_t i, free = PyCode_GetNumFree(co); if (qualname == NULL) @@ -1910,7 +2028,6 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py LOAD_DEREF but LOAD_CLOSURE is needed. */ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); - int arg, reftype; /* Special case: If a class contains a method with a free variable that has the same name as a method, @@ -1918,20 +2035,27 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py class. It should be handled by the closure, as well as by the normal name lookup logic. */ - reftype = get_ref_type(c, name); - if (reftype == CELL) + int reftype = get_ref_type(c, name); + if (reftype == -1) { + return 0; + } + int arg; + if (reftype == CELL) { arg = compiler_lookup_arg(c->u->u_cellvars, name); - else /* (reftype == FREE) */ + } + else { arg = compiler_lookup_arg(c->u->u_freevars, name); + } if (arg == -1) { - _Py_FatalErrorFormat(__func__, - "lookup %s in %s %d %d\n" - "freevars of %s: %s\n", - PyUnicode_AsUTF8(PyObject_Repr(name)), - PyUnicode_AsUTF8(c->u->u_name), - reftype, arg, - PyUnicode_AsUTF8(co->co_name), - PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars))); + PyErr_Format(PyExc_SystemError, + "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; " + "freevars of code %S: %R", + name, + reftype, + c->u->u_name, + co->co_name, + co->co_freevars); + return 0; } ADDOP_I(c, LOAD_CLOSURE, arg); } @@ -1945,7 +2069,7 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py } static int -compiler_decorators(struct compiler *c, asdl_seq* decos) +compiler_decorators(struct compiler *c, asdl_expr_seq* decos) { int i; @@ -1959,8 +2083,8 @@ compiler_decorators(struct compiler *c, asdl_seq* decos) } static int -compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs, - asdl_seq *kw_defaults) +compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, + asdl_expr_seq *kw_defaults) { /* Push a dict of keyword-only default values. @@ -2024,31 +2148,32 @@ compiler_visit_annexpr(struct compiler *c, expr_ty annotation) static int compiler_visit_argannotation(struct compiler *c, identifier id, - expr_ty annotation, PyObject *names) + expr_ty annotation, Py_ssize_t *annotations_len) { - if (annotation) { - PyObject *mangled; - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - VISIT(c, annexpr, annotation) - } - else { - VISIT(c, expr, annotation); - } - mangled = _Py_Mangle(c->u->u_private, id); - if (!mangled) - return 0; - if (PyList_Append(names, mangled) < 0) { - Py_DECREF(mangled); - return 0; - } - Py_DECREF(mangled); + if (!annotation) { + return 1; + } + + PyObject *mangled = _Py_Mangle(c->u->u_private, id); + if (!mangled) { + return 0; + } + ADDOP_LOAD_CONST(c, mangled); + Py_DECREF(mangled); + + if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { + VISIT(c, annexpr, annotation) } + else { + VISIT(c, expr, annotation); + } + *annotations_len += 2; return 1; } static int -compiler_visit_argannotations(struct compiler *c, asdl_seq* args, - PyObject *names) +compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args, + Py_ssize_t *annotations_len) { int i; for (i = 0; i < asdl_seq_LEN(args); i++) { @@ -2057,7 +2182,7 @@ compiler_visit_argannotations(struct compiler *c, asdl_seq* args, c, arg->arg, arg->annotation, - names)) + annotations_len)) return 0; } return 1; @@ -2067,58 +2192,44 @@ static int compiler_visit_annotations(struct compiler *c, arguments_ty args, expr_ty returns) { - /* Push arg annotation dict. + /* Push arg annotation names and values. The expressions are evaluated out-of-order wrt the source code. - Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed. + Return 0 on error, -1 if no annotations pushed, 1 if a annotations is pushed. */ static identifier return_str; - PyObject *names; - Py_ssize_t len; - names = PyList_New(0); - if (!names) - return 0; + Py_ssize_t annotations_len = 0; - if (!compiler_visit_argannotations(c, args->args, names)) - goto error; - if (!compiler_visit_argannotations(c, args->posonlyargs, names)) - goto error; + 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, names)) - goto error; - if (!compiler_visit_argannotations(c, args->kwonlyargs, names)) - goto error; + 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, names)) - goto error; + args->kwarg->annotation, &annotations_len)) + return 0; if (!return_str) { return_str = PyUnicode_InternFromString("return"); if (!return_str) - goto error; + return 0; } - if (!compiler_visit_argannotation(c, return_str, returns, names)) { - goto error; + if (!compiler_visit_argannotation(c, return_str, returns, &annotations_len)) { + return 0; } - len = PyList_GET_SIZE(names); - if (len) { - PyObject *keytuple = PyList_AsTuple(names); - Py_DECREF(names); - ADDOP_LOAD_CONST_NEW(c, keytuple); - ADDOP_I(c, BUILD_CONST_KEY_MAP, len); + if (annotations_len) { + ADDOP_I(c, BUILD_TUPLE, annotations_len); return 1; } - else { - Py_DECREF(names); - return -1; - } -error: - Py_DECREF(names); - return 0; + return -1; } static int @@ -2159,6 +2270,10 @@ forbidden_name(struct compiler *c, identifier name, expr_context_ty ctx) compiler_error(c, "cannot assign to __debug__"); return 1; } + if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) { + compiler_error(c, "cannot delete __debug__"); + return 1; + } return 0; } @@ -2173,7 +2288,7 @@ compiler_check_debug_one_arg(struct compiler *c, arg_ty arg) } static int -compiler_check_debug_args_seq(struct compiler *c, asdl_seq *args) +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++) { @@ -2208,8 +2323,8 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) arguments_ty args; expr_ty returns; identifier name; - asdl_seq* decos; - asdl_seq *body; + asdl_expr_seq* decos; + asdl_stmt_seq *body; Py_ssize_t i, funcflags; int annotations; int scope_type; @@ -2277,7 +2392,9 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) 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); - VISIT_SEQ_IN_SCOPE(c, stmt, body); + for (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); @@ -2288,7 +2405,11 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) return 0; } - compiler_make_closure(c, co, funcflags, qualname); + if (!compiler_make_closure(c, co, funcflags, qualname)) { + Py_DECREF(qualname); + Py_DECREF(co); + return 0; + } Py_DECREF(qualname); Py_DECREF(co); @@ -2306,7 +2427,7 @@ compiler_class(struct compiler *c, stmt_ty s) PyCodeObject *co; PyObject *str; int i, firstlineno; - asdl_seq* decos = s->v.ClassDef.decorator_list; + asdl_expr_seq *decos = s->v.ClassDef.decorator_list; if (!compiler_decorators(c, decos)) return 0; @@ -2366,6 +2487,8 @@ compiler_class(struct compiler *c, stmt_ty s) compiler_exit_scope(c); return 0; } + /* The following code is artificial */ + c->u->u_lineno = -1; /* 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 */ @@ -2410,16 +2533,17 @@ compiler_class(struct compiler *c, stmt_ty s) ADDOP(c, LOAD_BUILD_CLASS); /* 3. load a function (or closure) made from the code object */ - compiler_make_closure(c, co, 0, NULL); + if (!compiler_make_closure(c, co, 0, NULL)) { + Py_DECREF(co); + return 0; + } Py_DECREF(co); /* 4. load class name */ ADDOP_LOAD_CONST(c, 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)) + if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords)) return 0; /* 6. apply decorators */ @@ -2527,7 +2651,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) /* fallback to general implementation */ break; case BoolOp_kind: { - asdl_seq *s = e->v.BoolOp.values; + asdl_expr_seq *s = e->v.BoolOp.values; Py_ssize_t i, n = asdl_seq_LEN(s) - 1; assert(n >= 0); int cond2 = e->v.BoolOp.op == Or; @@ -2559,7 +2683,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) return 0; if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) return 0; - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); compiler_use_next_block(c, next2); if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) return 0; @@ -2582,20 +2706,21 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) ADDOP(c, DUP_TOP); ADDOP(c, ROT_THREE); ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JABS(c, POP_JUMP_IF_FALSE, cleanup); + ADDOP_JUMP(c, POP_JUMP_IF_FALSE, cleanup); NEXT_BLOCK(c); } 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_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + NEXT_BLOCK(c); basicblock *end = compiler_new_block(c); if (end == NULL) return 0; - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); compiler_use_next_block(c, cleanup); ADDOP(c, POP_TOP); if (!cond) { - ADDOP_JREL(c, JUMP_FORWARD, next); + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, next); } compiler_use_next_block(c, end); return 1; @@ -2610,7 +2735,8 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) /* general implementation */ VISIT(c, expr, e); - ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + NEXT_BLOCK(c); return 1; } @@ -2629,7 +2755,7 @@ compiler_ifexp(struct compiler *c, expr_ty e) if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) return 0; VISIT(c, expr, e->v.IfExp.body); - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); compiler_use_next_block(c, next); VISIT(c, expr, e->v.IfExp.orelse); compiler_use_next_block(c, end); @@ -2683,10 +2809,16 @@ compiler_lambda(struct compiler *c, expr_ty e) qualname = c->u->u_qualname; Py_INCREF(qualname); compiler_exit_scope(c); - if (co == NULL) + if (co == NULL) { + Py_DECREF(qualname); return 0; + } - compiler_make_closure(c, co, funcflags, qualname); + if (!compiler_make_closure(c, co, funcflags, qualname)) { + Py_DECREF(qualname); + Py_DECREF(co); + return 0; + } Py_DECREF(qualname); Py_DECREF(co); @@ -2697,48 +2829,28 @@ static int compiler_if(struct compiler *c, stmt_ty s) { basicblock *end, *next; - int constant; assert(s->kind == If_kind); end = compiler_new_block(c); - if (end == NULL) + if (end == NULL) { return 0; - - constant = expr_constant(s->v.If.test); - /* constant = 0: "if 0" - * constant = 1: "if 1", "if 2", ... - * constant = -1: rest */ - if (constant == 0) { - BEGIN_DO_NOT_EMIT_BYTECODE - VISIT_SEQ(c, stmt, s->v.If.body); - END_DO_NOT_EMIT_BYTECODE - if (s->v.If.orelse) { - VISIT_SEQ(c, stmt, s->v.If.orelse); - } - } else if (constant == 1) { - VISIT_SEQ(c, stmt, s->v.If.body); - if (s->v.If.orelse) { - BEGIN_DO_NOT_EMIT_BYTECODE - VISIT_SEQ(c, stmt, s->v.If.orelse); - END_DO_NOT_EMIT_BYTECODE - } - } else { - if (asdl_seq_LEN(s->v.If.orelse)) { - next = compiler_new_block(c); - if (next == NULL) - return 0; - } - else { - next = end; - } - if (!compiler_jump_if(c, s->v.If.test, next, 0)) { + } + if (asdl_seq_LEN(s->v.If.orelse)) { + next = compiler_new_block(c); + if (next == NULL) { return 0; } - VISIT_SEQ(c, stmt, s->v.If.body); - if (asdl_seq_LEN(s->v.If.orelse)) { - ADDOP_JREL(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next); - VISIT_SEQ(c, stmt, s->v.If.orelse); - } + } + else { + next = end; + } + if (!compiler_jump_if(c, s->v.If.test, next, 0)) { + return 0; + } + VISIT_SEQ(c, stmt, s->v.If.body); + if (asdl_seq_LEN(s->v.If.orelse)) { + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); + compiler_use_next_block(c, next); + VISIT_SEQ(c, stmt, s->v.If.orelse); } compiler_use_next_block(c, end); return 1; @@ -2747,12 +2859,13 @@ compiler_if(struct compiler *c, stmt_ty s) static int compiler_for(struct compiler *c, stmt_ty s) { - basicblock *start, *cleanup, *end; + basicblock *start, *body, *cleanup, *end; start = compiler_new_block(c); + body = compiler_new_block(c); cleanup = compiler_new_block(c); end = compiler_new_block(c); - if (start == NULL || end == NULL || cleanup == NULL) { + if (start == NULL || body == NULL || end == NULL || cleanup == NULL) { return 0; } if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { @@ -2761,10 +2874,13 @@ compiler_for(struct compiler *c, stmt_ty s) VISIT(c, expr, s->v.For.iter); ADDOP(c, GET_ITER); compiler_use_next_block(c, start); - ADDOP_JREL(c, FOR_ITER, cleanup); + ADDOP_JUMP(c, FOR_ITER, cleanup); + compiler_use_next_block(c, body); VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + /* Mark jump as artificial */ + c->u->u_lineno = -1; + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_use_next_block(c, cleanup); compiler_pop_fblock(c, FOR_LOOP, start); @@ -2800,7 +2916,7 @@ compiler_async_for(struct compiler *c, stmt_ty s) return 0; } /* SETUP_FINALLY to guard the __anext__ call */ - ADDOP_JREL(c, SETUP_FINALLY, except); + ADDOP_JUMP(c, SETUP_FINALLY, except); ADDOP(c, GET_ANEXT); ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); @@ -2809,18 +2925,16 @@ compiler_async_for(struct compiler *c, stmt_ty s) /* Success block for __anext__ */ VISIT(c, expr, s->v.AsyncFor.target); VISIT_SEQ(c, stmt, s->v.AsyncFor.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_pop_fblock(c, FOR_LOOP, start); /* Except block for __anext__ */ compiler_use_next_block(c, except); - /* We don't want to trace the END_ASYNC_FOR, so make sure - * that it has the same lineno as the following instruction. */ - if (asdl_seq_LEN(s->v.For.orelse)) { - SET_LOC(c, (stmt_ty)asdl_seq_GET(s->v.For.orelse, 0)); - } + /* 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); /* `else` block */ @@ -2834,63 +2948,35 @@ compiler_async_for(struct compiler *c, stmt_ty s) static int compiler_while(struct compiler *c, stmt_ty s) { - basicblock *loop, *orelse, *end, *anchor = NULL; - int constant = expr_constant(s->v.While.test); - - if (constant == 0) { - BEGIN_DO_NOT_EMIT_BYTECODE - // Push a dummy block so the VISIT_SEQ knows that we are - // inside a while loop so it can correctly evaluate syntax - // errors. - if (!compiler_push_fblock(c, WHILE_LOOP, NULL, NULL, NULL)) { - return 0; - } - VISIT_SEQ(c, stmt, s->v.While.body); - // Remove the dummy block now that is not needed. - compiler_pop_fblock(c, WHILE_LOOP, NULL); - END_DO_NOT_EMIT_BYTECODE - if (s->v.While.orelse) { - VISIT_SEQ(c, stmt, s->v.While.orelse); - } - return 1; - } + 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 (constant == -1) { - anchor = compiler_new_block(c); - if (anchor == NULL) - return 0; - } - if (loop == NULL || end == NULL) + if (loop == NULL || body == NULL || anchor == NULL || end == NULL) { return 0; - if (s->v.While.orelse) { - orelse = compiler_new_block(c); - if (orelse == NULL) - return 0; } - else - orelse = NULL; - compiler_use_next_block(c, loop); - if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) + 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; - if (constant == -1) { - if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) - return 0; } - VISIT_SEQ(c, stmt, s->v.While.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, loop); - /* XXX should the two POP instructions be in a separate block - if there is no else clause ? - */ + compiler_use_next_block(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; + } - if (constant == -1) - compiler_use_next_block(c, anchor); compiler_pop_fblock(c, WHILE_LOOP, loop); - if (orelse != NULL) /* what if orelse is just pass? */ + compiler_use_next_block(c, anchor); + if (s->v.While.orelse) { VISIT_SEQ(c, stmt, s->v.While.orelse); + } compiler_use_next_block(c, end); return 1; @@ -2911,16 +2997,28 @@ compiler_return(struct compiler *c, stmt_ty s) } 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); + } } + if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) { + SET_LOC(c, s); + ADDOP(c, NOP); + } + if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL)) return 0; if (s->v.Return.value == NULL) { ADDOP_LOAD_CONST(c, Py_None); } else if (!preserve_tos) { - VISIT(c, expr, s->v.Return.value); + ADDOP_LOAD_CONST(c, s->v.Return.value->v.Constant.value); } ADDOP(c, RETURN_VALUE); + NEXT_BLOCK(c); return 1; } @@ -2929,6 +3027,8 @@ static int compiler_break(struct compiler *c) { struct fblockinfo *loop = NULL; + /* Emit instruction with line number */ + ADDOP(c, NOP); if (!compiler_unwind_fblock_stack(c, 0, &loop)) { return 0; } @@ -2938,7 +3038,8 @@ compiler_break(struct compiler *c) if (!compiler_unwind_fblock(c, loop, 0)) { return 0; } - ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_exit); + ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_exit); + NEXT_BLOCK(c); return 1; } @@ -2946,13 +3047,16 @@ static int compiler_continue(struct compiler *c) { struct fblockinfo *loop = NULL; + /* Emit instruction with line number */ + ADDOP(c, NOP); if (!compiler_unwind_fblock_stack(c, 0, &loop)) { return 0; } if (loop == NULL) { return compiler_error(c, "'continue' not properly in loop"); } - ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_block); + ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_block); + NEXT_BLOCK(c) return 1; } @@ -2998,7 +3102,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) return 0; /* `try` block */ - ADDOP_JREL(c, SETUP_FINALLY, end); + 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; @@ -3009,17 +3113,17 @@ compiler_try_finally(struct compiler *c, stmt_ty s) else { VISIT_SEQ(c, stmt, s->v.Try.body); } - ADDOP(c, POP_BLOCK); + ADDOP_NOLINE(c, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP_JREL(c, JUMP_FORWARD, exit); + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, exit); /* `finally` block */ compiler_use_next_block(c, end); if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); - ADDOP(c, RERAISE); + ADDOP_I(c, RERAISE, 0); compiler_use_next_block(c, exit); return 1; } @@ -3066,14 +3170,14 @@ compiler_try_except(struct compiler *c, stmt_ty s) end = compiler_new_block(c); if (body == NULL || except == NULL || orelse == NULL || end == NULL) return 0; - ADDOP_JREL(c, SETUP_FINALLY, except); + ADDOP_JUMP(c, SETUP_FINALLY, except); compiler_use_next_block(c, body); if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); - ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, TRY_EXCEPT, body); - ADDOP_JREL(c, JUMP_FORWARD, orelse); + ADDOP_NOLINE(c, POP_BLOCK); + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, orelse); n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); /* Runtime will push a block here, so we need to account for that */ @@ -3082,16 +3186,17 @@ compiler_try_except(struct compiler *c, stmt_ty s) for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.Try.handlers, i); + SET_LOC(c, handler); if (!handler->v.ExceptHandler.type && i < n-1) return compiler_error(c, "default 'except:' must be last"); - SET_LOC(c, handler); except = compiler_new_block(c); if (except == NULL) return 0; if (handler->v.ExceptHandler.type) { ADDOP(c, DUP_TOP); VISIT(c, expr, handler->v.ExceptHandler.type); - ADDOP_JABS(c, JUMP_IF_NOT_EXC_MATCH, except); + ADDOP_JUMP(c, JUMP_IF_NOT_EXC_MATCH, except); + NEXT_BLOCK(c); } ADDOP(c, POP_TOP); if (handler->v.ExceptHandler.name) { @@ -3118,7 +3223,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) */ /* second try: */ - ADDOP_JREL(c, SETUP_FINALLY, cleanup_end); + ADDOP_JUMP(c, SETUP_FINALLY, 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; @@ -3126,23 +3231,25 @@ compiler_try_except(struct compiler *c, stmt_ty s) /* 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 */ + c->u->u_lineno = -1; ADDOP(c, POP_BLOCK); ADDOP(c, POP_EXCEPT); - /* name = None; del name */ ADDOP_LOAD_CONST(c, Py_None); compiler_nameop(c, handler->v.ExceptHandler.name, Store); compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); /* except: */ compiler_use_next_block(c, cleanup_end); - /* name = None; del name */ + /* name = None; del name; # Mark as artificial */ + c->u->u_lineno = -1; ADDOP_LOAD_CONST(c, Py_None); compiler_nameop(c, handler->v.ExceptHandler.name, Store); compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP(c, RERAISE); + ADDOP_I(c, RERAISE, 1); } else { basicblock *cleanup_body; @@ -3158,13 +3265,16 @@ compiler_try_except(struct compiler *c, stmt_ty s) return 0; VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); + c->u->u_lineno = -1; ADDOP(c, POP_EXCEPT); - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); } compiler_use_next_block(c, except); } compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); - ADDOP(c, RERAISE); + /* Mark as artificial */ + c->u->u_lineno = -1; + ADDOP_I(c, RERAISE, 0); compiler_use_next_block(c, orelse); VISIT_SEQ(c, stmt, s->v.Try.orelse); compiler_use_next_block(c, end); @@ -3232,11 +3342,12 @@ compiler_import(struct compiler *c, stmt_ty s) */ Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names); + PyObject *zero = _PyLong_GetZero(); // borrowed reference for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); int r; - ADDOP_LOAD_CONST(c, _PyLong_Zero); + ADDOP_LOAD_CONST(c, zero); ADDOP_LOAD_CONST(c, Py_None); ADDOP_NAME(c, IMPORT_NAME, alias->name, names); @@ -3334,10 +3445,12 @@ compiler_assert(struct compiler *c, stmt_ty s) { basicblock *end; - if (c->c_optimize) - return 1; - if (s->v.Assert.test->kind == Tuple_kind && - asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) + /* 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) || + (s->v.Assert.test->kind == Constant_kind && + 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?")) @@ -3345,6 +3458,8 @@ compiler_assert(struct compiler *c, stmt_ty s) return 0; } } + if (c->c_optimize) + return 1; end = compiler_new_block(c); if (end == NULL) return 0; @@ -3371,10 +3486,13 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value) if (value->kind == Constant_kind) { /* ignore constant statement */ + ADDOP(c, NOP); return 1; } VISIT(c, expr, value); + /* Mark POP_TOP as artificial */ + c->u->u_lineno = -1; ADDOP(c, POP_TOP); return 1; } @@ -3417,6 +3535,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) return compiler_while(c, s); case If_kind: return compiler_if(c, s); + case Match_kind: + return compiler_match(c, s); case Raise_kind: n = 0; if (s->v.Raise.exc) { @@ -3428,6 +3548,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) } } ADDOP_I(c, RAISE_VARARGS, (int)n); + NEXT_BLOCK(c); break; case Try_kind: return compiler_try(c, s); @@ -3443,6 +3564,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case Expr_kind: return compiler_visit_stmt_expr(c, s->v.Expr.value); case Pass_kind: + ADDOP(c, NOP); break; case Break_kind: return compiler_break(c); @@ -3577,7 +3699,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) op = 0; optype = OP_NAME; - scope = PyST_GetScope(c->u->u_ste, mangled); + scope = _PyST_GetScope(c->u->u_ste, mangled); switch (scope) { case FREE: dict = c->u->u_freevars; @@ -3654,7 +3776,7 @@ compiler_boolop(struct compiler *c, expr_ty e) basicblock *end; int jumpi; Py_ssize_t i, n; - asdl_seq *s; + asdl_expr_seq *s; assert(e->kind == BoolOp_kind); if (e->v.BoolOp.op == And) @@ -3669,7 +3791,12 @@ compiler_boolop(struct compiler *c, expr_ty e) assert(n >= 0); for (i = 0; i < n; ++i) { VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); - ADDOP_JABS(c, jumpi, end); + ADDOP_JUMP(c, jumpi, end); + basicblock *next = compiler_new_block(c); + if (next == NULL) { + return 0; + } + compiler_use_next_block(c, next); } VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); compiler_use_next_block(c, end); @@ -3677,18 +3804,17 @@ compiler_boolop(struct compiler *c, expr_ty e) } static int -starunpack_helper(struct compiler *c, asdl_seq *elts, int pushed, +starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, int build, int add, int extend, int tuple) { Py_ssize_t n = asdl_seq_LEN(elts); - Py_ssize_t i, seen_star = 0; if (n > 2 && are_all_items_const(elts, 0, n)) { PyObject *folded = PyTuple_New(n); if (folded == NULL) { return 0; } PyObject *val; - for (i = 0; i < n; i++) { + 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); @@ -3709,38 +3835,16 @@ starunpack_helper(struct compiler *c, asdl_seq *elts, int pushed, return 1; } - for (i = 0; i < n; i++) { + int big = n+pushed > STACK_USE_GUIDELINE; + int seen_star = 0; + for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind) { seen_star = 1; } } - if (seen_star) { - seen_star = 0; - for (i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(elts, i); - if (elt->kind == Starred_kind) { - if (seen_star == 0) { - ADDOP_I(c, build, i+pushed); - seen_star = 1; - } - VISIT(c, expr, elt->v.Starred.value); - ADDOP_I(c, extend, 1); - } - else { - VISIT(c, expr, elt); - if (seen_star) { - ADDOP_I(c, add, 1); - } - } - } - assert(seen_star); - if (tuple) { - ADDOP(c, LIST_TO_TUPLE); - } - } - else { - for (i = 0; i < n; i++) { + if (!seen_star && !big) { + for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); VISIT(c, expr, elt); } @@ -3749,17 +3853,43 @@ starunpack_helper(struct compiler *c, asdl_seq *elts, int pushed, } else { ADDOP_I(c, build, n+pushed); } + return 1; + } + int sequence_built = 0; + if (big) { + ADDOP_I(c, 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); + sequence_built = 1; + } + VISIT(c, expr, elt->v.Starred.value); + ADDOP_I(c, extend, 1); + } + else { + VISIT(c, expr, elt); + if (sequence_built) { + ADDOP_I(c, add, 1); + } + } + } + assert(sequence_built); + if (tuple) { + ADDOP(c, LIST_TO_TUPLE); } return 1; } static int -assignment_helper(struct compiler *c, asdl_seq *elts) +unpack_helper(struct compiler *c, asdl_expr_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); - Py_ssize_t i; int seen_star = 0; - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind && !seen_star) { if ((i >= (1 << 8)) || @@ -3778,7 +3908,15 @@ assignment_helper(struct compiler *c, asdl_seq *elts) if (!seen_star) { ADDOP_I(c, UNPACK_SEQUENCE, n); } - for (i = 0; i < n; i++) { + return 1; +} + +static int +assignment_helper(struct compiler *c, asdl_expr_seq *elts) +{ + Py_ssize_t n = asdl_seq_LEN(elts); + RETURN_IF_FALSE(unpack_helper(c, 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); } @@ -3788,7 +3926,7 @@ assignment_helper(struct compiler *c, asdl_seq *elts) static int compiler_list(struct compiler *c, expr_ty e) { - asdl_seq *elts = e->v.List.elts; + asdl_expr_seq *elts = e->v.List.elts; if (e->v.List.ctx == Store) { return assignment_helper(c, elts); } @@ -3804,7 +3942,7 @@ compiler_list(struct compiler *c, expr_ty e) static int compiler_tuple(struct compiler *c, expr_ty e) { - asdl_seq *elts = e->v.Tuple.elts; + asdl_expr_seq *elts = e->v.Tuple.elts; if (e->v.Tuple.ctx == Store) { return assignment_helper(c, elts); } @@ -3825,7 +3963,7 @@ compiler_set(struct compiler *c, expr_ty e) } static int -are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end) +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++) { @@ -3841,7 +3979,8 @@ 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; - if (n > 1 && are_all_items_const(e->v.Dict.keys, begin, end)) { + int big = n*2 > STACK_USE_GUIDELINE; + 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)); } @@ -3856,12 +3995,19 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end } ADDOP_LOAD_CONST_NEW(c, keys); ADDOP_I(c, BUILD_CONST_KEY_MAP, n); + return 1; } - else { - 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, 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); } + } + if (!big) { ADDOP_I(c, BUILD_MAP, n); } return 1; @@ -3897,7 +4043,7 @@ compiler_dict(struct compiler *c, expr_ty e) ADDOP_I(c, DICT_UPDATE, 1); } else { - if (elements == 0xFFFF) { + if (elements*2 > STACK_USE_GUIDELINE) { if (!compiler_subdict(c, e, i - elements, i + 1)) { return 0; } @@ -3952,7 +4098,7 @@ compiler_compare(struct compiler *c, expr_ty e) ADDOP(c, DUP_TOP); ADDOP(c, ROT_THREE); ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JABS(c, JUMP_IF_FALSE_OR_POP, cleanup); + ADDOP_JUMP(c, JUMP_IF_FALSE_OR_POP, cleanup); NEXT_BLOCK(c); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); @@ -3960,7 +4106,7 @@ compiler_compare(struct compiler *c, expr_ty e) basicblock *end = compiler_new_block(c); if (end == NULL) return 0; - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); compiler_use_next_block(c, cleanup); ADDOP(c, ROT_TWO); ADDOP(c, POP_TOP); @@ -4088,16 +4234,20 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) { Py_ssize_t argsl, i; expr_ty meth = e->v.Call.func; - asdl_seq *args = e->v.Call.args; + asdl_expr_seq *args = e->v.Call.args; /* Check that the call node is an attribute access, and that the call doesn't have keyword parameters. */ if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load || - asdl_seq_LEN(e->v.Call.keywords)) + asdl_seq_LEN(e->v.Call.keywords)) { return -1; - - /* Check that there are no *varargs types of arguments. */ + } + /* Check that there aren't too many arguments */ argsl = asdl_seq_LEN(args); + if (argsl >= STACK_USE_GUIDELINE) { + return -1; + } + /* 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) { @@ -4107,14 +4257,17 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) /* Alright, we can optimize the code. */ VISIT(c, expr, meth->v.Attribute.value); + int old_lineno = c->u->u_lineno; + c->u->u_lineno = meth->end_lineno; ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names); VISIT_SEQ(c, expr, e->v.Call.args); ADDOP_I(c, CALL_METHOD, asdl_seq_LEN(e->v.Call.args)); + c->u->u_lineno = old_lineno; return 1; } static int -validate_keywords(struct compiler *c, asdl_seq *keywords) +validate_keywords(struct compiler *c, asdl_keyword_seq *keywords) { Py_ssize_t nkeywords = asdl_seq_LEN(keywords); for (Py_ssize_t i = 0; i < nkeywords; i++) { @@ -4128,13 +4281,8 @@ validate_keywords(struct compiler *c, asdl_seq *keywords) 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)) { - PyObject *msg = PyUnicode_FromFormat("keyword argument repeated: %U", key->arg); - if (msg == NULL) { - return -1; - } - c->u->u_col_offset = other->col_offset; - compiler_error(c, PyUnicode_AsUTF8(msg)); - Py_DECREF(msg); + SET_LOC(c, other); + compiler_error(c, "keyword argument repeated: %U", key->arg); return -1; } } @@ -4161,9 +4309,29 @@ compiler_call(struct compiler *c, expr_ty e) static int compiler_joined_str(struct compiler *c, expr_ty e) { - 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)); + + Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values); + if (value_count > STACK_USE_GUIDELINE) { + ADDOP_LOAD_CONST_NEW(c, _PyUnicode_FromASCII("", 0)); + PyObject *join = _PyUnicode_FromASCII("join", 4); + if (join == NULL) { + return 0; + } + ADDOP_NAME(c, LOAD_METHOD, join, names); + Py_DECREF(join); + ADDOP_I(c, 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, CALL_METHOD, 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)); + } + } return 1; } @@ -4214,13 +4382,14 @@ compiler_formatted_value(struct compiler *c, expr_ty e) } static int -compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ssize_t end) +compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t begin, Py_ssize_t end) { Py_ssize_t i, n = end - begin; keyword_ty kw; PyObject *keys, *key; assert(n > 0); - if (n > 1) { + int big = n*2 > STACK_USE_GUIDELINE; + if (n > 1 && !big) { for (i = begin; i < end; i++) { kw = asdl_seq_GET(keywords, i); VISIT(c, expr, kw->value); @@ -4236,14 +4405,20 @@ compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ } ADDOP_LOAD_CONST_NEW(c, keys); ADDOP_I(c, BUILD_CONST_KEY_MAP, n); + return 1; } - else { - /* a for loop only executes once */ - for (i = begin; i < end; i++) { - kw = asdl_seq_GET(keywords, i); - ADDOP_LOAD_CONST(c, kw->arg); - VISIT(c, expr, kw->value); + if (big) { + ADDOP_I_NOLINE(c, BUILD_MAP, 0); + } + for (i = begin; i < end; i++) { + kw = asdl_seq_GET(keywords, i); + ADDOP_LOAD_CONST(c, kw->arg); + VISIT(c, expr, kw->value); + if (big) { + ADDOP_I_NOLINE(c, MAP_ADD, 1); } + } + if (!big) { ADDOP_I(c, BUILD_MAP, n); } return 1; @@ -4253,8 +4428,8 @@ compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ static int compiler_call_helper(struct compiler *c, int n, /* Args already pushed */ - asdl_seq *args, - asdl_seq *keywords) + asdl_expr_seq *args, + asdl_keyword_seq *keywords) { Py_ssize_t i, nseen, nelts, nkwelts; @@ -4265,6 +4440,9 @@ compiler_call_helper(struct compiler *c, nelts = asdl_seq_LEN(args); nkwelts = asdl_seq_LEN(keywords); + if (nelts + nkwelts*2 > STACK_USE_GUIDELINE) { + goto ex_call; + } for (i = 0; i < nelts; i++) { expr_ty elt = asdl_seq_GET(args, i); if (elt->kind == Starred_kind) { @@ -4379,7 +4557,7 @@ ex_call: static int compiler_comprehension_generator(struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type) { @@ -4396,7 +4574,7 @@ compiler_comprehension_generator(struct compiler *c, static int compiler_sync_comprehension_generator(struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type) { @@ -4428,7 +4606,7 @@ compiler_sync_comprehension_generator(struct compiler *c, /* Fast path for the temporary variable assignment idiom: for y in [f(x)] */ - asdl_seq *elts; + asdl_expr_seq *elts; switch (gen->iter->kind) { case List_kind: elts = gen->iter->v.List.elts; @@ -4454,7 +4632,7 @@ compiler_sync_comprehension_generator(struct compiler *c, if (start) { depth++; compiler_use_next_block(c, start); - ADDOP_JREL(c, FOR_ITER, anchor); + ADDOP_JUMP(c, FOR_ITER, anchor); NEXT_BLOCK(c); } VISIT(c, expr, gen->target); @@ -4506,7 +4684,7 @@ compiler_sync_comprehension_generator(struct compiler *c, } compiler_use_next_block(c, if_cleanup); if (start) { - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_use_next_block(c, anchor); } @@ -4515,7 +4693,7 @@ compiler_sync_comprehension_generator(struct compiler *c, static int compiler_async_comprehension_generator(struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type) { @@ -4544,8 +4722,13 @@ compiler_async_comprehension_generator(struct compiler *c, } compiler_use_next_block(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_JREL(c, SETUP_FINALLY, except); + ADDOP_JUMP(c, SETUP_FINALLY, except); ADDOP(c, GET_ANEXT); ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); @@ -4596,7 +4779,9 @@ compiler_async_comprehension_generator(struct compiler *c, } } compiler_use_next_block(c, if_cleanup); - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); + + compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start); compiler_use_next_block(c, except); ADDOP(c, END_ASYNC_FOR); @@ -4606,7 +4791,7 @@ compiler_async_comprehension_generator(struct compiler *c, static int compiler_comprehension(struct compiler *c, expr_ty e, int type, - identifier name, asdl_seq *generators, expr_ty elt, + identifier name, asdl_comprehension_seq *generators, expr_ty elt, expr_ty val) { PyCodeObject *co = NULL; @@ -4624,6 +4809,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, { goto error; } + SET_LOC(c, e); is_async_generator = c->u->u_ste->ste_coroutine; @@ -4672,8 +4858,9 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, if (co == NULL) goto error; - if (!compiler_make_closure(c, co, 0, qualname)) + if (!compiler_make_closure(c, co, 0, qualname)) { goto error; + } Py_DECREF(qualname); Py_DECREF(co); @@ -4777,23 +4964,15 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k) Return values: 1 for true, 0 for false, -1 for non-constant. */ -static int -expr_constant(expr_ty e) -{ - if (e->kind == Constant_kind) { - return PyObject_IsTrue(e->v.Constant.value); - } - return -1; -} - static int compiler_with_except_finish(struct compiler *c) { basicblock *exit; exit = compiler_new_block(c); if (exit == NULL) return 0; - ADDOP_JABS(c, POP_JUMP_IF_TRUE, exit); - ADDOP(c, RERAISE); + ADDOP_JUMP(c, POP_JUMP_IF_TRUE, exit); + NEXT_BLOCK(c); + ADDOP_I(c, RERAISE, 1); compiler_use_next_block(c, exit); ADDOP(c, POP_TOP); ADDOP(c, POP_TOP); @@ -4854,11 +5033,11 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); - ADDOP_JREL(c, SETUP_ASYNC_WITH, final); + ADDOP_JUMP(c, SETUP_ASYNC_WITH, final); /* SETUP_ASYNC_WITH pushes a finally block. */ compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, ASYNC_WITH, block, final, NULL)) { + if (!compiler_push_fblock(c, ASYNC_WITH, block, final, s)) { return 0; } @@ -4884,19 +5063,19 @@ compiler_async_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, GET_AWAITABLE); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); ADDOP(c, POP_TOP); - ADDOP_JABS(c, JUMP_ABSOLUTE, exit); + ADDOP_JUMP(c, JUMP_ABSOLUTE, exit); /* For exceptional outcome: */ compiler_use_next_block(c, final); - ADDOP(c, WITH_EXCEPT_START); ADDOP(c, GET_AWAITABLE); ADDOP_LOAD_CONST(c, Py_None); @@ -4946,11 +5125,11 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); /* Will push bound __exit__ */ - ADDOP_JREL(c, SETUP_WITH, final); + ADDOP_JUMP(c, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, WITH, block, final, NULL)) { + if (!compiler_push_fblock(c, WITH, block, final, s)) { return 0; } @@ -4969,6 +5148,9 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) else if (!compiler_with(c, s, pos)) return 0; + + /* Mark all following code as artificial */ + c->u->u_lineno = -1; ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, WITH, block); @@ -4977,14 +5159,14 @@ 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_JREL(c, JUMP_FORWARD, exit); + ADDOP_JUMP(c, JUMP_FORWARD, exit); /* For exceptional outcome: */ compiler_use_next_block(c, final); - ADDOP(c, WITH_EXCEPT_START); compiler_with_except_finish(c); @@ -5084,12 +5266,21 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) VISIT(c, expr, e->v.Attribute.value); switch (e->v.Attribute.ctx) { case Load: + { + int old_lineno = c->u->u_lineno; + c->u->u_lineno = e->end_lineno; ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); + c->u->u_lineno = old_lineno; break; + } case Store: - if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) + if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) { return 0; + } + int old_lineno = c->u->u_lineno; + c->u->u_lineno = e->end_lineno; ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); + c->u->u_lineno = old_lineno; break; case Del: ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names); @@ -5127,11 +5318,15 @@ 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; } @@ -5142,14 +5337,19 @@ compiler_augassign(struct compiler *c, stmt_ty s) 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); switch (e->kind) { case Attribute_kind: VISIT(c, expr, e->v.Attribute.value); ADDOP(c, DUP_TOP); + int old_lineno = c->u->u_lineno; + c->u->u_lineno = e->end_lineno; ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); + c->u->u_lineno = old_lineno; break; case Subscript_kind: VISIT(c, expr, e->v.Subscript.value); @@ -5169,7 +5369,9 @@ compiler_augassign(struct compiler *c, stmt_ty s) } 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; VISIT(c, expr, s->v.AugAssign.value); ADDOP(c, inplace_binop(s->v.AugAssign.op)); @@ -5178,6 +5380,7 @@ compiler_augassign(struct compiler *c, stmt_ty s) switch (e->kind) { case Attribute_kind: + c->u->u_lineno = e->end_lineno; ADDOP(c, ROT_TWO); ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); break; @@ -5204,6 +5407,12 @@ check_ann_expr(struct compiler *c, expr_ty e) static int 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; + } + /* Annotations are only evaluated in a module or class. */ if (c->u->u_scope_type == COMPILER_SCOPE_MODULE || c->u->u_scope_type == COMPILER_SCOPE_CLASS) { @@ -5230,7 +5439,7 @@ check_ann_subscr(struct compiler *c, expr_ty e) return 1; case Tuple_kind: { /* extended slice */ - asdl_seq *elts = e->v.Tuple.elts; + 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))) { @@ -5310,28 +5519,35 @@ compiler_annassign(struct compiler *c, stmt_ty s) */ static int -compiler_error(struct compiler *c, const char *errstr) +compiler_error(struct compiler *c, const char *format, ...) { - PyObject *loc; - PyObject *u = NULL, *v = NULL; - - loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno); - if (!loc) { + 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; + } + PyObject *loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno); + if (loc == NULL) { Py_INCREF(Py_None); loc = Py_None; } - u = Py_BuildValue("(OiiO)", c->c_filename, c->u->u_lineno, - c->u->u_col_offset + 1, loc); - if (!u) - goto exit; - v = Py_BuildValue("(zO)", errstr, u); - if (!v) + 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); + Py_DECREF(msg); + if (args == NULL) { goto exit; - PyErr_SetObject(PyExc_SyntaxError, v); + } + PyErr_SetObject(PyExc_SyntaxError, args); exit: Py_DECREF(loc); - Py_XDECREF(u); - Py_XDECREF(v); + Py_XDECREF(args); return 0; } @@ -5426,513 +5642,1287 @@ compiler_slice(struct compiler *c, expr_ty s) return 1; } -/* 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. +// PEP 634: Structural Pattern Matching - XXX must handle implicit jumps from one block to next -*/ +// To keep things simple, all compiler_pattern_* and pattern_helper_* routines +// follow the convention of consuming TOS (the subject for the given pattern) +// and calling jump_to_fail_pop on failure (no match). -struct assembler { - PyObject *a_bytecode; /* string containing bytecode */ - int a_offset; /* offset into bytecode */ - int a_nblocks; /* number of reachable blocks */ - basicblock **a_postorder; /* list of blocks in dfs postorder */ - PyObject *a_lnotab; /* string containing lnotab */ - int a_lnotab_off; /* offset into lnotab */ - int a_lineno; /* last lineno of emitted instruction */ - int a_lineno_off; /* bytecode offset of last lineno */ -}; +// When calling into these routines, it's important that pc->on_top be kept +// updated to reflect the current number of items that we are using on the top +// of the stack: they will be popped on failure, and any name captures will be +// stored *underneath* them on success. This lets us defer all names stores +// until the *entire* pattern matches. -static void -dfs(struct compiler *c, basicblock *b, struct assembler *a, int end) -{ - int i, j; +#define WILDCARD_CHECK(N) \ + ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name) - /* Get rid of recursion for normal control flow. - Since the number of blocks is limited, unused space in a_postorder - (from a_nblocks to end) can be used as a stack for still not ordered - blocks. */ - for (j = end; b && !b->b_seen; b = b->b_next) { - b->b_seen = 1; - assert(a->a_nblocks < j); - a->a_postorder[--j] = b; - } - while (j < end) { - b = a->a_postorder[j++]; - for (i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - if (instr->i_jrel || instr->i_jabs) - dfs(c, instr->i_target, a, j); - } - assert(a->a_nblocks < j); - a->a_postorder[a->a_nblocks++] = b; - } -} +#define WILDCARD_STAR_CHECK(N) \ + ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name) -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; - } -} +// Limit permitted subexpressions, even if the parser & AST validator let them through +#define MATCH_VALUE_EXPR(N) \ + ((N)->kind == Constant_kind || (N)->kind == Attribute_kind) -/* 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. - */ +// Allocate or resize pc->fail_pop to allow for n items to be popped on failure. static int -stackdepth(struct compiler *c) +ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n) { - 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++; + Py_ssize_t size = n + 1; + if (size <= pc->fail_pop_size) { + return 1; } - if (!entryblock) - return 0; - stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * nblocks); - if (!stack) { + Py_ssize_t needed = sizeof(basicblock*) * size; + basicblock **resized = PyObject_Realloc(pc->fail_pop, needed); + if (resized == NULL) { PyErr_NoMemory(); - return -1; + return 0; } - - sp = stack; - 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) { - _Py_FatalErrorFormat(__func__, - "opcode = %d", instr->i_opcode); - } - int new_depth = depth + effect; - if (new_depth > maxdepth) { - maxdepth = new_depth; - } - assert(depth >= 0); /* invalid code or bug in stackdepth() */ - if (instr->i_jrel || instr->i_jabs) { - 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; - if (instr->i_opcode == JUMP_ABSOLUTE || - instr->i_opcode == JUMP_FORWARD || - instr->i_opcode == RETURN_VALUE || - instr->i_opcode == RAISE_VARARGS || - instr->i_opcode == RERAISE) - { - /* remaining code is dead */ - next = NULL; - break; - } - } - if (next != NULL) { - stackdepth_push(&sp, next, depth); - } + pc->fail_pop = resized; + while (pc->fail_pop_size < size) { + basicblock *new_block; + RETURN_IF_FALSE(new_block = compiler_new_block(c)); + pc->fail_pop[pc->fail_pop_size++] = new_block; } - PyObject_Free(stack); - return maxdepth; + return 1; } +// Use op to jump to the correct fail_pop block. static int -assemble_init(struct assembler *a, int nblocks, int firstlineno) -{ - memset(a, 0, sizeof(struct assembler)); - a->a_lineno = firstlineno; - a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); - if (!a->a_bytecode) - return 0; - a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); - if (!a->a_lnotab) - return 0; - if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { - PyErr_NoMemory(); - return 0; - } - a->a_postorder = (basicblock **)PyObject_Malloc( - sizeof(basicblock *) * nblocks); - if (!a->a_postorder) { - PyErr_NoMemory(); - return 0; - } +jump_to_fail_pop(struct compiler *c, 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]); + NEXT_BLOCK(c); return 1; } -static void -assemble_free(struct assembler *a) +// Build all of the fail_pop blocks and reset fail_pop. +static int +emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc) { - Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_lnotab); - if (a->a_postorder) - PyObject_Free(a->a_postorder); + if (!pc->fail_pop_size) { + assert(pc->fail_pop == NULL); + NEXT_BLOCK(c); + return 1; + } + while (--pc->fail_pop_size) { + compiler_use_next_block(c, pc->fail_pop[pc->fail_pop_size]); + if (!compiler_addop(c, POP_TOP)) { + pc->fail_pop_size = 0; + PyObject_Free(pc->fail_pop); + pc->fail_pop = NULL; + return 0; + } + } + compiler_use_next_block(c, pc->fail_pop[0]); + PyObject_Free(pc->fail_pop); + pc->fail_pop = NULL; + return 1; } static int -blocksize(basicblock *b) +compiler_error_duplicate_store(struct compiler *c, identifier n) { - int i; - int size = 0; - - for (i = 0; i < b->b_iused; i++) - size += instrsize(b->b_instr[i].i_oparg); - return size; + return compiler_error(c, "multiple assignments to name %R in pattern", n); } -/* Appends a pair to the end of the line number table, a_lnotab, representing - the instruction's bytecode offset and line number. See - Objects/lnotab_notes.txt for the description of the line number table. */ - static int -assemble_lnotab(struct assembler *a, struct instr *i) +pattern_helper_store_name(struct compiler *c, identifier n, pattern_context *pc) { - int d_bytecode, d_lineno; - Py_ssize_t len; - unsigned char *lnotab; - - d_lineno = i->i_lineno - a->a_lineno; - if (d_lineno == 0) { + if (n == NULL) { + ADDOP(c, POP_TOP); return 1; } + if (forbidden_name(c, n, Store)) { + return 0; + } + // Can't assign to the same name twice: + int duplicate = PySequence_Contains(pc->stores, n); + if (duplicate < 0) { + return 0; + } + if (duplicate) { + return compiler_error_duplicate_store(c, n); + } + // Rotate this object underneath any items we need to preserve: + ADDOP_I(c, ROT_N, pc->on_top + PyList_GET_SIZE(pc->stores) + 1); + return !PyList_Append(pc->stores, n); +} - d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT); - assert(d_bytecode >= 0); - if (d_bytecode > 255) { - int j, nbytes, ncodes = d_bytecode / 255; - nbytes = a->a_lnotab_off + 2 * ncodes; - len = PyBytes_GET_SIZE(a->a_lnotab); - if (nbytes >= len) { - if ((len <= INT_MAX / 2) && (len * 2 < nbytes)) - len = nbytes; - else if (len <= INT_MAX / 2) - len *= 2; - else { - PyErr_NoMemory(); - return 0; - } - if (_PyBytes_Resize(&a->a_lnotab, len) < 0) - return 0; +static int +pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts) +{ + Py_ssize_t n = asdl_seq_LEN(elts); + int seen_star = 0; + for (Py_ssize_t i = 0; i < n; i++) { + 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, + "too many expressions in " + "star-unpacking sequence pattern"); + ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); + seen_star = 1; } - lnotab = (unsigned char *) - PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; - for (j = 0; j < ncodes; j++) { - *lnotab++ = 255; - *lnotab++ = 0; + else if (elt->kind == MatchStar_kind) { + return compiler_error(c, + "multiple starred expressions in sequence pattern"); } - d_bytecode -= ncodes * 255; - a->a_lnotab_off += ncodes * 2; } - assert(0 <= d_bytecode && d_bytecode <= 255); - - if (d_lineno < -128 || 127 < d_lineno) { - int j, nbytes, ncodes, k; - if (d_lineno < 0) { - k = -128; - /* use division on positive numbers */ - ncodes = (-d_lineno) / 128; - } - else { - k = 127; - ncodes = d_lineno / 127; - } - d_lineno -= ncodes * k; - assert(ncodes >= 1); - nbytes = a->a_lnotab_off + 2 * ncodes; - len = PyBytes_GET_SIZE(a->a_lnotab); - if (nbytes >= len) { - if ((len <= INT_MAX / 2) && len * 2 < nbytes) - len = nbytes; - else if (len <= INT_MAX / 2) - len *= 2; - else { - PyErr_NoMemory(); - return 0; - } - if (_PyBytes_Resize(&a->a_lnotab, len) < 0) - return 0; - } - lnotab = (unsigned char *) - PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; - *lnotab++ = d_bytecode; - *lnotab++ = k; - d_bytecode = 0; - for (j = 1; j < ncodes; j++) { - *lnotab++ = 0; - *lnotab++ = k; - } - a->a_lnotab_off += ncodes * 2; + if (!seen_star) { + ADDOP_I(c, UNPACK_SEQUENCE, n); } - assert(-128 <= d_lineno && d_lineno <= 127); + return 1; +} - len = PyBytes_GET_SIZE(a->a_lnotab); - if (a->a_lnotab_off + 2 >= len) { - if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0) - return 0; +static int +pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns, + Py_ssize_t star, pattern_context *pc) +{ + RETURN_IF_FALSE(pattern_unpack_helper(c, 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: + pc->on_top += size; + for (Py_ssize_t i = 0; i < size; i++) { + // 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)); } - lnotab = (unsigned char *) - PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + return 1; +} - a->a_lnotab_off += 2; - if (d_bytecode) { - *lnotab++ = d_bytecode; - *lnotab++ = d_lineno; - } - else { /* First line of a block; def stmt, etc. */ - *lnotab++ = 0; - *lnotab++ = d_lineno; +// 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) +{ + // We need to keep the subject around for extracting elements: + pc->on_top++; + Py_ssize_t size = asdl_seq_LEN(patterns); + for (Py_ssize_t i = 0; i < size; i++) { + pattern_ty pattern = asdl_seq_GET(patterns, i); + if (WILDCARD_CHECK(pattern)) { + continue; + } + if (i == star) { + assert(WILDCARD_STAR_CHECK(pattern)); + continue; + } + ADDOP(c, DUP_TOP); + if (i < star) { + ADDOP_LOAD_CONST_NEW(c, 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(c, BINARY_SUBTRACT); + } + ADDOP(c, BINARY_SUBSCR); + RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); } - a->a_lineno = i->i_lineno; - a->a_lineno_off = a->a_offset; + // Pop the subject, we're done with it: + pc->on_top--; + ADDOP(c, POP_TOP); return 1; } -/* assemble_emit() - Extend the bytecode with a new instruction. - Update lnotab if necessary. -*/ - +// Like compiler_pattern, but turn off checks for irrefutability. static int -assemble_emit(struct assembler *a, struct instr *i) +compiler_pattern_subpattern(struct compiler *c, pattern_ty p, pattern_context *pc) { - int size, arg = 0; - Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); - _Py_CODEUNIT *code; + int allow_irrefutable = pc->allow_irrefutable; + pc->allow_irrefutable = 1; + RETURN_IF_FALSE(compiler_pattern(c, p, pc)); + pc->allow_irrefutable = allow_irrefutable; + return 1; +} - arg = i->i_oparg; - size = instrsize(arg); - if (i->i_lineno && !assemble_lnotab(a, i)) - return 0; - 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; +static int +compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc) +{ + assert(p->kind == MatchAs_kind); + if (p->v.MatchAs.pattern == NULL) { + // An irrefutable match: + 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); + } + const char *e = "wildcard makes remaining patterns unreachable"; + return compiler_error(c, e); + } + return pattern_helper_store_name(c, p->v.MatchAs.name, pc); } - code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; - a->a_offset += size; - write_op_arg(code, i->i_opcode, arg, size); + // Need to make a copy for (possibly) storing later: + pc->on_top++; + ADDOP(c, DUP_TOP); + RETURN_IF_FALSE(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; } -static void -assemble_jump_offsets(struct assembler *a, struct compiler *c) +static int +compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc) { - basicblock *b; - int bsize, totsize, extended_arg_recompile; - int i; + assert(p->kind == MatchStar_kind); + RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchStar.name, pc)); + return 1; +} - /* Compute the size of each block and fixup jump args. - Replace block pointer with position in bytecode. */ - do { - totsize = 0; - for (i = a->a_nblocks - 1; i >= 0; i--) { - b = a->a_postorder[i]; - bsize = blocksize(b); - b->b_offset = totsize; - totsize += bsize; +static int +validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns) +{ + // Any errors will point to the pattern rather than the arg name as the + // parser is only supplying identifiers rather than Name or keyword nodes + 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; } - 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 = instrsize(instr->i_oparg); - /* Relative jumps are computed relative to - the instruction pointer after fetching - the jump instruction. - */ - bsize += isize; - if (instr->i_jabs || instr->i_jrel) { - instr->i_oparg = instr->i_target->b_offset; - if (instr->i_jrel) { - instr->i_oparg -= bsize; - } - instr->i_oparg *= sizeof(_Py_CODEUNIT); - if (instrsize(instr->i_oparg) != isize) { - extended_arg_recompile = 1; - } - } + 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; } } - - /* 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 instrsize() 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); -} - -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); - Py_INCREF(k); - assert((i - offset) < size); - assert((i - offset) >= 0); - PyTuple_SET_ITEM(tuple, i - offset, k); } - return tuple; + return 0; } -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) - return NULL; - while (PyDict_Next(dict, &pos, &k, &v)) { - i = PyLong_AS_LONG(v); - /* The keys of the dictionary can be tuples wrapping a contant. - * (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); +static int +compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc) +{ + assert(p->kind == MatchClass_kind); + asdl_pattern_seq *patterns = p->v.MatchClass.patterns; + asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs; + asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns; + Py_ssize_t nargs = asdl_seq_LEN(patterns); + Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs); + Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns); + if (nattrs != nkwd_patterns) { + // 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); + } + 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); + } + if (nattrs) { + RETURN_IF_FALSE(!validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); + SET_LOC(c, p); + } + VISIT(c, expr, p->v.MatchClass.cls); + PyObject *attr_names; + RETURN_IF_FALSE(attr_names = PyTuple_New(nattrs)); + 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); + // TOS is now a tuple of (nargs + nattrs) attributes. Preserve it: + pc->on_top++; + RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + for (i = 0; i < nargs + nattrs; i++) { + pattern_ty pattern; + if (i < nargs) { + // Positional: + pattern = asdl_seq_GET(patterns, i); } - Py_INCREF(k); - assert(i < size); - assert(i >= 0); - PyList_SET_ITEM(consts, i, k); + else { + // Keyword: + pattern = asdl_seq_GET(kwd_patterns, i - nargs); + } + if (WILDCARD_CHECK(pattern)) { + continue; + } + // Get the i-th attribute, and match it against the i-th pattern: + ADDOP(c, DUP_TOP); + ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i)); + ADDOP(c, BINARY_SUBSCR); + RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); } - return consts; + // Success! Pop the tuple of attributes: + pc->on_top--; + ADDOP(c, POP_TOP); + return 1; } 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; +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; + asdl_pattern_seq *patterns = p->v.MatchMapping.patterns; + Py_ssize_t size = asdl_seq_LEN(keys); + Py_ssize_t npatterns = asdl_seq_LEN(patterns); + if (size != npatterns) { + // 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); + } + // 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)); + if (!size && !star_target) { + // If the pattern is just "{}", we're done! Pop the subject: + pc->on_top--; + ADDOP(c, POP_TOP); + return 1; } + 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)); + } + if (INT_MAX < size - 1) { + return compiler_error(c, "too many sub-patterns in mapping pattern"); + } + // Collect all of the keys into a tuple for MATCH_KEYS and + // COPY_DICT_WITHOUT_KEYS. They can either be dotted names or literals: - /* (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; + // Maintaining a set of Constant_kind kind keys allows us to raise a + // SyntaxError in the case of duplicates. + PyObject *seen = PySet_New(NULL); + if (seen == NULL) { + return 0; } - return flags; -} + // NOTE: goto error on failure in the loop below to avoid leaking `seen` + for (Py_ssize_t i = 0; i < size; i++) { + expr_ty key = asdl_seq_GET(keys, i); + 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); + goto error; + } -// Merge *tuple* with constant cache. -// Unlike merge_consts_recursive(), this function doesn't work recursively. -static int -merge_const_tuple(struct compiler *c, PyObject **tuple) -{ - assert(PyTuple_CheckExact(*tuple)); + if (key->kind == Constant_kind) { + int in_seen = PySet_Contains(seen, key->v.Constant.value); + if (in_seen < 0) { + goto error; + } + if (in_seen) { + const char *e = "mapping pattern checks duplicate key (%R)"; + compiler_error(c, e, key->v.Constant.value); + goto error; + } + if (PySet_Add(seen, key->v.Constant.value)) { + goto error; + } + } - PyObject *key = _PyCode_ConstantKey(*tuple); - if (key == NULL) { - return 0; + else if (key->kind != Attribute_kind) { + const char *e = "mapping pattern keys may only match literals and attribute lookups"; + compiler_error(c, e); + goto error; + } + if (!compiler_visit_expr(c, key)) { + goto error; + } } - // t is borrowed reference - PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); - Py_DECREF(key); - if (t == NULL) { - return 0; + // all keys have been checked; there are no duplicates + Py_DECREF(seen); + + ADDOP_I(c, BUILD_TUPLE, size); + ADDOP(c, MATCH_KEYS); + // There's now a tuple of keys and a tuple of values on top of the subject: + pc->on_top += 2; + RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + // So far so good. Use that tuple of values on the stack to match + // sub-patterns against: + for (Py_ssize_t i = 0; i < size; i++) { + pattern_ty pattern = asdl_seq_GET(patterns, i); + if (WILDCARD_CHECK(pattern)) { + continue; + } + ADDOP(c, DUP_TOP); + ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i)); + ADDOP(c, BINARY_SUBSCR); + RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); } - if (t == key) { // tuple is new constant. - return 1; + // If we get this far, it's a match! We're done with the tuple of values, + // and whatever happens next should consume the tuple of keys underneath it: + pc->on_top -= 2; + ADDOP(c, POP_TOP); + if (star_target) { + // If we have a starred name, bind a dict of remaining items to it: + ADDOP(c, COPY_DICT_WITHOUT_KEYS); + RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc)); } - - PyObject *u = PyTuple_GET_ITEM(t, 1); - Py_INCREF(u); - Py_DECREF(*tuple); - *tuple = u; + else { + // Otherwise, we don't care about this tuple of keys anymore: + ADDOP(c, POP_TOP); + } + // Pop the subject: + pc->on_top--; + ADDOP(c, POP_TOP); return 1; + +error: + Py_DECREF(seen); + return 0; } -static PyCodeObject * -makecode(struct compiler *c, struct assembler *a) +static int +compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) { - PyObject *tmp; - PyCodeObject *co = NULL; - PyObject *consts = NULL; - PyObject *names = NULL; - PyObject *varnames = NULL; - PyObject *name = NULL; - PyObject *freevars = NULL; - PyObject *cellvars = NULL; - PyObject *bytecode = NULL; - Py_ssize_t nlocals; - int nlocals_int; - int flags; - int posorkeywordargcount, posonlyargcount, kwonlyargcount, maxdepth; - - consts = consts_dict_keys_inorder(c->u->u_consts); - names = dict_keys_inorder(c->u->u_names, 0); - varnames = dict_keys_inorder(c->u->u_varnames, 0); - if (!consts || !names || !varnames) - goto error; - - cellvars = dict_keys_inorder(c->u->u_cellvars, 0); - if (!cellvars) - goto error; - freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars)); - if (!freevars) - goto error; - - if (!merge_const_tuple(c, &names) || - !merge_const_tuple(c, &varnames) || - !merge_const_tuple(c, &cellvars) || - !merge_const_tuple(c, &freevars)) - { - goto error; + assert(p->kind == MatchOr_kind); + basicblock *end; + RETURN_IF_FALSE(end = compiler_new_block(c)); + 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: + pattern_context old_pc = *pc; + Py_INCREF(pc->stores); + // control is the list of names bound by the first alternative. It is used + // for checking different name bindings in alternatives, and for correcting + // the order in which extracted elements are placed on the stack. + PyObject *control = NULL; + // 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; + } + Py_SETREF(pc->stores, pc_stores); + // An irrefutable sub-pattern must be last, if it is allowed at all: + pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable; + pc->fail_pop = NULL; + pc->fail_pop_size = 0; + pc->on_top = 0; + if (!compiler_addop(c, DUP_TOP) || !compiler_pattern(c, alt, pc)) { + goto error; + } + // Success! + Py_ssize_t nstores = PyList_GET_SIZE(pc->stores); + if (!i) { + // This is the first alternative, so save its stores as a "control" + // 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); + } + else if (nstores != PyList_GET_SIZE(control)) { + goto diff; + } + else if (nstores) { + // There were captures. Check to see if we differ from control: + Py_ssize_t icontrol = nstores; + while (icontrol--) { + PyObject *name = PyList_GET_ITEM(control, icontrol); + Py_ssize_t istores = PySequence_Index(pc->stores, name); + if (istores < 0) { + PyErr_Clear(); + goto diff; + } + if (icontrol != istores) { + // Reorder the names on the stack to match the order of the + // names in control. There's probably a better way of doing + // this; the current solution is potentially very + // inefficient when each alternative subpattern binds lots + // of names in different orders. It's fine for reasonable + // cases, though. + assert(istores < icontrol); + Py_ssize_t rotations = istores + 1; + // Perform the same rotation on pc->stores: + PyObject *rotated = PyList_GetSlice(pc->stores, 0, + rotations); + if (rotated == NULL || + PyList_SetSlice(pc->stores, 0, rotations, NULL) || + PyList_SetSlice(pc->stores, icontrol - istores, + icontrol - istores, rotated)) + { + Py_XDECREF(rotated); + goto error; + } + Py_DECREF(rotated); + // That just did: + // rotated = pc_stores[:rotations] + // del pc_stores[:rotations] + // pc_stores[icontrol-istores:icontrol-istores] = rotated + // Do the same thing to the stack, using several ROT_Ns: + while (rotations--) { + if (!compiler_addop_i(c, ROT_N, icontrol + 1)) { + goto error; + } + } + } + } + } + assert(control); + if (!compiler_addop_j(c, JUMP_FORWARD, end) || + !compiler_next_block(c) || + !emit_and_reset_fail_pop(c, pc)) + { + goto error; + } + } + Py_DECREF(pc->stores); + *pc = old_pc; + Py_INCREF(pc->stores); + // 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_FORWARD)) { + goto error; + } + compiler_use_next_block(c, end); + Py_ssize_t nstores = PyList_GET_SIZE(control); + // There's a bunch of stuff on the stack between any where the new stores + // are and where they need to be: + // - The other stores. + // - A copy of the subject. + // - Anything else that may be on top of the stack. + // - Any previous stores we've already stashed away on the stack. + 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 (!compiler_addop_i(c, ROT_N, nrots)) { + goto error; + } + // Update the list of previous stores with this new name, checking for + // duplicates: + PyObject *name = PyList_GET_ITEM(control, i); + int dupe = PySequence_Contains(pc->stores, name); + if (dupe < 0) { + goto error; + } + if (dupe) { + compiler_error_duplicate_store(c, name); + goto error; + } + if (PyList_Append(pc->stores, name)) { + goto error; + } + } + Py_DECREF(old_pc.stores); + Py_DECREF(control); + // NOTE: Returning macros are safe again. + // Pop the copy of the subject: + ADDOP(c, POP_TOP); + return 1; +diff: + compiler_error(c, "alternative patterns bind different names"); +error: + PyObject_Free(old_pc.fail_pop); + Py_DECREF(old_pc.stores); + Py_XDECREF(control); + return 0; +} + + +static int +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; + Py_ssize_t size = asdl_seq_LEN(patterns); + Py_ssize_t star = -1; + int only_wildcard = 1; + int star_wildcard = 0; + // Find a starred name, if it exists. There may be at most one: + for (Py_ssize_t i = 0; i < size; i++) { + pattern_ty pattern = asdl_seq_GET(patterns, i); + if (pattern->kind == MatchStar_kind) { + if (star >= 0) { + const char *e = "multiple starred names in sequence pattern"; + return compiler_error(c, e); + } + star_wildcard = WILDCARD_STAR_CHECK(pattern); + only_wildcard &= star_wildcard; + star = i; + continue; + } + only_wildcard &= WILDCARD_CHECK(pattern); + } + // 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)); + 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)); + } + 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)); + } + // Whatever comes next should consume the subject: + pc->on_top--; + if (only_wildcard) { + // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc. + ADDOP(c, POP_TOP); + } + else if (star_wildcard) { + RETURN_IF_FALSE(pattern_helper_sequence_subscr(c, patterns, star, pc)); + } + else { + RETURN_IF_FALSE(pattern_helper_sequence_unpack(c, patterns, star, pc)); + } + return 1; +} + +static int +compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc) +{ + assert(p->kind == MatchValue_kind); + 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); + } + VISIT(c, expr, value); + ADDOP_COMPARE(c, Eq); + RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + return 1; +} + +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; +} + +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); + case MatchSingleton_kind: + return compiler_pattern_singleton(c, p, pc); + case MatchSequence_kind: + return compiler_pattern_sequence(c, p, pc); + case MatchMapping_kind: + return compiler_pattern_mapping(c, p, pc); + case MatchClass_kind: + return compiler_pattern_class(c, p, pc); + case MatchStar_kind: + return compiler_pattern_star(c, p, pc); + case MatchAs_kind: + return compiler_pattern_as(c, p, pc); + case MatchOr_kind: + return compiler_pattern_or(c, p, 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); +} + +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)); + 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(c, DUP_TOP); + } + 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)) { + Py_DECREF(pc->stores); + return 0; + } + 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)) { + Py_DECREF(pc->stores); + return 0; + } + } + 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)); + } + // Success! Pop the subject off, we're done with it: + if (i != cases - has_default - 1) { + ADDOP(c, POP_TOP); + } + VISIT_SEQ(c, stmt, m->body); + ADDOP_JUMP(c, JUMP_FORWARD, 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)); + } + 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); + } + else { + // Show line coverage for default case (it doesn't create bytecode) + ADDOP(c, NOP); + } + if (m->guard) { + RETURN_IF_FALSE(compiler_jump_if(c, m->guard, end, 0)); + } + VISIT_SEQ(c, stmt, m->body); + } + compiler_use_next_block(c, end); + return 1; +} + +static int +compiler_match(struct compiler *c, stmt_ty s) +{ + pattern_context pc; + pc.fail_pop = NULL; + int result = compiler_match_inner(c, s, &pc); + PyObject_Free(pc.fail_pop); + return result; +} + +#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; /* string containing bytecode */ + int a_offset; /* offset into bytecode */ + int a_nblocks; /* number of reachable blocks */ + PyObject *a_lnotab; /* string containing lnotab */ + int a_lnotab_off; /* offset into lnotab */ + int a_prevlineno; /* lineno of last emitted line in line table */ + int a_lineno; /* lineno of last emitted instruction */ + int a_lineno_start; /* bytecode start offset of current lineno */ + basicblock *a_entry; +}; + +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) +{ + 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; + } + + 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)) { + 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; + if (instr->i_opcode == JUMP_ABSOLUTE || + instr->i_opcode == JUMP_FORWARD || + 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); + } + } + PyObject_Free(stack); + return maxdepth; +} + +static int +assemble_init(struct assembler *a, int nblocks, int firstlineno) +{ + memset(a, 0, sizeof(struct assembler)); + a->a_prevlineno = a->a_lineno = firstlineno; + a->a_lnotab = NULL; + a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); + if (a->a_bytecode == NULL) { + goto error; + } + a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); + if (a->a_lnotab == NULL) { + goto error; + } + if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { + PyErr_NoMemory(); + goto error; + } + return 1; +error: + Py_XDECREF(a->a_bytecode); + Py_XDECREF(a->a_lnotab); + return 0; +} + +static void +assemble_free(struct assembler *a) +{ + Py_XDECREF(a->a_bytecode); + Py_XDECREF(a->a_lnotab); +} + +static int +blocksize(basicblock *b) +{ + int i; + int size = 0; + + for (i = 0; i < b->b_iused; i++) + size += instrsize(b->b_instr[i].i_oparg); + return size; +} + +static int +assemble_emit_linetable_pair(struct assembler *a, int bdelta, int ldelta) +{ + Py_ssize_t len = PyBytes_GET_SIZE(a->a_lnotab); + if (a->a_lnotab_off + 2 >= len) { + if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0) + return 0; + } + unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(a->a_lnotab); + lnotab += a->a_lnotab_off; + a->a_lnotab_off += 2; + *lnotab++ = bdelta; + *lnotab++ = ldelta; + return 1; +} + +/* Appends a range to the end of the line number table. See + * Objects/lnotab_notes.txt for the description of the line number table. */ + +static int +assemble_line_range(struct assembler *a) +{ + int ldelta, bdelta; + bdelta = (a->a_offset - a->a_lineno_start) * sizeof(_Py_CODEUNIT); + if (bdelta == 0) { + return 1; + } + if (a->a_lineno < 0) { + ldelta = -128; + } + else { + ldelta = a->a_lineno - a->a_prevlineno; + a->a_prevlineno = a->a_lineno; + while (ldelta > 127) { + if (!assemble_emit_linetable_pair(a, 0, 127)) { + return 0; + } + ldelta -= 127; + } + while (ldelta < -127) { + if (!assemble_emit_linetable_pair(a, 0, -127)) { + return 0; + } + ldelta += 127; + } + } + assert(-128 <= ldelta && ldelta < 128); + while (bdelta > 254) { + if (!assemble_emit_linetable_pair(a, 254, ldelta)) { + return 0; + } + ldelta = a->a_lineno < 0 ? -128 : 0; + bdelta -= 254; + } + if (!assemble_emit_linetable_pair(a, bdelta, ldelta)) { + return 0; + } + a->a_lineno_start = a->a_offset; + return 1; +} + +static int +assemble_lnotab(struct assembler *a, struct instr *i) +{ + if (i->i_lineno == a->a_lineno) { + return 1; + } + if (!assemble_line_range(a)) { + return 0; + } + a->a_lineno = i->i_lineno; + return 1; +} + + +/* assemble_emit() + Extend the bytecode with a new instruction. + Update lnotab if necessary. +*/ + +static int +assemble_emit(struct assembler *a, struct instr *i) +{ + int size, arg = 0; + Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); + _Py_CODEUNIT *code; + + arg = i->i_oparg; + size = instrsize(arg); + if (i->i_lineno && !assemble_lnotab(a, i)) + return 0; + 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; + } + code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; + a->a_offset += size; + write_op_arg(code, i->i_opcode, arg, size); + return 1; +} + +static void +normalize_jumps(struct assembler *a) +{ + for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + b->b_visited = 0; + } + for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + b->b_visited = 1; + if (b->b_iused == 0) { + continue; + } + struct instr *last = &b->b_instr[b->b_iused-1]; + if (last->i_opcode == JUMP_ABSOLUTE) { + if (last->i_target->b_visited == 0) { + last->i_opcode = JUMP_FORWARD; + } + } + if (last->i_opcode == JUMP_FORWARD) { + if (last->i_target->b_visited == 1) { + last->i_opcode = JUMP_ABSOLUTE; + } + } + } +} + +static void +assemble_jump_offsets(struct assembler *a, struct compiler *c) +{ + basicblock *b; + int bsize, totsize, extended_arg_recompile; + int i; + + /* 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 = instrsize(instr->i_oparg); + /* 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)) { + instr->i_oparg -= bsize; + } + if (instrsize(instr->i_oparg) != 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 instrsize() 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); +} + +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); + 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) + 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; + } + + /* (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 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; + } + + // t is borrowed reference + PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); + Py_DECREF(key); + if (t == NULL) { + return 0; + } + if (t == key) { // obj is new constant. + return 1; + } + + if (PyTuple_CheckExact(t)) { + // t is still borrowed reference + t = PyTuple_GET_ITEM(t, 1); + } + + Py_INCREF(t); + Py_DECREF(*obj); + *obj = t; + return 1; +} + +static PyCodeObject * +makecode(struct compiler *c, struct assembler *a, PyObject *consts) +{ + PyCodeObject *co = NULL; + PyObject *names = NULL; + PyObject *varnames = NULL; + PyObject *name = NULL; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + Py_ssize_t nlocals; + int nlocals_int; + int flags; + int posorkeywordargcount, posonlyargcount, kwonlyargcount, maxdepth; + + names = dict_keys_inorder(c->u->u_names, 0); + varnames = dict_keys_inorder(c->u->u_varnames, 0); + if (!names || !varnames) { + goto error; + } + cellvars = dict_keys_inorder(c->u->u_cellvars, 0); + if (!cellvars) + goto error; + freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars)); + if (!freevars) + goto error; + + if (!merge_const_one(c, &names) || + !merge_const_one(c, &varnames) || + !merge_const_one(c, &cellvars) || + !merge_const_one(c, &freevars)) + { + goto error; } nlocals = PyDict_GET_SIZE(c->u->u_varnames); @@ -5943,16 +6933,12 @@ makecode(struct compiler *c, struct assembler *a) if (flags < 0) goto error; - bytecode = PyCode_Optimize(a->a_bytecode, consts, names, a->a_lnotab); - if (!bytecode) - goto error; - - tmp = PyList_AsTuple(consts); /* PyCode_New requires a tuple */ - if (!tmp) + consts = PyList_AsTuple(consts); /* PyCode_New requires a tuple */ + if (consts == NULL) { goto error; - Py_DECREF(consts); - consts = tmp; - if (!merge_const_tuple(c, &consts)) { + } + if (!merge_const_one(c, &consts)) { + Py_DECREF(consts); goto error; } @@ -5961,21 +6947,28 @@ makecode(struct compiler *c, struct assembler *a) kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int); maxdepth = stackdepth(c); if (maxdepth < 0) { + Py_DECREF(consts); + goto error; + } + if (maxdepth > MAX_ALLOWED_STACK_USE) { + PyErr_Format(PyExc_SystemError, + "excessive stack use: stack is %d deep", + maxdepth); + Py_DECREF(consts); goto error; } co = PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount, posonlyargcount, kwonlyargcount, nlocals_int, - maxdepth, flags, bytecode, consts, names, + maxdepth, flags, a->a_bytecode, consts, names, varnames, freevars, cellvars, c->c_filename, c->u->u_name, c->u->u_firstlineno, a->a_lnotab); + Py_DECREF(consts); error: - Py_XDECREF(consts); Py_XDECREF(names); Py_XDECREF(varnames); Py_XDECREF(name); Py_XDECREF(freevars); Py_XDECREF(cellvars); - Py_XDECREF(bytecode); return co; } @@ -5983,10 +6976,11 @@ makecode(struct compiler *c, struct assembler *a) /* For debugging purposes only */ #if 0 static void -dump_instr(const struct instr *i) +dump_instr(struct instr *i) { - const char *jrel = i->i_jrel ? "jrel " : ""; - const char *jabs = i->i_jabs ? "jabs " : ""; + const char *jrel = (is_relative_jump(i)) ? "jrel " : ""; + const char *jabs = (is_jump(i) && !is_relative_jump(i))? "jabs " : ""; + char arg[128]; *arg = '\0'; @@ -6000,10 +6994,9 @@ dump_instr(const struct instr *i) static void dump_basicblock(const basicblock *b) { - const char *seen = b->b_seen ? "seen " : ""; const char *b_return = b->b_return ? "return " : ""; - fprintf(stderr, "used: %d, depth: %d, offset: %d %s%s\n", - b->b_iused, b->b_startdepth, b->b_offset, seen, b_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++) { @@ -6014,69 +7007,910 @@ dump_basicblock(const basicblock *b) } #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 +insert_generator_prefix(struct compiler *c, basicblock *entryblock) { + + int flags = compute_code_flags(c); + if (flags < 0) { + return -1; + } + int kind; + if (flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { + if (flags & CO_COROUTINE) { + kind = 1; + } + else if (flags & CO_ASYNC_GENERATOR) { + kind = 2; + } + else { + kind = 0; + } + } + else { + return 0; + } + if (compiler_next_instr(entryblock) < 0) { + return -1; + } + for (int i = entryblock->b_iused-1; i > 0; i--) { + entryblock->b_instr[i] = entryblock->b_instr[i-1]; + } + entryblock->b_instr[0].i_opcode = GEN_START; + entryblock->b_instr[0].i_oparg = kind; + entryblock->b_instr[0].i_lineno = -1; + entryblock->b_instr[0].i_target = NULL; + 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 void +propagate_line_numbers(struct assembler *a); + static PyCodeObject * assemble(struct compiler *c, int addNone) { basicblock *b, *entryblock; struct assembler a; - int i, j, nblocks; + int j, nblocks; PyCodeObject *co = NULL; + PyObject *consts = NULL; /* Make sure every block that falls off the end returns None. XXX NEXT_BLOCK() isn't quite right, because if the last block ends with a jump or return b_next shouldn't set. */ if (!c->u->u_curblock->b_return) { - NEXT_BLOCK(c); + c->u->u_lineno = -1; 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); + + if (insert_generator_prefix(c, entryblock)) { + goto error; + } /* Set firstlineno if it wasn't explicitly set. */ if (!c->u->u_firstlineno) { - if (entryblock && entryblock->b_instr && entryblock->b_instr->i_lineno) + if (entryblock->b_instr && entryblock->b_instr->i_lineno) c->u->u_firstlineno = entryblock->b_instr->i_lineno; - else + else c->u->u_firstlineno = 1; } + if (!assemble_init(&a, nblocks, c->u->u_firstlineno)) goto error; - dfs(c, entryblock, &a, nblocks); + a.a_entry = entryblock; + a.a_nblocks = nblocks; + + consts = consts_dict_keys_inorder(c->u->u_consts); + if (consts == NULL) { + goto error; + } + + 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); + + /* 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 in reverse postorder from dfs. */ - for (i = a.a_nblocks - 1; i >= 0; i--) { - b = a.a_postorder[i]; + /* 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; } + if (!assemble_line_range(&a)) { + return 0; + } - if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) + if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) { + goto error; + } + if (!merge_const_one(c, &a.a_lnotab)) { + goto error; + } + if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) { goto error; - if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) + } + if (!merge_const_one(c, &a.a_bytecode)) { goto error; + } - co = makecode(c, &a); + co = makecode(c, &a, consts); error: + Py_XDECREF(consts); assemble_free(&a); return co; } -#undef PyAST_Compile -PyCodeObject * -PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, - PyArena *arena) +/* 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 (inst[i].i_opcode != LOAD_CONST) { + 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 arg = inst[i].i_oparg; + PyObject *constant = PyList_GET_ITEM(consts, arg); + Py_INCREF(constant); + 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; +} + + +// Eliminate n * ROT_N(n). +static void +fold_rotations(struct instr *inst, int n) +{ + for (int i = 0; i < n; i++) { + int rot; + switch (inst[i].i_opcode) { + case ROT_N: + rot = inst[i].i_oparg; + break; + case ROT_FOUR: + rot = 4; + break; + case ROT_THREE: + rot = 3; + break; + case ROT_TWO: + rot = 2; + break; + default: + return; + } + if (rot != n) { + return; + } + } + for (int i = 0; i < n; i++) { + inst[i].i_opcode = NOP; + } +} + +// 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_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)) { + /* 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]; + } + else { + target = &nop; + } + 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 = PyList_GET_ITEM(consts, oparg); + is_true = PyObject_IsTrue(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_ABSOLUTE; + 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 = PyList_GET_ITEM(consts, oparg); + is_true = PyObject_IsTrue(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_ABSOLUTE; + bb->b_nofallthrough = 1; + } + else { + inst->i_opcode = NOP; + bb->b_instr[i+1].i_opcode = NOP; + } + break; + } + break; + } + + /* Try to fold tuples of constants. + Skip over BUILD_SEQN 1 UNPACK_SEQN 1. + Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. + Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ + 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; + break; + case 2: + inst->i_opcode = ROT_TWO; + bb->b_instr[i+1].i_opcode = NOP; + break; + case 3: + inst->i_opcode = ROT_THREE; + bb->b_instr[i+1].i_opcode = ROT_TWO; + } + break; + } + 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_ABSOLUTE: + case JUMP_FORWARD: + 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_ABSOLUTE: + case JUMP_FORWARD: + 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_FALSE: + switch (target->i_opcode) { + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); + } + break; + case POP_JUMP_IF_TRUE: + switch (target->i_opcode) { + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); + } + break; + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + switch (target->i_opcode) { + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + i -= jump_thread(inst, target, JUMP_ABSOLUTE); + } + break; + case FOR_ITER: + if (target->i_opcode == JUMP_FORWARD) { + i -= jump_thread(inst, target, FOR_ITER); + } + break; + case ROT_N: + switch (oparg) { + case 0: + case 1: + inst->i_opcode = NOP; + continue; + case 2: + inst->i_opcode = ROT_TWO; + break; + case 3: + inst->i_opcode = ROT_THREE; + break; + case 4: + inst->i_opcode = ROT_FOUR; + break; + } + if (i >= oparg - 1) { + fold_rotations(inst - oparg + 1, oparg); + } + break; + } + } + return 0; +error: + return -1; +} + +/* 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_ABSOLUTE && last->i_opcode != JUMP_FORWARD) { + return 0; + } + if (last->i_target->b_exit && last->i_target->b_iused <= MAX_COPY_SIZE) { + basicblock *to_copy = last->i_target; + 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, int prev_lineno) { + /* Remove NOPs when legal to do so. */ + int dest = 0; + 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 < 0 || next_lineno == lineno) { + bb->b_instr[src+1].i_lineno = lineno; + 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++) { + 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_ABSOLUTE: + case JUMP_FORWARD: + bb->b_nofallthrough = 1; + /* fall through */ + 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; + if (is_jump(&b->b_instr[i])) { + target = b->b_instr[i].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; + } + int prev_lineno = -1; + for (int i = 0; i < b->b_iused; i++) { + if (b->b_instr[i].i_lineno < 0) { + b->b_instr[i].i_lineno = prev_lineno; + } + else { + prev_lineno = b->b_instr[i].i_lineno; + } + } + 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) { + b->b_next->b_instr[0].i_lineno = prev_lineno; + } + } + if (is_jump(&b->b_instr[b->b_iused-1])) { + switch (b->b_instr[b->b_iused-1].i_opcode) { + /* Note: Only actual jumps, not exception handlers */ + case SETUP_ASYNC_WITH: + case SETUP_WITH: + case SETUP_FINALLY: + continue; + } + basicblock *target = b->b_instr[b->b_iused-1].i_target; + if (target->b_predecessors == 1) { + if (target->b_instr[0].i_lineno < 0) { + target->b_instr[0].i_lineno = prev_lineno; + } + } + } + } +} + +/* 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, -1); + 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; + } + } + basicblock *pred = NULL; + for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + int prev_lineno = -1; + if (pred && pred->b_iused) { + prev_lineno = pred->b_instr[pred->b_iused-1].i_lineno; + } + clean_basic_block(b, prev_lineno); + pred = b->b_nofallthrough ? NULL : b; + } + eliminate_empty_basic_blocks(a->a_entry); + /* 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]; + if (b_last_instr->i_opcode == JUMP_ABSOLUTE || + b_last_instr->i_opcode == JUMP_FORWARD) { + 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; + clean_basic_block(b, -1); + 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_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) { + return b->b_exit && b->b_instr[0].i_lineno < 0; +} + +/* 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])) { + switch (b->b_instr[b->b_iused-1].i_opcode) { + /* Note: Only actual jumps, not exception handlers */ + case SETUP_ASYNC_WITH: + case SETUP_WITH: + case SETUP_FINALLY: + continue; + } + 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; + } + new_target->b_instr[0].i_lineno = b->b_instr[b->b_iused-1].i_lineno; + 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); + b->b_next->b_instr[0].i_lineno = b->b_instr[b->b_iused-1].i_lineno; + } + } + } + return 0; +} + + +/* Retained for API compatibility. + * Optimization is now done in optimize_cfg */ + +PyObject * +PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts), + PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj)) { - return PyAST_CompileEx(mod, filename, flags, -1, arena); + Py_INCREF(code); + return code; } diff --git a/contrib/tools/python3/src/Python/condvar.h b/contrib/tools/python3/src/Python/condvar.h index 8cba19b8461..e5df7ff1328 100644 --- a/contrib/tools/python3/src/Python/condvar.h +++ b/contrib/tools/python3/src/Python/condvar.h @@ -99,7 +99,7 @@ PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) http://birrell.org/andrew/papers/ImplementingCVs.pdf Generic emulations of the pthread_cond_* API using - earlier Win32 functions can be found on the Web. + earlier Win32 functions can be found on the web. The following read can be give background information to these issues, but the implementations are all broken in some way. http://www.cse.wustl.edu/~schmidt/win32-cv-1.html diff --git a/contrib/tools/python3/src/Python/context.c b/contrib/tools/python3/src/Python/context.c index bacc7010c45..bf2ba93c14e 100644 --- a/contrib/tools/python3/src/Python/context.c +++ b/contrib/tools/python3/src/Python/context.c @@ -10,8 +10,6 @@ #define CONTEXT_FREELIST_MAXLEN 255 -static PyContext *ctx_freelist = NULL; -static int ctx_freelist_len = 0; #include "clinic/context.c.h" @@ -68,6 +66,14 @@ static int contextvar_del(PyContextVar *var); +static struct _Py_context_state * +get_context_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->context; +} + + PyObject * _PyContext_NewHamtForTests(void) { @@ -334,11 +340,16 @@ class _contextvars.Context "PyContext *" "&PyContext_Type" static inline PyContext * _context_alloc(void) { + struct _Py_context_state *state = get_context_state(); PyContext *ctx; - if (ctx_freelist_len) { - ctx_freelist_len--; - ctx = ctx_freelist; - ctx_freelist = (PyContext *)ctx->ctx_weakreflist; +#ifdef Py_DEBUG + // _context_alloc() must not be called after _PyContext_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree) { + state->numfree--; + ctx = state->freelist; + state->freelist = (PyContext *)ctx->ctx_weakreflist; ctx->ctx_weakreflist = NULL; _Py_NewReference((PyObject *)ctx); } @@ -458,10 +469,15 @@ context_tp_dealloc(PyContext *self) } (void)context_tp_clear(self); - if (ctx_freelist_len < CONTEXT_FREELIST_MAXLEN) { - ctx_freelist_len++; - self->ctx_weakreflist = (PyObject *)ctx_freelist; - ctx_freelist = self; + struct _Py_context_state *state = get_context_state(); +#ifdef Py_DEBUG + // _context_alloc() must not be called after _PyContext_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree < CONTEXT_FREELIST_MAXLEN) { + state->numfree++; + self->ctx_weakreflist = (PyObject *)state->freelist; + state->freelist = self; } else { Py_TYPE(self)->tp_free(self); @@ -687,7 +703,7 @@ static PyMappingMethods PyContext_as_mapping = { PyTypeObject PyContext_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "Context", + "_contextvars.Context", sizeof(PyContext), .tp_methods = PyContext_methods, .tp_as_mapping = &PyContext_as_mapping, @@ -1040,7 +1056,7 @@ static PyMethodDef PyContextVar_methods[] = { PyTypeObject PyContextVar_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "ContextVar", + "_contextvars.ContextVar", sizeof(PyContextVar), .tp_methods = PyContextVar_methods, .tp_members = PyContextVar_members, @@ -1181,7 +1197,7 @@ static PyMethodDef PyContextTokenType_methods[] = { PyTypeObject PyContextToken_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "Token", + "_contextvars.Token", sizeof(PyContextToken), .tp_methods = PyContextTokenType_methods, .tp_getset = PyContextTokenType_getsetlist, @@ -1271,11 +1287,12 @@ get_token_missing(void) void -_PyContext_ClearFreeList(void) +_PyContext_ClearFreeList(PyInterpreterState *interp) { - for (; ctx_freelist_len; ctx_freelist_len--) { - PyContext *ctx = ctx_freelist; - ctx_freelist = (PyContext *)ctx->ctx_weakreflist; + struct _Py_context_state *state = &interp->context; + for (; state->numfree; state->numfree--) { + PyContext *ctx = state->freelist; + state->freelist = (PyContext *)ctx->ctx_weakreflist; ctx->ctx_weakreflist = NULL; PyObject_GC_Del(ctx); } @@ -1283,10 +1300,16 @@ _PyContext_ClearFreeList(void) void -_PyContext_Fini(void) +_PyContext_Fini(PyInterpreterState *interp) { - Py_CLEAR(_token_missing); - _PyContext_ClearFreeList(); + if (_Py_IsMainInterpreter(interp)) { + Py_CLEAR(_token_missing); + } + _PyContext_ClearFreeList(interp); +#ifdef Py_DEBUG + struct _Py_context_state *state = &interp->context; + state->numfree = -1; +#endif _PyHamt_Fini(); } diff --git a/contrib/tools/python3/src/Python/dynload_win.c b/contrib/tools/python3/src/Python/dynload_win.c index 81787e5f22a..5702ab2cd71 100644 --- a/contrib/tools/python3/src/Python/dynload_win.c +++ b/contrib/tools/python3/src/Python/dynload_win.c @@ -166,14 +166,14 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, { dl_funcptr p; char funcname[258], *import_python; - const wchar_t *wpathname; _Py_CheckPython3(); -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wpathname = _PyUnicode_AsUnicode(pathname); -_Py_COMP_DIAG_POP +#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; @@ -195,6 +195,9 @@ _Py_COMP_DIAG_POP 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 */ /* restore old error mode settings */ SetErrorMode(old_mode); diff --git a/contrib/tools/python3/src/Python/errors.c b/contrib/tools/python3/src/Python/errors.c index 79278764cc5..bc1b55e440e 100644 --- a/contrib/tools/python3/src/Python/errors.c +++ b/contrib/tools/python3/src/Python/errors.c @@ -317,14 +317,14 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, PyObject **val, PyObject **tb) { int recursion_depth = 0; - tstate->overflowed++; + tstate->recursion_headroom++; PyObject *type, *value, *initial_tb; restart: type = *exc; if (type == NULL) { /* There was no exception, so nothing to do. */ - tstate->overflowed--; + tstate->recursion_headroom--; return; } @@ -376,7 +376,7 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, } *exc = type; *val = value; - tstate->overflowed--; + tstate->recursion_headroom--; return; error: @@ -1109,7 +1109,6 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict) { PyThreadState *tstate = _PyThreadState_GET(); PyObject *modulename = NULL; - PyObject *classname = NULL; PyObject *mydict = NULL; PyObject *bases = NULL; PyObject *result = NULL; @@ -1129,10 +1128,11 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict) goto failure; } - if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) { - if (_PyErr_Occurred(tstate)) { - goto failure; - } + int r = _PyDict_ContainsId(dict, &PyId___module__); + if (r < 0) { + goto failure; + } + if (r == 0) { modulename = PyUnicode_FromStringAndSize(name, (Py_ssize_t)(dot-name)); if (modulename == NULL) @@ -1155,7 +1155,6 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict) failure: Py_XDECREF(bases); Py_XDECREF(mydict); - Py_XDECREF(classname); Py_XDECREF(modulename); return result; } @@ -1220,7 +1219,7 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = { PyStatus -_PyErr_Init(void) +_PyErr_InitTypes(void) { if (UnraisableHookArgsType.tp_name == NULL) { if (PyStructSequence_InitType2(&UnraisableHookArgsType, @@ -1561,9 +1560,6 @@ PyErr_WriteUnraisable(PyObject *obj) } -extern PyObject *PyModule_GetWarningsModule(void); - - void PyErr_SyntaxLocation(const char *filename, int lineno) { @@ -1575,14 +1571,17 @@ PyErr_SyntaxLocation(const char *filename, int lineno) If the exception is not a SyntaxError, also sets additional attributes to make printing of exceptions believe it is a syntax error. */ -void -PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) +static void +PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, + int end_lineno, int end_col_offset) { PyObject *exc, *v, *tb, *tmp; _Py_IDENTIFIER(filename); _Py_IDENTIFIER(lineno); + _Py_IDENTIFIER(end_lineno); _Py_IDENTIFIER(msg); _Py_IDENTIFIER(offset); + _Py_IDENTIFIER(end_offset); _Py_IDENTIFIER(print_file_and_line); _Py_IDENTIFIER(text); PyThreadState *tstate = _PyThreadState_GET(); @@ -1612,6 +1611,32 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) _PyErr_Clear(tstate); } Py_XDECREF(tmp); + + tmp = NULL; + if (end_lineno >= 0) { + tmp = PyLong_FromLong(end_lineno); + if (tmp == NULL) { + _PyErr_Clear(tstate); + } + } + if (_PyObject_SetAttrId(v, &PyId_end_lineno, tmp ? tmp : Py_None)) { + _PyErr_Clear(tstate); + } + Py_XDECREF(tmp); + + tmp = NULL; + if (end_col_offset >= 0) { + tmp = PyLong_FromLong(end_col_offset); + if (tmp == NULL) { + _PyErr_Clear(tstate); + } + } + if (_PyObject_SetAttrId(v, &PyId_end_offset, tmp ? tmp : Py_None)) { + _PyErr_Clear(tstate); + } + Py_XDECREF(tmp); + + tmp = NULL; if (filename != NULL) { if (_PyObject_SetAttrId(v, &PyId_filename, filename)) { _PyErr_Clear(tstate); @@ -1624,9 +1649,18 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) } Py_DECREF(tmp); } + else { + _PyErr_Clear(tstate); + } } if (exc != PyExc_SyntaxError) { - if (!_PyObject_HasAttrId(v, &PyId_msg)) { + if (_PyObject_LookupAttrId(v, &PyId_msg, &tmp) < 0) { + _PyErr_Clear(tstate); + } + else if (tmp) { + Py_DECREF(tmp); + } + else { tmp = PyObject_Str(v); if (tmp) { if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { @@ -1638,7 +1672,13 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) _PyErr_Clear(tstate); } } - if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) { + if (_PyObject_LookupAttrId(v, &PyId_print_file_and_line, &tmp) < 0) { + _PyErr_Clear(tstate); + } + else if (tmp) { + Py_DECREF(tmp); + } + else { if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, Py_None)) { _PyErr_Clear(tstate); @@ -1648,6 +1688,17 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) _PyErr_Restore(tstate, exc, v, tb); } +void +PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) { + PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, lineno, -1); +} + +void +PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset, + int end_lineno, int end_col_offset) { + PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, end_lineno, end_col_offset); +} + void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) { @@ -1673,7 +1724,7 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) functionality in tb_displayline() in traceback.c. */ static PyObject * -err_programtext(PyThreadState *tstate, FILE *fp, int lineno) +err_programtext(PyThreadState *tstate, FILE *fp, int lineno, const char* encoding) { int i; char linebuf[1000]; @@ -1701,7 +1752,11 @@ after_loop: fclose(fp); if (i == lineno) { PyObject *res; - res = PyUnicode_FromString(linebuf); + if (encoding != NULL) { + res = PyUnicode_Decode(linebuf, strlen(linebuf), encoding, "replace"); + } else { + res = PyUnicode_FromString(linebuf); + } if (res == NULL) _PyErr_Clear(tstate); return res; @@ -1712,17 +1767,22 @@ after_loop: PyObject * PyErr_ProgramText(const char *filename, int lineno) { - FILE *fp; - if (filename == NULL || *filename == '\0' || lineno <= 0) { + if (filename == NULL) { return NULL; } - PyThreadState *tstate = _PyThreadState_GET(); - fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE); - return err_programtext(tstate, fp, lineno); + + PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); + if (filename_obj == NULL) { + PyErr_Clear(); + return NULL; + } + PyObject *res = PyErr_ProgramTextObject(filename_obj, lineno); + Py_DECREF(filename_obj); + return res; } PyObject * -PyErr_ProgramTextObject(PyObject *filename, int lineno) +_PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* encoding) { if (filename == NULL || lineno <= 0) { return NULL; @@ -1734,7 +1794,13 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno) _PyErr_Clear(tstate); return NULL; } - return err_programtext(tstate, fp, lineno); + return err_programtext(tstate, fp, lineno, encoding); +} + +PyObject * +PyErr_ProgramTextObject(PyObject *filename, int lineno) +{ + return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL); } #ifdef __cplusplus diff --git a/contrib/tools/python3/src/Python/fileutils.c b/contrib/tools/python3/src/Python/fileutils.c index 26e97df4ef3..c3144ee4078 100644 --- a/contrib/tools/python3/src/Python/fileutils.c +++ b/contrib/tools/python3/src/Python/fileutils.c @@ -1,5 +1,6 @@ #include "Python.h" -#include "pycore_fileutils.h" +#include "pycore_fileutils.h" // fileutils definitions +#include "pycore_runtime.h" // _PyRuntime #include "osdefs.h" // SEP #include @@ -65,9 +66,6 @@ get_surrogateescape(_Py_error_handler errors, int *surrogateescape) PyObject * _Py_device_encoding(int fd) { -#if defined(MS_WINDOWS) - UINT cp; -#endif int valid; Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH @@ -78,6 +76,7 @@ _Py_device_encoding(int fd) Py_RETURN_NONE; #if defined(MS_WINDOWS) + UINT cp; if (fd == 0) cp = GetConsoleCP(); else if (fd == 1 || fd == 2) @@ -86,16 +85,14 @@ _Py_device_encoding(int fd) cp = 0; /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application has no console */ - if (cp != 0) - return PyUnicode_FromFormat("cp%u", (unsigned int)cp); -#elif defined(CODESET) - { - char *codeset = nl_langinfo(CODESET); - if (codeset != NULL && codeset[0] != 0) - return PyUnicode_FromString(codeset); + if (cp == 0) { + Py_RETURN_NONE; } + + return PyUnicode_FromFormat("cp%u", (unsigned int)cp); +#else + return _Py_GetLocaleEncodingObject(); #endif - Py_RETURN_NONE; } @@ -871,6 +868,72 @@ _Py_EncodeLocaleEx(const wchar_t *text, char **str, current_locale, errors); } + +// Get the current locale encoding name: +// +// - Return "UTF-8" if _Py_FORCE_UTF8_LOCALE macro is defined (ex: on Android) +// - Return "UTF-8" if the UTF-8 Mode is enabled +// - On Windows, return the ANSI code page (ex: "cp1250") +// - Return "UTF-8" if nl_langinfo(CODESET) returns an empty string. +// - Otherwise, return nl_langinfo(CODESET). +// +// Return NULL on memory allocation failure. +// +// See also config_get_locale_encoding() +wchar_t* +_Py_GetLocaleEncoding(void) +{ +#ifdef _Py_FORCE_UTF8_LOCALE + // On Android langinfo.h and CODESET are missing, + // and UTF-8 is always used in mbstowcs() and wcstombs(). + return _PyMem_RawWcsdup(L"UTF-8"); +#else + const PyPreConfig *preconfig = &_PyRuntime.preconfig; + if (preconfig->utf8_mode) { + return _PyMem_RawWcsdup(L"UTF-8"); + } + +#ifdef MS_WINDOWS + wchar_t encoding[23]; + unsigned int ansi_codepage = GetACP(); + swprintf(encoding, Py_ARRAY_LENGTH(encoding), L"cp%u", ansi_codepage); + encoding[Py_ARRAY_LENGTH(encoding) - 1] = 0; + return _PyMem_RawWcsdup(encoding); +#else + const char *encoding = nl_langinfo(CODESET); + if (!encoding || encoding[0] == '\0') { + // Use UTF-8 if nl_langinfo() returns an empty string. It can happen on + // macOS if the LC_CTYPE locale is not supported. + return _PyMem_RawWcsdup(L"UTF-8"); + } + + wchar_t *wstr; + int res = decode_current_locale(encoding, &wstr, NULL, + NULL, _Py_ERROR_SURROGATEESCAPE); + if (res < 0) { + return NULL; + } + return wstr; +#endif // !MS_WINDOWS + +#endif // !_Py_FORCE_UTF8_LOCALE +} + + +PyObject * +_Py_GetLocaleEncodingObject(void) +{ + wchar_t *encoding = _Py_GetLocaleEncoding(); + if (encoding == NULL) { + PyErr_NoMemory(); + return NULL; + } + + PyObject *str = PyUnicode_FromWideChar(encoding, -1); + PyMem_RawFree(encoding); + return str; +} + #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION /* Check whether current locale uses Unicode as internal wchar_t form. */ @@ -1061,9 +1124,7 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status) HANDLE h; int type; - _Py_BEGIN_SUPPRESS_IPH - h = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH + h = _Py_get_osfhandle_noraise(fd); if (h == INVALID_HANDLE_VALUE) { /* errno is already set by _get_osfhandle, but we also set @@ -1156,18 +1217,21 @@ _Py_stat(PyObject *path, struct stat *statbuf) #ifdef MS_WINDOWS int err; struct _stat wstatbuf; - const wchar_t *wpath; -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wpath = _PyUnicode_AsUnicode(path); -_Py_COMP_DIAG_POP +#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 = _wstat(wpath, &wstatbuf); if (!err) statbuf->st_mode = wstatbuf.st_mode; +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(wpath); +#endif /* USE_UNICODE_WCHAR_CACHE */ return err; #else int ret; @@ -1199,9 +1263,7 @@ get_inheritable(int fd, int raise) HANDLE handle; DWORD flags; - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH + handle = _Py_get_osfhandle_noraise(fd); if (handle == INVALID_HANDLE_VALUE) { if (raise) PyErr_SetFromErrno(PyExc_OSError); @@ -1272,9 +1334,7 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) } #ifdef MS_WINDOWS - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH + handle = _Py_get_osfhandle_noraise(fd); if (handle == INVALID_HANDLE_VALUE) { if (raise) PyErr_SetFromErrno(PyExc_OSError); @@ -1545,33 +1605,6 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode) return f; } -/* Wrapper to fopen(). - - The file descriptor is created non-inheritable. - - If interrupted by a signal, fail with EINTR. */ -FILE* -_Py_fopen(const char *pathname, const char *mode) -{ - PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname); - if (pathname_obj == NULL) { - return NULL; - } - if (PySys_Audit("open", "Osi", pathname_obj, mode, 0) < 0) { - Py_DECREF(pathname_obj); - return NULL; - } - Py_DECREF(pathname_obj); - - FILE *f = fopen(pathname, mode); - if (f == NULL) - return NULL; - if (make_non_inheritable(fileno(f)) < 0) { - fclose(f); - return NULL; - } - return f; -} /* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem encoding and call fopen() otherwise. @@ -1592,7 +1625,6 @@ _Py_fopen_obj(PyObject *path, const char *mode) FILE *f; int async_err = 0; #ifdef MS_WINDOWS - const wchar_t *wpath; wchar_t wmode[10]; int usize; @@ -1607,10 +1639,11 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_TYPE(path)); return NULL; } -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wpath = _PyUnicode_AsUnicode(path); -_Py_COMP_DIAG_POP +#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; @@ -1618,6 +1651,9 @@ _Py_COMP_DIAG_POP 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; } @@ -1627,6 +1663,9 @@ _Py_COMP_DIAG_POP Py_END_ALLOW_THREADS } while (f == NULL && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(wpath); +#endif /* USE_UNICODE_WCHAR_CACHE */ #else PyObject *bytes; const char *path_bytes; @@ -2080,13 +2119,9 @@ _Py_dup(int fd) assert(PyGILState_Check()); #ifdef MS_WINDOWS - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH - if (handle == INVALID_HANDLE_VALUE) { - PyErr_SetFromErrno(PyExc_OSError); + handle = _Py_get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) return -1; - } Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH @@ -2164,7 +2199,9 @@ _Py_get_blocking(int fd) int _Py_set_blocking(int fd, int blocking) { -#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO) +/* bpo-41462: On VxWorks, ioctl(FIONBIO) only works on sockets. + Use fcntl() instead. */ +#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO) && !defined(__VXWORKS__) int arg = !blocking; if (ioctl(fd, FIONBIO, &arg) < 0) goto error; @@ -2194,8 +2231,47 @@ error: PyErr_SetFromErrno(PyExc_OSError); return -1; } -#endif +#else /* MS_WINDOWS */ +void* +_Py_get_osfhandle_noraise(int fd) +{ + void *handle; + _Py_BEGIN_SUPPRESS_IPH + handle = (void*)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + return handle; +} + +void* +_Py_get_osfhandle(int fd) +{ + void *handle = _Py_get_osfhandle_noraise(fd); + if (handle == INVALID_HANDLE_VALUE) + PyErr_SetFromErrno(PyExc_OSError); + return handle; +} + +int +_Py_open_osfhandle_noraise(void *handle, int flags) +{ + int fd; + _Py_BEGIN_SUPPRESS_IPH + fd = _open_osfhandle((intptr_t)handle, flags); + _Py_END_SUPPRESS_IPH + return fd; +} + +int +_Py_open_osfhandle(void *handle, int flags) +{ + int fd = _Py_open_osfhandle_noraise(handle, flags); + if (fd == -1) + PyErr_SetFromErrno(PyExc_OSError); + + return fd; +} +#endif /* MS_WINDOWS */ int _Py_GetLocaleconvNumeric(struct lconv *lc, @@ -2274,3 +2350,79 @@ done: #undef GET_LOCALE_STRING } + +/* Our selection logic for which function to use is as follows: + * 1. If close_range(2) is available, always prefer that; it's better for + * contiguous ranges like this than fdwalk(3) which entails iterating over + * the entire fd space and simply doing nothing for those outside the range. + * 2. If closefrom(2) is available, we'll attempt to use that next if we're + * closing up to sysconf(_SC_OPEN_MAX). + * 2a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), + * as that will be more performant if the range happens to have any chunk of + * non-opened fd in the middle. + * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. + */ +#ifdef __FreeBSD__ +# define USE_CLOSEFROM +#endif /* __FreeBSD__ */ + +#ifdef HAVE_FDWALK +# define USE_FDWALK +#endif /* HAVE_FDWALK */ + +#ifdef USE_FDWALK +static int +_fdwalk_close_func(void *lohi, int fd) +{ + int lo = ((int *)lohi)[0]; + int hi = ((int *)lohi)[1]; + + if (fd >= hi) { + return 1; + } + else if (fd >= lo) { + /* Ignore errors */ + (void)close(fd); + } + return 0; +} +#endif /* USE_FDWALK */ + +/* Closes all file descriptors in [first, last], ignoring errors. */ +void +_Py_closerange(int first, int last) +{ + first = Py_MAX(first, 0); + _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_CLOSE_RANGE + if (close_range(first, last, 0) == 0 || errno != ENOSYS) { + /* Any errors encountered while closing file descriptors are ignored; + * ENOSYS means no kernel support, though, + * so we'll fallback to the other methods. */ + } + else +#endif /* HAVE_CLOSE_RANGE */ +#ifdef USE_CLOSEFROM + if (last >= sysconf(_SC_OPEN_MAX)) { + /* Any errors encountered while closing file descriptors are ignored */ + closefrom(first); + } + else +#endif /* USE_CLOSEFROM */ +#ifdef USE_FDWALK + { + int lohi[2]; + lohi[0] = first; + lohi[1] = last + 1; + fdwalk(_fdwalk_close_func, lohi); + } +#else + { + for (int i = first; i <= last; i++) { + /* Ignore errors */ + (void)close(i); + } + } +#endif /* USE_FDWALK */ + _Py_END_SUPPRESS_IPH +} diff --git a/contrib/tools/python3/src/Python/formatter_unicode.c b/contrib/tools/python3/src/Python/formatter_unicode.c index e7ec4dd5cb4..7b5a7bd04eb 100644 --- a/contrib/tools/python3/src/Python/formatter_unicode.c +++ b/contrib/tools/python3/src/Python/formatter_unicode.c @@ -219,7 +219,7 @@ parse_internal_render_format_spec(PyObject *format_spec, /* The special case for 0-padding (backwards compat) */ if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') { format->fill_char = '0'; - if (!align_specified) { + if (!align_specified && default_align == '>') { format->align = '='; } ++pos; diff --git a/contrib/tools/python3/src/Python/frozen.c b/contrib/tools/python3/src/Python/frozen.c index 228a11019cf..7f433ff80ca 100644 --- a/contrib/tools/python3/src/Python/frozen.c +++ b/contrib/tools/python3/src/Python/frozen.c @@ -1,5 +1,5 @@ -/* Dummy frozen modules initializer */ +/* Frozen modules initializer */ #include "Python.h" #include "importlib.h" @@ -10,23 +10,12 @@ define a single frozen module, __hello__. Loading it will print some famous words... */ -/* To regenerate this data after the bytecode or marshal format has changed, - go to ../Tools/freeze/ and freeze the flag.py file; then copy and paste - the appropriate bytes from M___main__.c. */ - -static unsigned char M___hello__[] = { - 227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0, - 90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3, - 84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78, - 41,2,218,11,105,110,105,116,105,97,108,105,122,101,100,218, - 5,112,114,105,110,116,169,0,114,3,0,0,0,114,3,0, - 0,0,250,20,84,111,111,108,115,47,102,114,101,101,122,101, - 47,102,108,97,103,46,112,121,218,8,60,109,111,100,117,108, - 101,62,1,0,0,0,115,2,0,0,0,4,1, -}; +/* Run "make regen-frozen" to regen the file below (e.g. after a bytecode + * format change). The include file defines _Py_M__hello as an array of bytes. + */ +#include "frozen_hello.h" -#define SIZE (int)sizeof(M___hello__) +#define SIZE (int)sizeof(_Py_M__hello) static const struct _frozen _PyImport_FrozenModules[] = { /* importlib */ @@ -37,10 +26,10 @@ static const struct _frozen _PyImport_FrozenModules[] = { {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport)}, /* Test module */ - {"__hello__", M___hello__, SIZE}, + {"__hello__", _Py_M__hello, SIZE}, /* Test package (negative size indicates package-ness) */ - {"__phello__", M___hello__, -SIZE}, - {"__phello__.spam", M___hello__, SIZE}, + {"__phello__", _Py_M__hello, -SIZE}, + {"__phello__.spam", _Py_M__hello, SIZE}, {0, 0, 0} /* sentinel */ }; diff --git a/contrib/tools/python3/src/Python/frozen_hello.h b/contrib/tools/python3/src/Python/frozen_hello.h new file mode 100644 index 00000000000..5448c80daa4 --- /dev/null +++ b/contrib/tools/python3/src/Python/frozen_hello.h @@ -0,0 +1,12 @@ +/* Auto-generated by Programs/_freeze_importlib.c */ +const unsigned char _Py_M__hello[] = { + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0, + 90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3, + 84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78, + 41,2,90,11,105,110,105,116,105,97,108,105,122,101,100,218, + 5,112,114,105,110,116,169,0,114,1,0,0,0,114,1,0, + 0,0,122,14,60,102,114,111,122,101,110,32,104,101,108,108, + 111,62,218,8,60,109,111,100,117,108,101,62,1,0,0,0, + 115,4,0,0,0,4,0,12,1, +}; diff --git a/contrib/tools/python3/src/Python/future.c b/contrib/tools/python3/src/Python/future.c index 1663a38a6fd..d465608ca45 100644 --- a/contrib/tools/python3/src/Python/future.c +++ b/contrib/tools/python3/src/Python/future.c @@ -1,11 +1,5 @@ #include "Python.h" -#include "Python-ast.h" -#include "node.h" -#include "token.h" -#include "graminit.h" -#include "code.h" -#include "symtable.h" -#include "ast.h" +#include "pycore_ast.h" // _PyAST_GetDocString() #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" #define ERR_LATE_FUTURE \ @@ -15,11 +9,10 @@ static int future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) { int i; - asdl_seq *names; assert(s->kind == ImportFrom_kind); - names = s->v.ImportFrom.names; + asdl_alias_seq *names = s->v.ImportFrom.names; for (i = 0; i < asdl_seq_LEN(names); i++) { alias_ty name = (alias_ty)asdl_seq_GET(names, i); const char *feature = PyUnicode_AsUTF8(name->name); @@ -123,7 +116,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) PyFutureFeatures * -PyFuture_FromASTObject(mod_ty mod, PyObject *filename) +_PyFuture_FromAST(mod_ty mod, PyObject *filename) { PyFutureFeatures *ff; @@ -141,18 +134,3 @@ PyFuture_FromASTObject(mod_ty mod, PyObject *filename) } return ff; } - - -PyFutureFeatures * -PyFuture_FromAST(mod_ty mod, const char *filename_str) -{ - PyFutureFeatures *ff; - PyObject *filename; - - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - ff = PyFuture_FromASTObject(mod, filename); - Py_DECREF(filename); - return ff; -} diff --git a/contrib/tools/python3/src/Python/getargs.c b/contrib/tools/python3/src/Python/getargs.c index d4a531a5efb..d5e083509ef 100644 --- a/contrib/tools/python3/src/Python/getargs.c +++ b/contrib/tools/python3/src/Python/getargs.c @@ -2,7 +2,7 @@ /* New getargs implementation */ #include "Python.h" -#include "pycore_tupleobject.h" +#include "pycore_tuple.h" // _PyTuple_ITEMS() #include #include @@ -202,7 +202,7 @@ static int cleanup_ptr(PyObject *self, void *ptr) { if (ptr) { - PyMem_FREE(ptr); + PyMem_Free(ptr); } return 0; } @@ -246,7 +246,7 @@ cleanreturn(int retval, freelist_t *freelist) } } if (freelist->entries_malloced) - PyMem_FREE(freelist->entries); + PyMem_Free(freelist->entries); return retval; } @@ -452,7 +452,7 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, } if (iarg != 0) { PyOS_snprintf(p, sizeof(buf) - (p - buf), - "argument %" PY_FORMAT_SIZE_T "d", iarg); + "argument %zd", iarg); i = 0; p += strlen(p); while (i < 32 && levels[i] > 0 && (int)(p-buf) < 220) { @@ -540,15 +540,14 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, levels[0] = 0; if (toplevel) { PyOS_snprintf(msgbuf, bufsize, - "expected %d argument%s, not %" PY_FORMAT_SIZE_T "d", + "expected %d argument%s, not %zd", n, n == 1 ? "" : "s", len); } else { PyOS_snprintf(msgbuf, bufsize, - "must be sequence of length %d, " - "not %" PY_FORMAT_SIZE_T "d", + "must be sequence of length %d, not %zd", n, len); } return msgbuf; @@ -643,22 +642,6 @@ converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize) #define CONV_UNICODE "(unicode conversion error)" -/* Explicitly check for float arguments when integers are expected. - Return 1 for error, 0 if ok. - XXX Should be removed after the end of the deprecation period in - _PyLong_FromNbIndexOrNbInt. */ -static int -float_argument_error(PyObject *arg) -{ - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - return 1; - } - else - return 0; -} - /* Convert a non-tuple argument. Return NULL if conversion went OK, or a string with a message describing the failure. The message is formatted as "must be , not ". @@ -672,29 +655,14 @@ static const char * convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, char *msgbuf, size_t bufsize, freelist_t *freelist) { - /* For # codes */ -#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\ - if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \ - else { \ - if (PyErr_WarnEx(PyExc_DeprecationWarning, \ - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { \ - return NULL; \ - } \ - q=va_arg(*p_va, int*); \ - } -#define STORE_SIZE(s) \ - if (flags & FLAG_SIZE_T) \ - *q2=s; \ - else { \ - if (INT_MAX < s) { \ - PyErr_SetString(PyExc_OverflowError, \ - "size does not fit in an int"); \ - return converterr("", arg, msgbuf, bufsize); \ - } \ - *q = (int)s; \ - } -#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q) #define RETURN_ERR_OCCURRED return msgbuf + /* For # codes */ +#define REQUIRE_PY_SSIZE_T_CLEAN \ + if (!(flags & FLAG_SIZE_T)) { \ + PyErr_SetString(PyExc_SystemError, \ + "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \ + RETURN_ERR_OCCURRED; \ + } const char *format = *p_format; char c = *format++; @@ -704,10 +672,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'b': { /* unsigned byte -- very short int */ char *p = va_arg(*p_va, char *); - long ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = PyLong_AsLong(arg); + long ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else if (ival < 0) { @@ -728,11 +693,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'B': {/* byte sized bitfield - both signed and unsigned values allowed */ char *p = va_arg(*p_va, char *); - long ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = PyLong_AsUnsignedLongMask(arg); - if (ival == -1 && PyErr_Occurred()) + unsigned long ival = PyLong_AsUnsignedLongMask(arg); + if (ival == (unsigned long)-1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else *p = (unsigned char) ival; @@ -741,10 +703,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'h': {/* signed short int */ short *p = va_arg(*p_va, short *); - long ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = PyLong_AsLong(arg); + long ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else if (ival < SHRT_MIN) { @@ -765,11 +724,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'H': { /* short int sized bitfield, both signed and unsigned allowed */ unsigned short *p = va_arg(*p_va, unsigned short *); - long ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = PyLong_AsUnsignedLongMask(arg); - if (ival == -1 && PyErr_Occurred()) + unsigned long ival = PyLong_AsUnsignedLongMask(arg); + if (ival == (unsigned long)-1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else *p = (unsigned short) ival; @@ -778,10 +734,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'i': {/* signed int */ int *p = va_arg(*p_va, int *); - long ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = PyLong_AsLong(arg); + long ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else if (ival > INT_MAX) { @@ -802,14 +755,11 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'I': { /* int sized bitfield, both signed and unsigned allowed */ unsigned int *p = va_arg(*p_va, unsigned int *); - unsigned int ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = (unsigned int)PyLong_AsUnsignedLongMask(arg); - if (ival == (unsigned int)-1 && PyErr_Occurred()) + unsigned long ival = PyLong_AsUnsignedLongMask(arg); + if (ival == (unsigned long)-1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else - *p = ival; + *p = (unsigned int) ival; break; } @@ -818,9 +768,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, PyObject *iobj; Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *); Py_ssize_t ival = -1; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - iobj = PyNumber_Index(arg); + iobj = _PyNumber_Index(arg); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -832,10 +780,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } case 'l': {/* long int */ long *p = va_arg(*p_va, long *); - long ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = PyLong_AsLong(arg); + long ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else @@ -856,10 +801,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'L': {/* long long */ long long *p = va_arg( *p_va, long long * ); - long long ival; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - ival = PyLong_AsLongLong(arg); + long long ival = PyLong_AsLongLong(arg); if (ival == (long long)-1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else @@ -974,8 +916,9 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, if (count < 0) return converterr(buf, arg, msgbuf, bufsize); if (*format == '#') { - FETCH_SIZE; - STORE_SIZE(count); + REQUIRE_PY_SSIZE_T_CLEAN; + Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); + *psize = count; format++; } else { if (strlen(*p) != (size_t)count) { @@ -1017,11 +960,12 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } else if (*format == '#') { /* a string or read-only bytes-like object */ /* "s#" or "z#" */ const void **p = (const void **)va_arg(*p_va, const char **); - FETCH_SIZE; + REQUIRE_PY_SSIZE_T_CLEAN; + Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); if (c == 'z' && arg == Py_None) { *p = NULL; - STORE_SIZE(0); + *psize = 0; } else if (PyUnicode_Check(arg)) { Py_ssize_t len; @@ -1030,7 +974,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, return converterr(CONV_UNICODE, arg, msgbuf, bufsize); *p = sarg; - STORE_SIZE(len); + *psize = len; } else { /* read-only bytes-like object */ /* XXX Really? */ @@ -1038,7 +982,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, Py_ssize_t count = convertbuffer(arg, p, &buf); if (count < 0) return converterr(buf, arg, msgbuf, bufsize); - STORE_SIZE(count); + *psize = count; } format++; } else { @@ -1070,25 +1014,29 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'u': /* raw unicode buffer (Py_UNICODE *) */ case 'Z': /* raw unicode buffer or None */ { - // TODO: Raise DeprecationWarning + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "getargs: The '%c' format is deprecated. Use 'U' instead.", c)) { + return NULL; + } _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); if (*format == '#') { /* "u#" or "Z#" */ - FETCH_SIZE; + REQUIRE_PY_SSIZE_T_CLEAN; + Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); if (c == 'Z' && arg == Py_None) { *p = NULL; - STORE_SIZE(0); + *psize = 0; } else if (PyUnicode_Check(arg)) { Py_ssize_t len; *p = PyUnicode_AsUnicodeAndSize(arg, &len); if (*p == NULL) RETURN_ERR_OCCURRED; - STORE_SIZE(len); + *psize = len; } else return converterr(c == 'Z' ? "str or None" : "str", @@ -1203,22 +1151,11 @@ _Py_COMP_DIAG_POP trailing 0-byte */ - int *q = NULL; Py_ssize_t *q2 = NULL; - if (flags & FLAG_SIZE_T) { - q2 = va_arg(*p_va, Py_ssize_t*); - } - else { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) - { - Py_DECREF(s); - return NULL; - } - q = va_arg(*p_va, int*); - } + REQUIRE_PY_SSIZE_T_CLEAN; + Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); format++; - if (q == NULL && q2 == NULL) { + if (psize == NULL) { Py_DECREF(s); return converterr( "(buffer_len is NULL)", @@ -1238,30 +1175,20 @@ _Py_COMP_DIAG_POP arg, msgbuf, bufsize); } } else { - if (size + 1 > BUFFER_LEN) { + if (size + 1 > *psize) { Py_DECREF(s); PyErr_Format(PyExc_ValueError, "encoded string too long " "(%zd, maximum length %zd)", - (Py_ssize_t)size, (Py_ssize_t)(BUFFER_LEN-1)); + (Py_ssize_t)size, (Py_ssize_t)(*psize - 1)); RETURN_ERR_OCCURRED; } } memcpy(*buffer, ptr, size+1); - if (flags & FLAG_SIZE_T) { - *q2 = size; - } - else { - if (INT_MAX < size) { - Py_DECREF(s); - PyErr_SetString(PyExc_OverflowError, - "size does not fit in an int"); - return converterr("", arg, msgbuf, bufsize); - } - *q = (int)size; - } - } else { + *psize = size; + } + else { /* Using a 0-terminated buffer: - the encoded string has to be 0-terminated @@ -1399,9 +1326,7 @@ _Py_COMP_DIAG_POP *p_format = format; return NULL; -#undef FETCH_SIZE -#undef STORE_SIZE -#undef BUFFER_LEN +#undef REQUIRE_PY_SSIZE_T_CLEAN #undef RETURN_ERR_OCCURRED } @@ -2607,15 +2532,12 @@ skipitem(const char **p_format, va_list *p_va, int flags) } if (*format == '#') { if (p_va != NULL) { - if (flags & FLAG_SIZE_T) - (void) va_arg(*p_va, Py_ssize_t *); - else { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { - return NULL; - } - (void) va_arg(*p_va, int *); + if (!(flags & FLAG_SIZE_T)) { + PyErr_SetString(PyExc_SystemError, + "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); + return NULL; } + (void) va_arg(*p_va, Py_ssize_t *); } format++; } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w') diff --git a/contrib/tools/python3/src/Python/getcompiler.c b/contrib/tools/python3/src/Python/getcompiler.c index 59c0dbf92ae..a5d26239e87 100644 --- a/contrib/tools/python3/src/Python/getcompiler.c +++ b/contrib/tools/python3/src/Python/getcompiler.c @@ -8,9 +8,9 @@ // Note the __clang__ conditional has to come before the __GNUC__ one because // clang pretends to be GCC. #if defined(__clang__) -#define COMPILER "\n[Clang " __clang_version__ "]" +#define COMPILER "[Clang " __clang_version__ "]" #elif defined(__GNUC__) -#define COMPILER "\n[GCC " __VERSION__ "]" +#define COMPILER "[GCC " __VERSION__ "]" // Generic fallbacks. #elif defined(__cplusplus) #define COMPILER "[C++]" diff --git a/contrib/tools/python3/src/Python/graminit.c b/contrib/tools/python3/src/Python/graminit.c deleted file mode 100644 index b7aa52895f8..00000000000 --- a/contrib/tools/python3/src/Python/graminit.c +++ /dev/null @@ -1,2688 +0,0 @@ -/* Generated by Parser/pgen */ - -#include "exports.h" -#include "grammar.h" -Py_EXPORTED_SYMBOL grammar _PyParser_Grammar; -static const arc arcs_0_0[3] = { - {2, 1}, - {3, 2}, - {4, 1}, -}; -static const arc arcs_0_1[1] = { - {0, 1}, -}; -static const arc arcs_0_2[1] = { - {2, 1}, -}; -static state states_0[3] = { - {3, arcs_0_0}, - {1, arcs_0_1}, - {1, arcs_0_2}, -}; -static const arc arcs_1_0[3] = { - {44, 1}, - {2, 0}, - {45, 0}, -}; -static const arc arcs_1_1[1] = { - {0, 1}, -}; -static state states_1[2] = { - {3, arcs_1_0}, - {1, arcs_1_1}, -}; -static const arc arcs_2_0[1] = { - {47, 1}, -}; -static const arc arcs_2_1[2] = { - {44, 2}, - {2, 1}, -}; -static const arc arcs_2_2[1] = { - {0, 2}, -}; -static state states_2[3] = { - {1, arcs_2_0}, - {2, arcs_2_1}, - {1, arcs_2_2}, -}; -static const arc arcs_3_0[1] = { - {10, 1}, -}; -static const arc arcs_3_1[1] = { - {49, 2}, -}; -static const arc arcs_3_2[1] = { - {2, 3}, -}; -static const arc arcs_3_3[1] = { - {0, 3}, -}; -static state states_3[4] = { - {1, arcs_3_0}, - {1, arcs_3_1}, - {1, arcs_3_2}, - {1, arcs_3_3}, -}; -static const arc arcs_4_0[1] = { - {48, 1}, -}; -static const arc arcs_4_1[2] = { - {48, 1}, - {0, 1}, -}; -static state states_4[2] = { - {1, arcs_4_0}, - {2, arcs_4_1}, -}; -static const arc arcs_5_0[1] = { - {50, 1}, -}; -static const arc arcs_5_1[3] = { - {52, 2}, - {53, 2}, - {54, 2}, -}; -static const arc arcs_5_2[1] = { - {0, 2}, -}; -static state states_5[3] = { - {1, arcs_5_0}, - {3, arcs_5_1}, - {1, arcs_5_2}, -}; -static const arc arcs_6_0[1] = { - {38, 1}, -}; -static const arc arcs_6_1[1] = { - {54, 2}, -}; -static const arc arcs_6_2[1] = { - {0, 2}, -}; -static state states_6[3] = { - {1, arcs_6_0}, - {1, arcs_6_1}, - {1, arcs_6_2}, -}; -static const arc arcs_7_0[1] = { - {19, 1}, -}; -static const arc arcs_7_1[1] = { - {40, 2}, -}; -static const arc arcs_7_2[1] = { - {55, 3}, -}; -static const arc arcs_7_3[2] = { - {56, 4}, - {57, 5}, -}; -static const arc arcs_7_4[1] = { - {58, 6}, -}; -static const arc arcs_7_5[2] = { - {59, 7}, - {60, 8}, -}; -static const arc arcs_7_6[1] = { - {57, 5}, -}; -static const arc arcs_7_7[1] = { - {60, 8}, -}; -static const arc arcs_7_8[1] = { - {0, 8}, -}; -static state states_7[9] = { - {1, arcs_7_0}, - {1, arcs_7_1}, - {1, arcs_7_2}, - {2, arcs_7_3}, - {1, arcs_7_4}, - {2, arcs_7_5}, - {1, arcs_7_6}, - {1, arcs_7_7}, - {1, arcs_7_8}, -}; -static const arc arcs_8_0[1] = { - {5, 1}, -}; -static const arc arcs_8_1[2] = { - {61, 2}, - {62, 3}, -}; -static const arc arcs_8_2[1] = { - {0, 2}, -}; -static const arc arcs_8_3[1] = { - {61, 2}, -}; -static state states_8[4] = { - {1, arcs_8_0}, - {2, arcs_8_1}, - {1, arcs_8_2}, - {1, arcs_8_3}, -}; -static const arc arcs_9_0[3] = { - {6, 1}, - {63, 2}, - {64, 3}, -}; -static const arc arcs_9_1[4] = { - {65, 4}, - {59, 5}, - {64, 6}, - {0, 1}, -}; -static const arc arcs_9_2[1] = { - {64, 7}, -}; -static const arc arcs_9_3[4] = { - {65, 8}, - {66, 9}, - {59, 5}, - {0, 3}, -}; -static const arc arcs_9_4[4] = { - {63, 2}, - {59, 10}, - {64, 11}, - {0, 4}, -}; -static const arc arcs_9_5[1] = { - {0, 5}, -}; -static const arc arcs_9_6[3] = { - {65, 4}, - {59, 5}, - {0, 6}, -}; -static const arc arcs_9_7[3] = { - {65, 12}, - {59, 5}, - {0, 7}, -}; -static const arc arcs_9_8[6] = { - {6, 13}, - {63, 2}, - {67, 14}, - {59, 15}, - {64, 3}, - {0, 8}, -}; -static const arc arcs_9_9[1] = { - {58, 16}, -}; -static const arc arcs_9_10[3] = { - {63, 2}, - {64, 11}, - {0, 10}, -}; -static const arc arcs_9_11[4] = { - {65, 4}, - {66, 17}, - {59, 5}, - {0, 11}, -}; -static const arc arcs_9_12[2] = { - {59, 5}, - {0, 12}, -}; -static const arc arcs_9_13[4] = { - {65, 18}, - {59, 5}, - {64, 19}, - {0, 13}, -}; -static const arc arcs_9_14[2] = { - {65, 20}, - {0, 14}, -}; -static const arc arcs_9_15[5] = { - {6, 13}, - {63, 2}, - {67, 14}, - {64, 3}, - {0, 15}, -}; -static const arc arcs_9_16[3] = { - {65, 8}, - {59, 5}, - {0, 16}, -}; -static const arc arcs_9_17[1] = { - {58, 6}, -}; -static const arc arcs_9_18[4] = { - {63, 2}, - {59, 21}, - {64, 22}, - {0, 18}, -}; -static const arc arcs_9_19[3] = { - {65, 18}, - {59, 5}, - {0, 19}, -}; -static const arc arcs_9_20[5] = { - {6, 23}, - {63, 2}, - {59, 24}, - {64, 25}, - {0, 20}, -}; -static const arc arcs_9_21[3] = { - {63, 2}, - {64, 22}, - {0, 21}, -}; -static const arc arcs_9_22[4] = { - {65, 18}, - {66, 26}, - {59, 5}, - {0, 22}, -}; -static const arc arcs_9_23[4] = { - {65, 27}, - {59, 5}, - {64, 28}, - {0, 23}, -}; -static const arc arcs_9_24[1] = { - {64, 25}, -}; -static const arc arcs_9_25[4] = { - {65, 29}, - {66, 30}, - {59, 5}, - {0, 25}, -}; -static const arc arcs_9_26[1] = { - {58, 19}, -}; -static const arc arcs_9_27[4] = { - {63, 2}, - {59, 31}, - {64, 32}, - {0, 27}, -}; -static const arc arcs_9_28[3] = { - {65, 27}, - {59, 5}, - {0, 28}, -}; -static const arc arcs_9_29[5] = { - {6, 33}, - {63, 2}, - {59, 34}, - {64, 25}, - {0, 29}, -}; -static const arc arcs_9_30[1] = { - {58, 35}, -}; -static const arc arcs_9_31[3] = { - {63, 2}, - {64, 32}, - {0, 31}, -}; -static const arc arcs_9_32[4] = { - {65, 27}, - {66, 36}, - {59, 5}, - {0, 32}, -}; -static const arc arcs_9_33[4] = { - {65, 37}, - {59, 5}, - {64, 38}, - {0, 33}, -}; -static const arc arcs_9_34[4] = { - {6, 33}, - {63, 2}, - {64, 25}, - {0, 34}, -}; -static const arc arcs_9_35[3] = { - {65, 29}, - {59, 5}, - {0, 35}, -}; -static const arc arcs_9_36[1] = { - {58, 28}, -}; -static const arc arcs_9_37[4] = { - {63, 2}, - {59, 39}, - {64, 40}, - {0, 37}, -}; -static const arc arcs_9_38[3] = { - {65, 37}, - {59, 5}, - {0, 38}, -}; -static const arc arcs_9_39[3] = { - {63, 2}, - {64, 40}, - {0, 39}, -}; -static const arc arcs_9_40[4] = { - {65, 37}, - {66, 41}, - {59, 5}, - {0, 40}, -}; -static const arc arcs_9_41[1] = { - {58, 38}, -}; -static state states_9[42] = { - {3, arcs_9_0}, - {4, arcs_9_1}, - {1, arcs_9_2}, - {4, arcs_9_3}, - {4, arcs_9_4}, - {1, arcs_9_5}, - {3, arcs_9_6}, - {3, arcs_9_7}, - {6, arcs_9_8}, - {1, arcs_9_9}, - {3, arcs_9_10}, - {4, arcs_9_11}, - {2, arcs_9_12}, - {4, arcs_9_13}, - {2, arcs_9_14}, - {5, arcs_9_15}, - {3, arcs_9_16}, - {1, arcs_9_17}, - {4, arcs_9_18}, - {3, arcs_9_19}, - {5, arcs_9_20}, - {3, arcs_9_21}, - {4, arcs_9_22}, - {4, arcs_9_23}, - {1, arcs_9_24}, - {4, arcs_9_25}, - {1, arcs_9_26}, - {4, arcs_9_27}, - {3, arcs_9_28}, - {5, arcs_9_29}, - {1, arcs_9_30}, - {3, arcs_9_31}, - {4, arcs_9_32}, - {4, arcs_9_33}, - {4, arcs_9_34}, - {3, arcs_9_35}, - {1, arcs_9_36}, - {4, arcs_9_37}, - {3, arcs_9_38}, - {3, arcs_9_39}, - {4, arcs_9_40}, - {1, arcs_9_41}, -}; -static const arc arcs_10_0[1] = { - {40, 1}, -}; -static const arc arcs_10_1[2] = { - {57, 2}, - {0, 1}, -}; -static const arc arcs_10_2[1] = { - {58, 3}, -}; -static const arc arcs_10_3[1] = { - {0, 3}, -}; -static state states_10[4] = { - {1, arcs_10_0}, - {2, arcs_10_1}, - {1, arcs_10_2}, - {1, arcs_10_3}, -}; -static const arc arcs_11_0[3] = { - {6, 1}, - {63, 2}, - {69, 3}, -}; -static const arc arcs_11_1[3] = { - {65, 4}, - {69, 5}, - {0, 1}, -}; -static const arc arcs_11_2[1] = { - {69, 6}, -}; -static const arc arcs_11_3[3] = { - {65, 7}, - {66, 8}, - {0, 3}, -}; -static const arc arcs_11_4[3] = { - {63, 2}, - {69, 9}, - {0, 4}, -}; -static const arc arcs_11_5[2] = { - {65, 4}, - {0, 5}, -}; -static const arc arcs_11_6[2] = { - {65, 10}, - {0, 6}, -}; -static const arc arcs_11_7[5] = { - {6, 11}, - {63, 2}, - {67, 12}, - {69, 3}, - {0, 7}, -}; -static const arc arcs_11_8[1] = { - {58, 13}, -}; -static const arc arcs_11_9[3] = { - {65, 4}, - {66, 14}, - {0, 9}, -}; -static const arc arcs_11_10[1] = { - {0, 10}, -}; -static const arc arcs_11_11[3] = { - {65, 15}, - {69, 16}, - {0, 11}, -}; -static const arc arcs_11_12[2] = { - {65, 17}, - {0, 12}, -}; -static const arc arcs_11_13[2] = { - {65, 7}, - {0, 13}, -}; -static const arc arcs_11_14[1] = { - {58, 5}, -}; -static const arc arcs_11_15[3] = { - {63, 2}, - {69, 18}, - {0, 15}, -}; -static const arc arcs_11_16[2] = { - {65, 15}, - {0, 16}, -}; -static const arc arcs_11_17[4] = { - {6, 19}, - {63, 2}, - {69, 20}, - {0, 17}, -}; -static const arc arcs_11_18[3] = { - {65, 15}, - {66, 21}, - {0, 18}, -}; -static const arc arcs_11_19[3] = { - {65, 22}, - {69, 23}, - {0, 19}, -}; -static const arc arcs_11_20[3] = { - {65, 24}, - {66, 25}, - {0, 20}, -}; -static const arc arcs_11_21[1] = { - {58, 16}, -}; -static const arc arcs_11_22[3] = { - {63, 2}, - {69, 26}, - {0, 22}, -}; -static const arc arcs_11_23[2] = { - {65, 22}, - {0, 23}, -}; -static const arc arcs_11_24[4] = { - {6, 27}, - {63, 2}, - {69, 20}, - {0, 24}, -}; -static const arc arcs_11_25[1] = { - {58, 28}, -}; -static const arc arcs_11_26[3] = { - {65, 22}, - {66, 29}, - {0, 26}, -}; -static const arc arcs_11_27[3] = { - {65, 30}, - {69, 31}, - {0, 27}, -}; -static const arc arcs_11_28[2] = { - {65, 24}, - {0, 28}, -}; -static const arc arcs_11_29[1] = { - {58, 23}, -}; -static const arc arcs_11_30[3] = { - {63, 2}, - {69, 32}, - {0, 30}, -}; -static const arc arcs_11_31[2] = { - {65, 30}, - {0, 31}, -}; -static const arc arcs_11_32[3] = { - {65, 30}, - {66, 33}, - {0, 32}, -}; -static const arc arcs_11_33[1] = { - {58, 31}, -}; -static state states_11[34] = { - {3, arcs_11_0}, - {3, arcs_11_1}, - {1, arcs_11_2}, - {3, arcs_11_3}, - {3, arcs_11_4}, - {2, arcs_11_5}, - {2, arcs_11_6}, - {5, arcs_11_7}, - {1, arcs_11_8}, - {3, arcs_11_9}, - {1, arcs_11_10}, - {3, arcs_11_11}, - {2, arcs_11_12}, - {2, arcs_11_13}, - {1, arcs_11_14}, - {3, arcs_11_15}, - {2, arcs_11_16}, - {4, arcs_11_17}, - {3, arcs_11_18}, - {3, arcs_11_19}, - {3, arcs_11_20}, - {1, arcs_11_21}, - {3, arcs_11_22}, - {2, arcs_11_23}, - {4, arcs_11_24}, - {1, arcs_11_25}, - {3, arcs_11_26}, - {3, arcs_11_27}, - {2, arcs_11_28}, - {1, arcs_11_29}, - {3, arcs_11_30}, - {2, arcs_11_31}, - {3, arcs_11_32}, - {1, arcs_11_33}, -}; -static const arc arcs_12_0[1] = { - {40, 1}, -}; -static const arc arcs_12_1[1] = { - {0, 1}, -}; -static state states_12[2] = { - {1, arcs_12_0}, - {1, arcs_12_1}, -}; -static const arc arcs_13_0[2] = { - {3, 1}, - {4, 1}, -}; -static const arc arcs_13_1[1] = { - {0, 1}, -}; -static state states_13[2] = { - {2, arcs_13_0}, - {1, arcs_13_1}, -}; -static const arc arcs_14_0[1] = { - {70, 1}, -}; -static const arc arcs_14_1[2] = { - {71, 2}, - {2, 3}, -}; -static const arc arcs_14_2[2] = { - {2, 3}, - {70, 1}, -}; -static const arc arcs_14_3[1] = { - {0, 3}, -}; -static state states_14[4] = { - {1, arcs_14_0}, - {2, arcs_14_1}, - {2, arcs_14_2}, - {1, arcs_14_3}, -}; -static const arc arcs_15_0[8] = { - {72, 1}, - {73, 1}, - {74, 1}, - {75, 1}, - {76, 1}, - {77, 1}, - {78, 1}, - {79, 1}, -}; -static const arc arcs_15_1[1] = { - {0, 1}, -}; -static state states_15[2] = { - {8, arcs_15_0}, - {1, arcs_15_1}, -}; -static const arc arcs_16_0[1] = { - {80, 1}, -}; -static const arc arcs_16_1[4] = { - {66, 2}, - {81, 3}, - {82, 4}, - {0, 1}, -}; -static const arc arcs_16_2[2] = { - {80, 5}, - {83, 5}, -}; -static const arc arcs_16_3[1] = { - {0, 3}, -}; -static const arc arcs_16_4[2] = { - {47, 3}, - {83, 3}, -}; -static const arc arcs_16_5[3] = { - {66, 2}, - {59, 3}, - {0, 5}, -}; -static state states_16[6] = { - {1, arcs_16_0}, - {4, arcs_16_1}, - {2, arcs_16_2}, - {1, arcs_16_3}, - {2, arcs_16_4}, - {3, arcs_16_5}, -}; -static const arc arcs_17_0[1] = { - {57, 1}, -}; -static const arc arcs_17_1[1] = { - {58, 2}, -}; -static const arc arcs_17_2[2] = { - {66, 3}, - {0, 2}, -}; -static const arc arcs_17_3[2] = { - {80, 4}, - {83, 4}, -}; -static const arc arcs_17_4[1] = { - {0, 4}, -}; -static state states_17[5] = { - {1, arcs_17_0}, - {1, arcs_17_1}, - {2, arcs_17_2}, - {2, arcs_17_3}, - {1, arcs_17_4}, -}; -static const arc arcs_18_0[2] = { - {84, 1}, - {58, 1}, -}; -static const arc arcs_18_1[2] = { - {65, 2}, - {0, 1}, -}; -static const arc arcs_18_2[3] = { - {84, 1}, - {58, 1}, - {0, 2}, -}; -static state states_18[3] = { - {2, arcs_18_0}, - {2, arcs_18_1}, - {3, arcs_18_2}, -}; -static const arc arcs_19_0[13] = { - {85, 1}, - {86, 1}, - {87, 1}, - {88, 1}, - {89, 1}, - {90, 1}, - {91, 1}, - {92, 1}, - {93, 1}, - {94, 1}, - {95, 1}, - {96, 1}, - {97, 1}, -}; -static const arc arcs_19_1[1] = { - {0, 1}, -}; -static state states_19[2] = { - {13, arcs_19_0}, - {1, arcs_19_1}, -}; -static const arc arcs_20_0[1] = { - {20, 1}, -}; -static const arc arcs_20_1[1] = { - {98, 2}, -}; -static const arc arcs_20_2[1] = { - {0, 2}, -}; -static state states_20[3] = { - {1, arcs_20_0}, - {1, arcs_20_1}, - {1, arcs_20_2}, -}; -static const arc arcs_21_0[1] = { - {29, 1}, -}; -static const arc arcs_21_1[1] = { - {0, 1}, -}; -static state states_21[2] = { - {1, arcs_21_0}, - {1, arcs_21_1}, -}; -static const arc arcs_22_0[5] = { - {99, 1}, - {100, 1}, - {101, 1}, - {102, 1}, - {103, 1}, -}; -static const arc arcs_22_1[1] = { - {0, 1}, -}; -static state states_22[2] = { - {5, arcs_22_0}, - {1, arcs_22_1}, -}; -static const arc arcs_23_0[1] = { - {16, 1}, -}; -static const arc arcs_23_1[1] = { - {0, 1}, -}; -static state states_23[2] = { - {1, arcs_23_0}, - {1, arcs_23_1}, -}; -static const arc arcs_24_0[1] = { - {18, 1}, -}; -static const arc arcs_24_1[1] = { - {0, 1}, -}; -static state states_24[2] = { - {1, arcs_24_0}, - {1, arcs_24_1}, -}; -static const arc arcs_25_0[1] = { - {31, 1}, -}; -static const arc arcs_25_1[2] = { - {80, 2}, - {0, 1}, -}; -static const arc arcs_25_2[1] = { - {0, 2}, -}; -static state states_25[3] = { - {1, arcs_25_0}, - {2, arcs_25_1}, - {1, arcs_25_2}, -}; -static const arc arcs_26_0[1] = { - {83, 1}, -}; -static const arc arcs_26_1[1] = { - {0, 1}, -}; -static state states_26[2] = { - {1, arcs_26_0}, - {1, arcs_26_1}, -}; -static const arc arcs_27_0[1] = { - {30, 1}, -}; -static const arc arcs_27_1[2] = { - {58, 2}, - {0, 1}, -}; -static const arc arcs_27_2[2] = { - {22, 3}, - {0, 2}, -}; -static const arc arcs_27_3[1] = { - {58, 4}, -}; -static const arc arcs_27_4[1] = { - {0, 4}, -}; -static state states_27[5] = { - {1, arcs_27_0}, - {2, arcs_27_1}, - {2, arcs_27_2}, - {1, arcs_27_3}, - {1, arcs_27_4}, -}; -static const arc arcs_28_0[2] = { - {104, 1}, - {105, 1}, -}; -static const arc arcs_28_1[1] = { - {0, 1}, -}; -static state states_28[2] = { - {2, arcs_28_0}, - {1, arcs_28_1}, -}; -static const arc arcs_29_0[1] = { - {25, 1}, -}; -static const arc arcs_29_1[1] = { - {106, 2}, -}; -static const arc arcs_29_2[1] = { - {0, 2}, -}; -static state states_29[3] = { - {1, arcs_29_0}, - {1, arcs_29_1}, - {1, arcs_29_2}, -}; -static const arc arcs_30_0[1] = { - {22, 1}, -}; -static const arc arcs_30_1[3] = { - {107, 2}, - {9, 2}, - {108, 3}, -}; -static const arc arcs_30_2[4] = { - {107, 2}, - {9, 2}, - {25, 4}, - {108, 3}, -}; -static const arc arcs_30_3[1] = { - {25, 4}, -}; -static const arc arcs_30_4[3] = { - {5, 5}, - {6, 6}, - {109, 6}, -}; -static const arc arcs_30_5[1] = { - {109, 7}, -}; -static const arc arcs_30_6[1] = { - {0, 6}, -}; -static const arc arcs_30_7[1] = { - {61, 6}, -}; -static state states_30[8] = { - {1, arcs_30_0}, - {3, arcs_30_1}, - {4, arcs_30_2}, - {1, arcs_30_3}, - {3, arcs_30_4}, - {1, arcs_30_5}, - {1, arcs_30_6}, - {1, arcs_30_7}, -}; -static const arc arcs_31_0[1] = { - {40, 1}, -}; -static const arc arcs_31_1[2] = { - {111, 2}, - {0, 1}, -}; -static const arc arcs_31_2[1] = { - {40, 3}, -}; -static const arc arcs_31_3[1] = { - {0, 3}, -}; -static state states_31[4] = { - {1, arcs_31_0}, - {2, arcs_31_1}, - {1, arcs_31_2}, - {1, arcs_31_3}, -}; -static const arc arcs_32_0[1] = { - {108, 1}, -}; -static const arc arcs_32_1[2] = { - {111, 2}, - {0, 1}, -}; -static const arc arcs_32_2[1] = { - {40, 3}, -}; -static const arc arcs_32_3[1] = { - {0, 3}, -}; -static state states_32[4] = { - {1, arcs_32_0}, - {2, arcs_32_1}, - {1, arcs_32_2}, - {1, arcs_32_3}, -}; -static const arc arcs_33_0[1] = { - {110, 1}, -}; -static const arc arcs_33_1[2] = { - {65, 2}, - {0, 1}, -}; -static const arc arcs_33_2[2] = { - {110, 1}, - {0, 2}, -}; -static state states_33[3] = { - {1, arcs_33_0}, - {2, arcs_33_1}, - {2, arcs_33_2}, -}; -static const arc arcs_34_0[1] = { - {112, 1}, -}; -static const arc arcs_34_1[2] = { - {65, 0}, - {0, 1}, -}; -static state states_34[2] = { - {1, arcs_34_0}, - {2, arcs_34_1}, -}; -static const arc arcs_35_0[1] = { - {40, 1}, -}; -static const arc arcs_35_1[2] = { - {107, 0}, - {0, 1}, -}; -static state states_35[2] = { - {1, arcs_35_0}, - {2, arcs_35_1}, -}; -static const arc arcs_36_0[1] = { - {23, 1}, -}; -static const arc arcs_36_1[1] = { - {40, 2}, -}; -static const arc arcs_36_2[2] = { - {65, 1}, - {0, 2}, -}; -static state states_36[3] = { - {1, arcs_36_0}, - {1, arcs_36_1}, - {2, arcs_36_2}, -}; -static const arc arcs_37_0[1] = { - {27, 1}, -}; -static const arc arcs_37_1[1] = { - {40, 2}, -}; -static const arc arcs_37_2[2] = { - {65, 1}, - {0, 2}, -}; -static state states_37[3] = { - {1, arcs_37_0}, - {1, arcs_37_1}, - {2, arcs_37_2}, -}; -static const arc arcs_38_0[1] = { - {15, 1}, -}; -static const arc arcs_38_1[1] = { - {58, 2}, -}; -static const arc arcs_38_2[2] = { - {65, 3}, - {0, 2}, -}; -static const arc arcs_38_3[1] = { - {58, 4}, -}; -static const arc arcs_38_4[1] = { - {0, 4}, -}; -static state states_38[5] = { - {1, arcs_38_0}, - {1, arcs_38_1}, - {2, arcs_38_2}, - {1, arcs_38_3}, - {1, arcs_38_4}, -}; -static const arc arcs_39_0[9] = { - {113, 1}, - {53, 1}, - {51, 1}, - {114, 1}, - {54, 1}, - {115, 1}, - {116, 1}, - {117, 1}, - {118, 1}, -}; -static const arc arcs_39_1[1] = { - {0, 1}, -}; -static state states_39[2] = { - {9, arcs_39_0}, - {1, arcs_39_1}, -}; -static const arc arcs_40_0[1] = { - {38, 1}, -}; -static const arc arcs_40_1[3] = { - {114, 2}, - {54, 2}, - {118, 2}, -}; -static const arc arcs_40_2[1] = { - {0, 2}, -}; -static state states_40[3] = { - {1, arcs_40_0}, - {3, arcs_40_1}, - {1, arcs_40_2}, -}; -static const arc arcs_41_0[1] = { - {24, 1}, -}; -static const arc arcs_41_1[1] = { - {49, 2}, -}; -static const arc arcs_41_2[1] = { - {57, 3}, -}; -static const arc arcs_41_3[1] = { - {119, 4}, -}; -static const arc arcs_41_4[3] = { - {120, 1}, - {121, 5}, - {0, 4}, -}; -static const arc arcs_41_5[1] = { - {57, 6}, -}; -static const arc arcs_41_6[1] = { - {119, 7}, -}; -static const arc arcs_41_7[1] = { - {0, 7}, -}; -static state states_41[8] = { - {1, arcs_41_0}, - {1, arcs_41_1}, - {1, arcs_41_2}, - {1, arcs_41_3}, - {3, arcs_41_4}, - {1, arcs_41_5}, - {1, arcs_41_6}, - {1, arcs_41_7}, -}; -static const arc arcs_42_0[1] = { - {33, 1}, -}; -static const arc arcs_42_1[1] = { - {49, 2}, -}; -static const arc arcs_42_2[1] = { - {57, 3}, -}; -static const arc arcs_42_3[1] = { - {119, 4}, -}; -static const arc arcs_42_4[2] = { - {121, 5}, - {0, 4}, -}; -static const arc arcs_42_5[1] = { - {57, 6}, -}; -static const arc arcs_42_6[1] = { - {119, 7}, -}; -static const arc arcs_42_7[1] = { - {0, 7}, -}; -static state states_42[8] = { - {1, arcs_42_0}, - {1, arcs_42_1}, - {1, arcs_42_2}, - {1, arcs_42_3}, - {2, arcs_42_4}, - {1, arcs_42_5}, - {1, arcs_42_6}, - {1, arcs_42_7}, -}; -static const arc arcs_43_0[1] = { - {21, 1}, -}; -static const arc arcs_43_1[1] = { - {98, 2}, -}; -static const arc arcs_43_2[1] = { - {122, 3}, -}; -static const arc arcs_43_3[1] = { - {47, 4}, -}; -static const arc arcs_43_4[1] = { - {57, 5}, -}; -static const arc arcs_43_5[2] = { - {59, 6}, - {119, 7}, -}; -static const arc arcs_43_6[1] = { - {119, 7}, -}; -static const arc arcs_43_7[2] = { - {121, 8}, - {0, 7}, -}; -static const arc arcs_43_8[1] = { - {57, 9}, -}; -static const arc arcs_43_9[1] = { - {119, 10}, -}; -static const arc arcs_43_10[1] = { - {0, 10}, -}; -static state states_43[11] = { - {1, arcs_43_0}, - {1, arcs_43_1}, - {1, arcs_43_2}, - {1, arcs_43_3}, - {1, arcs_43_4}, - {2, arcs_43_5}, - {1, arcs_43_6}, - {2, arcs_43_7}, - {1, arcs_43_8}, - {1, arcs_43_9}, - {1, arcs_43_10}, -}; -static const arc arcs_44_0[1] = { - {32, 1}, -}; -static const arc arcs_44_1[1] = { - {57, 2}, -}; -static const arc arcs_44_2[1] = { - {119, 3}, -}; -static const arc arcs_44_3[2] = { - {123, 4}, - {124, 5}, -}; -static const arc arcs_44_4[1] = { - {57, 6}, -}; -static const arc arcs_44_5[1] = { - {57, 7}, -}; -static const arc arcs_44_6[1] = { - {119, 8}, -}; -static const arc arcs_44_7[1] = { - {119, 9}, -}; -static const arc arcs_44_8[1] = { - {0, 8}, -}; -static const arc arcs_44_9[4] = { - {121, 10}, - {123, 4}, - {124, 5}, - {0, 9}, -}; -static const arc arcs_44_10[1] = { - {57, 11}, -}; -static const arc arcs_44_11[1] = { - {119, 12}, -}; -static const arc arcs_44_12[2] = { - {123, 4}, - {0, 12}, -}; -static state states_44[13] = { - {1, arcs_44_0}, - {1, arcs_44_1}, - {1, arcs_44_2}, - {2, arcs_44_3}, - {1, arcs_44_4}, - {1, arcs_44_5}, - {1, arcs_44_6}, - {1, arcs_44_7}, - {1, arcs_44_8}, - {4, arcs_44_9}, - {1, arcs_44_10}, - {1, arcs_44_11}, - {2, arcs_44_12}, -}; -static const arc arcs_45_0[1] = { - {34, 1}, -}; -static const arc arcs_45_1[1] = { - {125, 2}, -}; -static const arc arcs_45_2[2] = { - {65, 1}, - {57, 3}, -}; -static const arc arcs_45_3[2] = { - {59, 4}, - {119, 5}, -}; -static const arc arcs_45_4[1] = { - {119, 5}, -}; -static const arc arcs_45_5[1] = { - {0, 5}, -}; -static state states_45[6] = { - {1, arcs_45_0}, - {1, arcs_45_1}, - {2, arcs_45_2}, - {2, arcs_45_3}, - {1, arcs_45_4}, - {1, arcs_45_5}, -}; -static const arc arcs_46_0[1] = { - {58, 1}, -}; -static const arc arcs_46_1[2] = { - {111, 2}, - {0, 1}, -}; -static const arc arcs_46_2[1] = { - {126, 3}, -}; -static const arc arcs_46_3[1] = { - {0, 3}, -}; -static state states_46[4] = { - {1, arcs_46_0}, - {2, arcs_46_1}, - {1, arcs_46_2}, - {1, arcs_46_3}, -}; -static const arc arcs_47_0[1] = { - {127, 1}, -}; -static const arc arcs_47_1[2] = { - {58, 2}, - {0, 1}, -}; -static const arc arcs_47_2[2] = { - {111, 3}, - {0, 2}, -}; -static const arc arcs_47_3[1] = { - {40, 4}, -}; -static const arc arcs_47_4[1] = { - {0, 4}, -}; -static state states_47[5] = { - {1, arcs_47_0}, - {2, arcs_47_1}, - {2, arcs_47_2}, - {1, arcs_47_3}, - {1, arcs_47_4}, -}; -static const arc arcs_48_0[2] = { - {2, 1}, - {4, 2}, -}; -static const arc arcs_48_1[1] = { - {128, 3}, -}; -static const arc arcs_48_2[1] = { - {0, 2}, -}; -static const arc arcs_48_3[1] = { - {45, 4}, -}; -static const arc arcs_48_4[2] = { - {129, 2}, - {45, 4}, -}; -static state states_48[5] = { - {2, arcs_48_0}, - {1, arcs_48_1}, - {1, arcs_48_2}, - {1, arcs_48_3}, - {2, arcs_48_4}, -}; -static const arc arcs_49_0[1] = { - {58, 1}, -}; -static const arc arcs_49_1[2] = { - {130, 2}, - {0, 1}, -}; -static const arc arcs_49_2[1] = { - {58, 3}, -}; -static const arc arcs_49_3[1] = { - {0, 3}, -}; -static state states_49[4] = { - {1, arcs_49_0}, - {2, arcs_49_1}, - {1, arcs_49_2}, - {1, arcs_49_3}, -}; -static const arc arcs_50_0[2] = { - {131, 1}, - {132, 2}, -}; -static const arc arcs_50_1[1] = { - {0, 1}, -}; -static const arc arcs_50_2[2] = { - {24, 3}, - {0, 2}, -}; -static const arc arcs_50_3[1] = { - {132, 4}, -}; -static const arc arcs_50_4[1] = { - {121, 5}, -}; -static const arc arcs_50_5[1] = { - {58, 1}, -}; -static state states_50[6] = { - {2, arcs_50_0}, - {1, arcs_50_1}, - {2, arcs_50_2}, - {1, arcs_50_3}, - {1, arcs_50_4}, - {1, arcs_50_5}, -}; -static const arc arcs_51_0[2] = { - {134, 1}, - {132, 1}, -}; -static const arc arcs_51_1[1] = { - {0, 1}, -}; -static state states_51[2] = { - {2, arcs_51_0}, - {1, arcs_51_1}, -}; -static const arc arcs_52_0[1] = { - {26, 1}, -}; -static const arc arcs_52_1[2] = { - {57, 2}, - {68, 3}, -}; -static const arc arcs_52_2[1] = { - {58, 4}, -}; -static const arc arcs_52_3[1] = { - {57, 2}, -}; -static const arc arcs_52_4[1] = { - {0, 4}, -}; -static state states_52[5] = { - {1, arcs_52_0}, - {2, arcs_52_1}, - {1, arcs_52_2}, - {1, arcs_52_3}, - {1, arcs_52_4}, -}; -static const arc arcs_53_0[1] = { - {26, 1}, -}; -static const arc arcs_53_1[2] = { - {57, 2}, - {68, 3}, -}; -static const arc arcs_53_2[1] = { - {133, 4}, -}; -static const arc arcs_53_3[1] = { - {57, 2}, -}; -static const arc arcs_53_4[1] = { - {0, 4}, -}; -static state states_53[5] = { - {1, arcs_53_0}, - {2, arcs_53_1}, - {1, arcs_53_2}, - {1, arcs_53_3}, - {1, arcs_53_4}, -}; -static const arc arcs_54_0[1] = { - {135, 1}, -}; -static const arc arcs_54_1[2] = { - {136, 0}, - {0, 1}, -}; -static state states_54[2] = { - {1, arcs_54_0}, - {2, arcs_54_1}, -}; -static const arc arcs_55_0[1] = { - {137, 1}, -}; -static const arc arcs_55_1[2] = { - {138, 0}, - {0, 1}, -}; -static state states_55[2] = { - {1, arcs_55_0}, - {2, arcs_55_1}, -}; -static const arc arcs_56_0[2] = { - {28, 1}, - {139, 2}, -}; -static const arc arcs_56_1[1] = { - {137, 2}, -}; -static const arc arcs_56_2[1] = { - {0, 2}, -}; -static state states_56[3] = { - {2, arcs_56_0}, - {1, arcs_56_1}, - {1, arcs_56_2}, -}; -static const arc arcs_57_0[1] = { - {126, 1}, -}; -static const arc arcs_57_1[2] = { - {140, 0}, - {0, 1}, -}; -static state states_57[2] = { - {1, arcs_57_0}, - {2, arcs_57_1}, -}; -static const arc arcs_58_0[10] = { - {141, 1}, - {142, 1}, - {143, 1}, - {141, 1}, - {144, 1}, - {145, 1}, - {146, 1}, - {122, 1}, - {147, 2}, - {28, 3}, -}; -static const arc arcs_58_1[1] = { - {0, 1}, -}; -static const arc arcs_58_2[2] = { - {28, 1}, - {0, 2}, -}; -static const arc arcs_58_3[1] = { - {122, 1}, -}; -static state states_58[4] = { - {10, arcs_58_0}, - {1, arcs_58_1}, - {2, arcs_58_2}, - {1, arcs_58_3}, -}; -static const arc arcs_59_0[1] = { - {6, 1}, -}; -static const arc arcs_59_1[1] = { - {126, 2}, -}; -static const arc arcs_59_2[1] = { - {0, 2}, -}; -static state states_59[3] = { - {1, arcs_59_0}, - {1, arcs_59_1}, - {1, arcs_59_2}, -}; -static const arc arcs_60_0[1] = { - {148, 1}, -}; -static const arc arcs_60_1[2] = { - {149, 0}, - {0, 1}, -}; -static state states_60[2] = { - {1, arcs_60_0}, - {2, arcs_60_1}, -}; -static const arc arcs_61_0[1] = { - {150, 1}, -}; -static const arc arcs_61_1[2] = { - {151, 0}, - {0, 1}, -}; -static state states_61[2] = { - {1, arcs_61_0}, - {2, arcs_61_1}, -}; -static const arc arcs_62_0[1] = { - {152, 1}, -}; -static const arc arcs_62_1[2] = { - {153, 0}, - {0, 1}, -}; -static state states_62[2] = { - {1, arcs_62_0}, - {2, arcs_62_1}, -}; -static const arc arcs_63_0[1] = { - {154, 1}, -}; -static const arc arcs_63_1[3] = { - {155, 0}, - {156, 0}, - {0, 1}, -}; -static state states_63[2] = { - {1, arcs_63_0}, - {3, arcs_63_1}, -}; -static const arc arcs_64_0[1] = { - {157, 1}, -}; -static const arc arcs_64_1[3] = { - {7, 0}, - {8, 0}, - {0, 1}, -}; -static state states_64[2] = { - {1, arcs_64_0}, - {3, arcs_64_1}, -}; -static const arc arcs_65_0[1] = { - {158, 1}, -}; -static const arc arcs_65_1[6] = { - {159, 0}, - {6, 0}, - {67, 0}, - {160, 0}, - {10, 0}, - {0, 1}, -}; -static state states_65[2] = { - {1, arcs_65_0}, - {6, arcs_65_1}, -}; -static const arc arcs_66_0[4] = { - {7, 1}, - {8, 1}, - {37, 1}, - {161, 2}, -}; -static const arc arcs_66_1[1] = { - {158, 2}, -}; -static const arc arcs_66_2[1] = { - {0, 2}, -}; -static state states_66[3] = { - {4, arcs_66_0}, - {1, arcs_66_1}, - {1, arcs_66_2}, -}; -static const arc arcs_67_0[1] = { - {162, 1}, -}; -static const arc arcs_67_1[2] = { - {63, 2}, - {0, 1}, -}; -static const arc arcs_67_2[1] = { - {158, 3}, -}; -static const arc arcs_67_3[1] = { - {0, 3}, -}; -static state states_67[4] = { - {1, arcs_67_0}, - {2, arcs_67_1}, - {1, arcs_67_2}, - {1, arcs_67_3}, -}; -static const arc arcs_68_0[2] = { - {39, 1}, - {163, 2}, -}; -static const arc arcs_68_1[1] = { - {163, 2}, -}; -static const arc arcs_68_2[2] = { - {164, 2}, - {0, 2}, -}; -static state states_68[3] = { - {2, arcs_68_0}, - {1, arcs_68_1}, - {2, arcs_68_2}, -}; -static const arc arcs_69_0[10] = { - {5, 1}, - {9, 2}, - {11, 2}, - {12, 2}, - {13, 2}, - {14, 3}, - {36, 4}, - {40, 2}, - {41, 2}, - {42, 5}, -}; -static const arc arcs_69_1[3] = { - {61, 2}, - {165, 6}, - {83, 6}, -}; -static const arc arcs_69_2[1] = { - {0, 2}, -}; -static const arc arcs_69_3[2] = { - {166, 2}, - {165, 7}, -}; -static const arc arcs_69_4[2] = { - {167, 2}, - {168, 8}, -}; -static const arc arcs_69_5[2] = { - {42, 5}, - {0, 5}, -}; -static const arc arcs_69_6[1] = { - {61, 2}, -}; -static const arc arcs_69_7[1] = { - {166, 2}, -}; -static const arc arcs_69_8[1] = { - {167, 2}, -}; -static state states_69[9] = { - {10, arcs_69_0}, - {3, arcs_69_1}, - {1, arcs_69_2}, - {2, arcs_69_3}, - {2, arcs_69_4}, - {2, arcs_69_5}, - {1, arcs_69_6}, - {1, arcs_69_7}, - {1, arcs_69_8}, -}; -static const arc arcs_70_0[2] = { - {49, 1}, - {84, 1}, -}; -static const arc arcs_70_1[3] = { - {65, 2}, - {169, 3}, - {0, 1}, -}; -static const arc arcs_70_2[3] = { - {49, 4}, - {84, 4}, - {0, 2}, -}; -static const arc arcs_70_3[1] = { - {0, 3}, -}; -static const arc arcs_70_4[2] = { - {65, 2}, - {0, 4}, -}; -static state states_70[5] = { - {2, arcs_70_0}, - {3, arcs_70_1}, - {3, arcs_70_2}, - {1, arcs_70_3}, - {2, arcs_70_4}, -}; -static const arc arcs_71_0[3] = { - {5, 1}, - {107, 2}, - {14, 3}, -}; -static const arc arcs_71_1[2] = { - {61, 4}, - {170, 5}, -}; -static const arc arcs_71_2[1] = { - {40, 4}, -}; -static const arc arcs_71_3[1] = { - {171, 6}, -}; -static const arc arcs_71_4[1] = { - {0, 4}, -}; -static const arc arcs_71_5[1] = { - {61, 4}, -}; -static const arc arcs_71_6[1] = { - {166, 4}, -}; -static state states_71[7] = { - {3, arcs_71_0}, - {2, arcs_71_1}, - {1, arcs_71_2}, - {1, arcs_71_3}, - {1, arcs_71_4}, - {1, arcs_71_5}, - {1, arcs_71_6}, -}; -static const arc arcs_72_0[1] = { - {172, 1}, -}; -static const arc arcs_72_1[2] = { - {65, 2}, - {0, 1}, -}; -static const arc arcs_72_2[2] = { - {172, 1}, - {0, 2}, -}; -static state states_72[3] = { - {1, arcs_72_0}, - {2, arcs_72_1}, - {2, arcs_72_2}, -}; -static const arc arcs_73_0[2] = { - {57, 1}, - {58, 2}, -}; -static const arc arcs_73_1[3] = { - {173, 3}, - {58, 4}, - {0, 1}, -}; -static const arc arcs_73_2[2] = { - {57, 1}, - {0, 2}, -}; -static const arc arcs_73_3[1] = { - {0, 3}, -}; -static const arc arcs_73_4[2] = { - {173, 3}, - {0, 4}, -}; -static state states_73[5] = { - {2, arcs_73_0}, - {3, arcs_73_1}, - {2, arcs_73_2}, - {1, arcs_73_3}, - {2, arcs_73_4}, -}; -static const arc arcs_74_0[1] = { - {57, 1}, -}; -static const arc arcs_74_1[2] = { - {58, 2}, - {0, 1}, -}; -static const arc arcs_74_2[1] = { - {0, 2}, -}; -static state states_74[3] = { - {1, arcs_74_0}, - {2, arcs_74_1}, - {1, arcs_74_2}, -}; -static const arc arcs_75_0[2] = { - {126, 1}, - {84, 1}, -}; -static const arc arcs_75_1[2] = { - {65, 2}, - {0, 1}, -}; -static const arc arcs_75_2[3] = { - {126, 1}, - {84, 1}, - {0, 2}, -}; -static state states_75[3] = { - {2, arcs_75_0}, - {2, arcs_75_1}, - {3, arcs_75_2}, -}; -static const arc arcs_76_0[1] = { - {58, 1}, -}; -static const arc arcs_76_1[2] = { - {65, 2}, - {0, 1}, -}; -static const arc arcs_76_2[2] = { - {58, 1}, - {0, 2}, -}; -static state states_76[3] = { - {1, arcs_76_0}, - {2, arcs_76_1}, - {2, arcs_76_2}, -}; -static const arc arcs_77_0[3] = { - {63, 1}, - {84, 2}, - {58, 3}, -}; -static const arc arcs_77_1[1] = { - {126, 4}, -}; -static const arc arcs_77_2[3] = { - {65, 5}, - {169, 6}, - {0, 2}, -}; -static const arc arcs_77_3[4] = { - {65, 5}, - {57, 7}, - {169, 6}, - {0, 3}, -}; -static const arc arcs_77_4[3] = { - {65, 8}, - {169, 6}, - {0, 4}, -}; -static const arc arcs_77_5[3] = { - {84, 9}, - {58, 9}, - {0, 5}, -}; -static const arc arcs_77_6[1] = { - {0, 6}, -}; -static const arc arcs_77_7[1] = { - {58, 4}, -}; -static const arc arcs_77_8[3] = { - {63, 10}, - {58, 11}, - {0, 8}, -}; -static const arc arcs_77_9[2] = { - {65, 5}, - {0, 9}, -}; -static const arc arcs_77_10[1] = { - {126, 12}, -}; -static const arc arcs_77_11[1] = { - {57, 13}, -}; -static const arc arcs_77_12[2] = { - {65, 8}, - {0, 12}, -}; -static const arc arcs_77_13[1] = { - {58, 12}, -}; -static state states_77[14] = { - {3, arcs_77_0}, - {1, arcs_77_1}, - {3, arcs_77_2}, - {4, arcs_77_3}, - {3, arcs_77_4}, - {3, arcs_77_5}, - {1, arcs_77_6}, - {1, arcs_77_7}, - {3, arcs_77_8}, - {2, arcs_77_9}, - {1, arcs_77_10}, - {1, arcs_77_11}, - {2, arcs_77_12}, - {1, arcs_77_13}, -}; -static const arc arcs_78_0[1] = { - {17, 1}, -}; -static const arc arcs_78_1[1] = { - {40, 2}, -}; -static const arc arcs_78_2[2] = { - {5, 3}, - {57, 4}, -}; -static const arc arcs_78_3[2] = { - {61, 5}, - {170, 6}, -}; -static const arc arcs_78_4[1] = { - {119, 7}, -}; -static const arc arcs_78_5[1] = { - {57, 4}, -}; -static const arc arcs_78_6[1] = { - {61, 5}, -}; -static const arc arcs_78_7[1] = { - {0, 7}, -}; -static state states_78[8] = { - {1, arcs_78_0}, - {1, arcs_78_1}, - {2, arcs_78_2}, - {2, arcs_78_3}, - {1, arcs_78_4}, - {1, arcs_78_5}, - {1, arcs_78_6}, - {1, arcs_78_7}, -}; -static const arc arcs_79_0[1] = { - {174, 1}, -}; -static const arc arcs_79_1[2] = { - {65, 2}, - {0, 1}, -}; -static const arc arcs_79_2[2] = { - {174, 1}, - {0, 2}, -}; -static state states_79[3] = { - {1, arcs_79_0}, - {2, arcs_79_1}, - {2, arcs_79_2}, -}; -static const arc arcs_80_0[3] = { - {6, 1}, - {63, 1}, - {58, 2}, -}; -static const arc arcs_80_1[1] = { - {58, 3}, -}; -static const arc arcs_80_2[4] = { - {130, 1}, - {66, 1}, - {169, 3}, - {0, 2}, -}; -static const arc arcs_80_3[1] = { - {0, 3}, -}; -static state states_80[4] = { - {3, arcs_80_0}, - {1, arcs_80_1}, - {4, arcs_80_2}, - {1, arcs_80_3}, -}; -static const arc arcs_81_0[2] = { - {169, 1}, - {176, 1}, -}; -static const arc arcs_81_1[1] = { - {0, 1}, -}; -static state states_81[2] = { - {2, arcs_81_0}, - {1, arcs_81_1}, -}; -static const arc arcs_82_0[1] = { - {21, 1}, -}; -static const arc arcs_82_1[1] = { - {98, 2}, -}; -static const arc arcs_82_2[1] = { - {122, 3}, -}; -static const arc arcs_82_3[1] = { - {132, 4}, -}; -static const arc arcs_82_4[2] = { - {175, 5}, - {0, 4}, -}; -static const arc arcs_82_5[1] = { - {0, 5}, -}; -static state states_82[6] = { - {1, arcs_82_0}, - {1, arcs_82_1}, - {1, arcs_82_2}, - {1, arcs_82_3}, - {2, arcs_82_4}, - {1, arcs_82_5}, -}; -static const arc arcs_83_0[2] = { - {38, 1}, - {177, 2}, -}; -static const arc arcs_83_1[1] = { - {177, 2}, -}; -static const arc arcs_83_2[1] = { - {0, 2}, -}; -static state states_83[3] = { - {2, arcs_83_0}, - {1, arcs_83_1}, - {1, arcs_83_2}, -}; -static const arc arcs_84_0[1] = { - {24, 1}, -}; -static const arc arcs_84_1[1] = { - {133, 2}, -}; -static const arc arcs_84_2[2] = { - {175, 3}, - {0, 2}, -}; -static const arc arcs_84_3[1] = { - {0, 3}, -}; -static state states_84[4] = { - {1, arcs_84_0}, - {1, arcs_84_1}, - {2, arcs_84_2}, - {1, arcs_84_3}, -}; -static const arc arcs_85_0[1] = { - {40, 1}, -}; -static const arc arcs_85_1[1] = { - {0, 1}, -}; -static state states_85[2] = { - {1, arcs_85_0}, - {1, arcs_85_1}, -}; -static const arc arcs_86_0[1] = { - {35, 1}, -}; -static const arc arcs_86_1[2] = { - {179, 2}, - {0, 1}, -}; -static const arc arcs_86_2[1] = { - {0, 2}, -}; -static state states_86[3] = { - {1, arcs_86_0}, - {2, arcs_86_1}, - {1, arcs_86_2}, -}; -static const arc arcs_87_0[2] = { - {22, 1}, - {80, 2}, -}; -static const arc arcs_87_1[1] = { - {58, 2}, -}; -static const arc arcs_87_2[1] = { - {0, 2}, -}; -static state states_87[3] = { - {2, arcs_87_0}, - {1, arcs_87_1}, - {1, arcs_87_2}, -}; -static const arc arcs_88_0[2] = { - {2, 1}, - {4, 2}, -}; -static const arc arcs_88_1[2] = { - {128, 3}, - {59, 4}, -}; -static const arc arcs_88_2[1] = { - {0, 2}, -}; -static const arc arcs_88_3[1] = { - {45, 5}, -}; -static const arc arcs_88_4[1] = { - {2, 6}, -}; -static const arc arcs_88_5[2] = { - {129, 2}, - {45, 5}, -}; -static const arc arcs_88_6[1] = { - {128, 3}, -}; -static state states_88[7] = { - {2, arcs_88_0}, - {2, arcs_88_1}, - {1, arcs_88_2}, - {1, arcs_88_3}, - {1, arcs_88_4}, - {2, arcs_88_5}, - {1, arcs_88_6}, -}; -static const arc arcs_89_0[1] = { - {181, 1}, -}; -static const arc arcs_89_1[2] = { - {44, 2}, - {2, 1}, -}; -static const arc arcs_89_2[1] = { - {0, 2}, -}; -static state states_89[3] = { - {1, arcs_89_0}, - {2, arcs_89_1}, - {1, arcs_89_2}, -}; -static const arc arcs_90_0[1] = { - {5, 1}, -}; -static const arc arcs_90_1[2] = { - {61, 2}, - {182, 3}, -}; -static const arc arcs_90_2[1] = { - {56, 4}, -}; -static const arc arcs_90_3[1] = { - {61, 2}, -}; -static const arc arcs_90_4[1] = { - {58, 5}, -}; -static const arc arcs_90_5[1] = { - {0, 5}, -}; -static state states_90[6] = { - {1, arcs_90_0}, - {2, arcs_90_1}, - {1, arcs_90_2}, - {1, arcs_90_3}, - {1, arcs_90_4}, - {1, arcs_90_5}, -}; -static const arc arcs_91_0[3] = { - {6, 1}, - {63, 2}, - {58, 3}, -}; -static const arc arcs_91_1[3] = { - {65, 4}, - {58, 5}, - {0, 1}, -}; -static const arc arcs_91_2[1] = { - {58, 6}, -}; -static const arc arcs_91_3[2] = { - {65, 7}, - {0, 3}, -}; -static const arc arcs_91_4[2] = { - {63, 2}, - {58, 5}, -}; -static const arc arcs_91_5[2] = { - {65, 4}, - {0, 5}, -}; -static const arc arcs_91_6[1] = { - {0, 6}, -}; -static const arc arcs_91_7[4] = { - {6, 8}, - {63, 2}, - {58, 3}, - {0, 7}, -}; -static const arc arcs_91_8[3] = { - {65, 9}, - {58, 10}, - {0, 8}, -}; -static const arc arcs_91_9[2] = { - {63, 2}, - {58, 10}, -}; -static const arc arcs_91_10[2] = { - {65, 9}, - {0, 10}, -}; -static state states_91[11] = { - {3, arcs_91_0}, - {3, arcs_91_1}, - {1, arcs_91_2}, - {2, arcs_91_3}, - {2, arcs_91_4}, - {2, arcs_91_5}, - {1, arcs_91_6}, - {4, arcs_91_7}, - {3, arcs_91_8}, - {2, arcs_91_9}, - {2, arcs_91_10}, -}; -static const dfa dfas[92] = { - {256, "single_input", 3, states_0, - "\344\377\377\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {257, "file_input", 2, states_1, - "\344\377\377\377\377\027\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {258, "eval_input", 3, states_2, - "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {259, "decorator", 4, states_3, - "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {260, "decorators", 2, states_4, - "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {261, "decorated", 3, states_5, - "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {262, "async_funcdef", 3, states_6, - "\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {263, "funcdef", 9, states_7, - "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {264, "parameters", 4, states_8, - "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {265, "typedargslist", 42, states_9, - "\100\000\000\000\000\001\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {266, "tfpdef", 4, states_10, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {267, "varargslist", 34, states_11, - "\100\000\000\000\000\001\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {268, "vfpdef", 2, states_12, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {269, "stmt", 2, states_13, - "\340\377\377\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {270, "simple_stmt", 4, states_14, - "\340\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {271, "small_stmt", 2, states_15, - "\340\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {272, "expr_stmt", 6, states_16, - "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {273, "annassign", 5, states_17, - "\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {274, "testlist_star_expr", 3, states_18, - "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {275, "augassign", 2, states_19, - "\000\000\000\000\000\000\000\000\000\000\340\377\003\000\000\000\000\000\000\000\000\000\000"}, - {276, "del_stmt", 3, states_20, - "\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {277, "pass_stmt", 2, states_21, - "\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {278, "flow_stmt", 2, states_22, - "\000\000\005\300\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {279, "break_stmt", 2, states_23, - "\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {280, "continue_stmt", 2, states_24, - "\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {281, "return_stmt", 3, states_25, - "\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {282, "yield_stmt", 2, states_26, - "\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {283, "raise_stmt", 5, states_27, - "\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {284, "import_stmt", 2, states_28, - "\000\000\100\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {285, "import_name", 3, states_29, - "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {286, "import_from", 8, states_30, - "\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {287, "import_as_name", 4, states_31, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {288, "dotted_as_name", 4, states_32, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {289, "import_as_names", 3, states_33, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {290, "dotted_as_names", 2, states_34, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {291, "dotted_name", 2, states_35, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {292, "global_stmt", 3, states_36, - "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {293, "nonlocal_stmt", 3, states_37, - "\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {294, "assert_stmt", 5, states_38, - "\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {295, "compound_stmt", 2, states_39, - "\000\004\052\001\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {296, "async_stmt", 3, states_40, - "\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {297, "if_stmt", 8, states_41, - "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {298, "while_stmt", 8, states_42, - "\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {299, "for_stmt", 11, states_43, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {300, "try_stmt", 13, states_44, - "\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {301, "with_stmt", 6, states_45, - "\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {302, "with_item", 4, states_46, - "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {303, "except_clause", 5, states_47, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000"}, - {304, "suite", 5, states_48, - "\344\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {305, "namedexpr_test", 4, states_49, - "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {306, "test", 6, states_50, - "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {307, "test_nocond", 2, states_51, - "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {308, "lambdef", 5, states_52, - "\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {309, "lambdef_nocond", 5, states_53, - "\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {310, "or_test", 2, states_54, - "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {311, "and_test", 2, states_55, - "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {312, "not_test", 3, states_56, - "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {313, "comparison", 2, states_57, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {314, "comp_op", 4, states_58, - "\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\004\000\340\017\000\000\000\000"}, - {315, "star_expr", 3, states_59, - "\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {316, "expr", 2, states_60, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {317, "xor_expr", 2, states_61, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {318, "and_expr", 2, states_62, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {319, "shift_expr", 2, states_63, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {320, "arith_expr", 2, states_64, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {321, "term", 2, states_65, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {322, "factor", 3, states_66, - "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {323, "power", 4, states_67, - "\040\172\000\000\220\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {324, "atom_expr", 3, states_68, - "\040\172\000\000\220\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {325, "atom", 9, states_69, - "\040\172\000\000\020\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {326, "testlist_comp", 5, states_70, - "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {327, "trailer", 7, states_71, - "\040\100\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, - {328, "subscriptlist", 3, states_72, - "\240\173\000\024\260\007\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {329, "subscript", 5, states_73, - "\240\173\000\024\260\007\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {330, "sliceop", 3, states_74, - "\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {331, "exprlist", 3, states_75, - "\340\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {332, "testlist", 3, states_76, - "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {333, "dictorsetmaker", 14, states_77, - "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {334, "classdef", 8, states_78, - "\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {335, "arglist", 3, states_79, - "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {336, "argument", 4, states_80, - "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {337, "comp_iter", 2, states_81, - "\000\000\040\001\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {338, "sync_comp_for", 6, states_82, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {339, "comp_for", 3, states_83, - "\000\000\040\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {340, "comp_if", 4, states_84, - "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {341, "encoding_decl", 2, states_85, - "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {342, "yield_expr", 3, states_86, - "\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {343, "yield_arg", 3, states_87, - "\340\173\100\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {344, "func_body_suite", 7, states_88, - "\344\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {345, "func_type_input", 3, states_89, - "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {346, "func_type", 6, states_90, - "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {347, "typelist", 11, states_91, - "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, -}; -static const label labels[183] = { - {0, "EMPTY"}, - {256, 0}, - {4, 0}, - {295, 0}, - {270, 0}, - {7, 0}, - {16, 0}, - {14, 0}, - {15, 0}, - {52, 0}, - {49, 0}, - {1, "False"}, - {1, "None"}, - {1, "True"}, - {9, 0}, - {1, "assert"}, - {1, "break"}, - {1, "class"}, - {1, "continue"}, - {1, "def"}, - {1, "del"}, - {1, "for"}, - {1, "from"}, - {1, "global"}, - {1, "if"}, - {1, "import"}, - {1, "lambda"}, - {1, "nonlocal"}, - {1, "not"}, - {1, "pass"}, - {1, "raise"}, - {1, "return"}, - {1, "try"}, - {1, "while"}, - {1, "with"}, - {1, "yield"}, - {25, 0}, - {31, 0}, - {56, 0}, - {55, 0}, - {1, 0}, - {2, 0}, - {3, 0}, - {257, 0}, - {0, 0}, - {269, 0}, - {258, 0}, - {332, 0}, - {259, 0}, - {305, 0}, - {260, 0}, - {261, 0}, - {262, 0}, - {334, 0}, - {263, 0}, - {264, 0}, - {51, 0}, - {11, 0}, - {306, 0}, - {58, 0}, - {344, 0}, - {8, 0}, - {265, 0}, - {35, 0}, - {266, 0}, - {12, 0}, - {22, 0}, - {17, 0}, - {267, 0}, - {268, 0}, - {271, 0}, - {13, 0}, - {294, 0}, - {276, 0}, - {272, 0}, - {278, 0}, - {292, 0}, - {284, 0}, - {293, 0}, - {277, 0}, - {274, 0}, - {273, 0}, - {275, 0}, - {342, 0}, - {315, 0}, - {40, 0}, - {41, 0}, - {46, 0}, - {38, 0}, - {36, 0}, - {37, 0}, - {48, 0}, - {39, 0}, - {44, 0}, - {45, 0}, - {50, 0}, - {43, 0}, - {42, 0}, - {331, 0}, - {279, 0}, - {280, 0}, - {283, 0}, - {281, 0}, - {282, 0}, - {286, 0}, - {285, 0}, - {290, 0}, - {23, 0}, - {291, 0}, - {289, 0}, - {287, 0}, - {1, "as"}, - {288, 0}, - {296, 0}, - {299, 0}, - {297, 0}, - {300, 0}, - {298, 0}, - {301, 0}, - {304, 0}, - {1, "elif"}, - {1, "else"}, - {1, "in"}, - {1, "finally"}, - {303, 0}, - {302, 0}, - {316, 0}, - {1, "except"}, - {5, 0}, - {6, 0}, - {53, 0}, - {308, 0}, - {310, 0}, - {307, 0}, - {309, 0}, - {311, 0}, - {1, "or"}, - {312, 0}, - {1, "and"}, - {313, 0}, - {314, 0}, - {28, 0}, - {20, 0}, - {29, 0}, - {27, 0}, - {21, 0}, - {30, 0}, - {1, "is"}, - {317, 0}, - {18, 0}, - {318, 0}, - {32, 0}, - {319, 0}, - {19, 0}, - {320, 0}, - {33, 0}, - {34, 0}, - {321, 0}, - {322, 0}, - {24, 0}, - {47, 0}, - {323, 0}, - {324, 0}, - {325, 0}, - {327, 0}, - {326, 0}, - {10, 0}, - {26, 0}, - {333, 0}, - {339, 0}, - {335, 0}, - {328, 0}, - {329, 0}, - {330, 0}, - {336, 0}, - {337, 0}, - {340, 0}, - {338, 0}, - {341, 0}, - {343, 0}, - {345, 0}, - {346, 0}, - {347, 0}, -}; -Py_EXPORTED_SYMBOL grammar _PyParser_Grammar = { - 92, - dfas, - {183, labels}, - 256 -}; diff --git a/contrib/tools/python3/src/Python/hamt.c b/contrib/tools/python3/src/Python/hamt.c index 8801c5ea418..e272e8808fd 100644 --- a/contrib/tools/python3/src/Python/hamt.c +++ b/contrib/tools/python3/src/Python/hamt.c @@ -1,5 +1,6 @@ #include "Python.h" +#include "pycore_bitutils.h" // _Py_popcount32 #include "pycore_hamt.h" #include "pycore_object.h" // _PyObject_GC_TRACK() #include // offsetof() @@ -433,30 +434,10 @@ hamt_bitpos(int32_t hash, uint32_t shift) return (uint32_t)1 << hamt_mask(hash, shift); } -static inline uint32_t -hamt_bitcount(uint32_t i) -{ - /* We could use native popcount instruction but that would - require to either add configure flags to enable SSE4.2 - support or to detect it dynamically. Otherwise, we have - a risk of CPython not working properly on older hardware. - - In practice, there's no observable difference in - performance between using a popcount instruction or the - following fallback code. - - The algorithm is copied from: - https://graphics.stanford.edu/~seander/bithacks.html - */ - i = i - ((i >> 1) & 0x55555555); - i = (i & 0x33333333) + ((i >> 2) & 0x33333333); - return (((i + (i >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; -} - static inline uint32_t hamt_bitindex(uint32_t bitmap, uint32_t bit) { - return hamt_bitcount(bitmap & (bit - 1)); + return (uint32_t)_Py_popcount32(bitmap & (bit - 1)); } @@ -820,7 +801,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, else { /* There was no key before with the same (shift,hash). */ - uint32_t n = hamt_bitcount(self->b_bitmap); + uint32_t n = (uint32_t)_Py_popcount32(self->b_bitmap); if (n >= 16) { /* When we have a situation where we want to store more diff --git a/contrib/tools/python3/src/Python/import.c b/contrib/tools/python3/src/Python/import.c index e4dbf4b0d8c..bd33fa184ab 100644 --- a/contrib/tools/python3/src/Python/import.c +++ b/contrib/tools/python3/src/Python/import.c @@ -2,8 +2,7 @@ #include "Python.h" -#include "Python-ast.h" -#undef Yield /* undefine macro conflicting with */ +#include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" #include "pycore_pyerrors.h" #include "pycore_pyhash.h" @@ -51,43 +50,6 @@ module _imp /* Initialize things */ -PyStatus -_PyImportHooks_Init(PyThreadState *tstate) -{ - PyObject *v, *path_hooks = NULL; - int err = 0; - - /* adding sys.path_hooks and sys.path_importer_cache */ - v = PyList_New(0); - if (v == NULL) - goto error; - err = PySys_SetObject("meta_path", v); - Py_DECREF(v); - if (err) - goto error; - v = PyDict_New(); - if (v == NULL) - goto error; - err = PySys_SetObject("path_importer_cache", v); - Py_DECREF(v); - if (err) - goto error; - path_hooks = PyList_New(0); - if (path_hooks == NULL) - goto error; - err = PySys_SetObject("path_hooks", path_hooks); - if (err) { - goto error; - } - Py_DECREF(path_hooks); - return _PyStatus_OK(); - - error: - _PyErr_Print(tstate); - return _PyStatus_ERR("initializing sys.meta_path, sys.path_hooks, " - "or path_importer_cache failed"); -} - PyStatus _PyImportZip_Init(PyThreadState *tstate) { @@ -148,7 +110,7 @@ _PyImportZip_Init(PyThreadState *tstate) 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 = 0; +static PyThread_type_lock import_lock = NULL; static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID; static int import_lock_level = 0; @@ -171,7 +133,7 @@ _PyImport_AcquireLock(void) !PyThread_acquire_lock(import_lock, 0)) { PyThreadState *tstate = PyEval_SaveThread(); - PyThread_acquire_lock(import_lock, 1); + PyThread_acquire_lock(import_lock, WAIT_LOCK); PyEval_RestoreThread(tstate); } assert(import_lock_level == 0); @@ -197,33 +159,30 @@ _PyImport_ReleaseLock(void) } #ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child to ensure that newly +/* This function is called from PyOS_AfterFork_Child() to ensure that newly created child processes do not share locks with the parent. 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. */ - -void +PyStatus _PyImport_ReInitLock(void) { if (import_lock != NULL) { if (_PyThread_at_fork_reinit(&import_lock) < 0) { - _Py_FatalErrorFunc(__func__, "failed to create a new lock"); + return _PyStatus_ERR("failed to create a new lock"); } } + if (import_lock_level > 1) { /* Forked as a side effect of import */ unsigned long me = PyThread_get_thread_ident(); - /* The following could fail if the lock is already held, but forking as - a side-effect of an import is a) rare, b) nuts, and c) difficult to - do thanks to the lock only being held when doing individual module - locks per import. */ - PyThread_acquire_lock(import_lock, NOWAIT_LOCK); + PyThread_acquire_lock(import_lock, WAIT_LOCK); import_lock_thread = me; import_lock_level--; } else { import_lock_thread = PYTHREAD_INVALID_THREAD_ID; import_lock_level = 0; } + return _PyStatus_OK(); } #endif @@ -343,16 +302,16 @@ _PyImport_GetModuleId(struct _Py_Identifier *nameid) int _PyImport_SetModule(PyObject *name, PyObject *m) { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *modules = tstate->interp->modules; + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *modules = interp->modules; return PyObject_SetItem(modules, name, m); } int _PyImport_SetModuleString(const char *name, PyObject *m) { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *modules = tstate->interp->modules; + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *modules = interp->modules; return PyMapping_SetItemString(modules, name, m); } @@ -384,9 +343,8 @@ import_get_module(PyThreadState *tstate, PyObject *name) static int -import_ensure_initialized(PyThreadState *tstate, PyObject *mod, PyObject *name) +import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *name) { - PyInterpreterState *interp = tstate->interp; PyObject *spec; _Py_IDENTIFIER(_lock_unlock_module); @@ -412,233 +370,6 @@ import_ensure_initialized(PyThreadState *tstate, PyObject *mod, PyObject *name) } -/* List of names to clear in sys */ -static const char * const sys_deletes[] = { - "path", "argv", "ps1", "ps2", - "last_type", "last_value", "last_traceback", - "path_hooks", "path_importer_cache", "meta_path", - "__interactivehook__", - NULL -}; - -static const char * const sys_files[] = { - "stdin", "__stdin__", - "stdout", "__stdout__", - "stderr", "__stderr__", - NULL -}; - -/* Un-initialize things, as good as we can */ - -void -_PyImport_Cleanup(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - PyObject *modules = interp->modules; - if (modules == NULL) { - /* Already done */ - return; - } - - /* Delete some special variables first. These are common - places where user values hide and people complain when their - destructors fail. Since the modules containing them are - deleted *last* of all, they would come too late in the normal - destruction order. Sigh. */ - - /* XXX Perhaps these precautions are obsolete. Who knows? */ - - int verbose = _PyInterpreterState_GetConfig(interp)->verbose; - if (verbose) { - PySys_WriteStderr("# clear builtins._\n"); - } - if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) { - PyErr_WriteUnraisable(NULL); - } - - 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) { - PyErr_WriteUnraisable(NULL); - } - } - for (p = sys_files; *p != NULL; p+=2) { - if (verbose) { - PySys_WriteStderr("# restore sys.%s\n", *p); - } - PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict, - *(p+1)); - if (value == NULL) { - if (_PyErr_Occurred(tstate)) { - PyErr_WriteUnraisable(NULL); - } - value = Py_None; - } - if (PyDict_SetItemString(interp->sysdict, *p, value) < 0) { - PyErr_WriteUnraisable(NULL); - } - } - - /* We prepare a list which will receive (name, weakref) tuples of - modules when they are removed from sys.modules. The name is used - for diagnosis messages (in verbose mode), while the weakref helps - detect those modules which have been held alive. */ - PyObject *weaklist = PyList_New(0); - if (weaklist == NULL) { - PyErr_WriteUnraisable(NULL); - } - -#define STORE_MODULE_WEAKREF(name, mod) \ - if (weaklist != NULL) { \ - PyObject *wr = PyWeakref_NewRef(mod, NULL); \ - if (wr) { \ - PyObject *tup = PyTuple_Pack(2, name, wr); \ - if (!tup || PyList_Append(weaklist, tup) < 0) { \ - PyErr_WriteUnraisable(NULL); \ - } \ - Py_XDECREF(tup); \ - Py_DECREF(wr); \ - } \ - else { \ - PyErr_WriteUnraisable(NULL); \ - } \ - } -#define CLEAR_MODULE(name, mod) \ - if (PyModule_Check(mod)) { \ - if (verbose && PyUnicode_Check(name)) { \ - PySys_FormatStderr("# cleanup[2] removing %U\n", name); \ - } \ - STORE_MODULE_WEAKREF(name, mod); \ - if (PyObject_SetItem(modules, name, Py_None) < 0) { \ - PyErr_WriteUnraisable(NULL); \ - } \ - } - - /* Remove all modules from sys.modules, hoping that garbage collection - can reclaim most of them. */ - if (PyDict_CheckExact(modules)) { - Py_ssize_t pos = 0; - PyObject *key, *value; - while (PyDict_Next(modules, &pos, &key, &value)) { - CLEAR_MODULE(key, value); - } - } - else { - PyObject *iterator = PyObject_GetIter(modules); - if (iterator == NULL) { - PyErr_WriteUnraisable(NULL); - } - else { - PyObject *key; - while ((key = PyIter_Next(iterator))) { - PyObject *value = PyObject_GetItem(modules, key); - if (value == NULL) { - PyErr_WriteUnraisable(NULL); - continue; - } - CLEAR_MODULE(key, value); - Py_DECREF(value); - Py_DECREF(key); - } - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(NULL); - } - Py_DECREF(iterator); - } - } - - /* Clear the modules dict. */ - if (PyDict_CheckExact(modules)) { - PyDict_Clear(modules); - } - else { - _Py_IDENTIFIER(clear); - if (_PyObject_CallMethodIdNoArgs(modules, &PyId_clear) == NULL) { - PyErr_WriteUnraisable(NULL); - } - } - /* Restore the original builtins dict, to ensure that any - user data gets cleared. */ - PyObject *dict = PyDict_Copy(interp->builtins); - if (dict == NULL) { - PyErr_WriteUnraisable(NULL); - } - PyDict_Clear(interp->builtins); - if (PyDict_Update(interp->builtins, interp->builtins_copy)) { - _PyErr_Clear(tstate); - } - Py_XDECREF(dict); - /* Collect references */ - _PyGC_CollectNoFail(); - /* Dump GC stats before it's too late, since it uses the warnings - machinery. */ - _PyGC_DumpShutdownStats(tstate); - - /* Now, if there are any modules left alive, clear their globals to - minimize potential leaks. All C extension modules actually end - up here, since they are kept alive in the interpreter state. - - The special treatment of "builtins" here is because even - when it's not referenced as a module, its dictionary is - referenced by almost every module's __builtins__. Since - deleting a module clears its dictionary (even if there are - references left to it), we need to delete the "builtins" - module last. Likewise, we don't delete sys until the very - end because it is implicitly referenced (e.g. by print). */ - if (weaklist != NULL) { - Py_ssize_t i; - /* Since dict is ordered in CPython 3.6+, modules are saved in - importing order. First clear modules imported later. */ - for (i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) { - PyObject *tup = PyList_GET_ITEM(weaklist, i); - PyObject *name = PyTuple_GET_ITEM(tup, 0); - PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); - if (mod == Py_None) - continue; - assert(PyModule_Check(mod)); - dict = PyModule_GetDict(mod); - if (dict == interp->builtins || dict == interp->sysdict) - continue; - Py_INCREF(mod); - if (verbose && PyUnicode_Check(name)) { - PySys_FormatStderr("# cleanup[3] wiping %U\n", name); - } - _PyModule_Clear(mod); - Py_DECREF(mod); - } - Py_DECREF(weaklist); - } - - /* Next, delete sys and builtins (in that order) */ - if (verbose) { - PySys_FormatStderr("# cleanup[3] wiping sys\n"); - } - _PyModule_ClearDict(interp->sysdict); - if (verbose) { - PySys_FormatStderr("# cleanup[3] wiping builtins\n"); - } - _PyModule_ClearDict(interp->builtins); - - /* Clear module dict copies stored in the interpreter state */ - _PyInterpreterState_ClearModules(interp); - - /* Clear and delete the modules directory. Actual modules will - still be there only if imported during the execution of some - destructor. */ - interp->modules = NULL; - Py_DECREF(modules); - - /* Once more */ - _PyGC_CollectNoFail(); - -#undef CLEAR_MODULE -#undef STORE_MODULE_WEAKREF -} - - /* Helper for pythonrun.c -- return magic number and tag. */ long @@ -678,7 +409,7 @@ PyImport_GetMagicTag(void) 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 - _PyImport_FindExtensionObject(). + import_find_extension(). Modules which do support multiple initialization set their m_size field to a non-negative number (indicating the size of the @@ -712,7 +443,7 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, // 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) || def->m_size == -1) { + 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, @@ -793,10 +524,14 @@ import_find_extension(PyThreadState *tstate, PyObject *name, if (mod == NULL) return NULL; mdict = PyModule_GetDict(mod); - if (mdict == NULL) + if (mdict == NULL) { + Py_DECREF(mod); return NULL; - if (PyDict_Update(mdict, def->m_base.m_copy)) + } + if (PyDict_Update(mdict, def->m_base.m_copy)) { + Py_DECREF(mod); return NULL; + } } else { if (def->m_base.m_init == NULL) @@ -808,10 +543,10 @@ import_find_extension(PyThreadState *tstate, PyObject *name, Py_DECREF(mod); return NULL; } - Py_DECREF(mod); } if (_PyState_AddModule(tstate, mod, def) < 0) { PyMapping_DelItem(modules, name); + Py_DECREF(mod); return NULL; } @@ -827,27 +562,23 @@ PyObject * _PyImport_FindExtensionObject(PyObject *name, PyObject *filename) { PyThreadState *tstate = _PyThreadState_GET(); - return import_find_extension(tstate, name, filename); + PyObject *mod = import_find_extension(tstate, name, filename); + if (mod) { + PyObject *ref = PyWeakref_NewRef(mod, NULL); + Py_DECREF(mod); + if (ref == NULL) { + return NULL; + } + mod = PyWeakref_GetObject(ref); + Py_DECREF(ref); + } + return mod; /* borrowed reference */ } -PyObject * -_PyImport_FindBuiltin(PyThreadState *tstate, const char *name) -{ - PyObject *res, *nameobj; - nameobj = PyUnicode_InternFromString(name); - if (nameobj == NULL) - return NULL; - res = import_find_extension(tstate, nameobj, nameobj); - 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. - Because the former action is most common, THIS DOES NOT RETURN A - 'NEW' REFERENCE! */ + if not, create a new one and insert it in the modules dictionary. */ static PyObject * import_add_module(PyThreadState *tstate, PyObject *name) @@ -862,6 +593,7 @@ import_add_module(PyThreadState *tstate, PyObject *name) PyObject *m; if (PyDict_CheckExact(modules)) { m = PyDict_GetItemWithError(modules, name); + Py_XINCREF(m); } else { m = PyObject_GetItem(modules, name); @@ -877,6 +609,7 @@ import_add_module(PyThreadState *tstate, PyObject *name) if (m != NULL && PyModule_Check(m)) { return m; } + Py_XDECREF(m); m = PyModule_NewObject(name); if (m == NULL) return NULL; @@ -884,7 +617,6 @@ import_add_module(PyThreadState *tstate, PyObject *name) Py_DECREF(m); return NULL; } - Py_DECREF(m); /* Yes, it still exists, in modules! */ return m; } @@ -893,7 +625,17 @@ PyObject * PyImport_AddModuleObject(PyObject *name) { PyThreadState *tstate = _PyThreadState_GET(); - return import_add_module(tstate, name); + PyObject *mod = import_add_module(tstate, name); + if (mod) { + PyObject *ref = PyWeakref_NewRef(mod, NULL); + Py_DECREF(mod); + if (ref == NULL) { + return NULL; + } + mod = PyWeakref_GetObject(ref); + Py_DECREF(ref); + } + return mod; /* borrowed reference */ } @@ -1018,7 +760,7 @@ static PyObject * module_dict_for_exec(PyThreadState *tstate, PyObject *name) { _Py_IDENTIFIER(__builtins__); - PyObject *m, *d = NULL; + PyObject *m, *d; m = import_add_module(tstate, name); if (m == NULL) @@ -1026,17 +768,20 @@ module_dict_for_exec(PyThreadState *tstate, PyObject *name) /* 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); - if (_PyDict_GetItemIdWithError(d, &PyId___builtins__) == NULL) { - if (_PyErr_Occurred(tstate) || - _PyDict_SetItemId(d, &PyId___builtins__, - PyEval_GetBuiltins()) != 0) - { - remove_module(tstate, name); - return NULL; - } + int r = _PyDict_ContainsId(d, &PyId___builtins__); + if (r == 0) { + r = _PyDict_SetItemId(d, &PyId___builtins__, + PyEval_GetBuiltins()); + } + if (r < 0) { + remove_module(tstate, name); + Py_DECREF(m); + return NULL; } - return d; /* Return a borrowed reference. */ + Py_INCREF(d); + Py_DECREF(m); + return d; } static PyObject * @@ -1080,8 +825,10 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, } external = PyObject_GetAttrString(tstate->interp->importlib, "_bootstrap_external"); - if (external == NULL) + if (external == NULL) { + Py_DECREF(d); return NULL; + } res = _PyObject_CallMethodIdObjArgs(external, &PyId__fix_up_module, d, name, pathname, cpathname, NULL); @@ -1090,6 +837,7 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, Py_DECREF(res); res = exec_code_in_module(tstate, name, d, co); } + Py_DECREF(d); return res; } @@ -1183,8 +931,7 @@ is_builtin(PyObject *name) 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. - Returns a borrowed reference. */ + path_importer_cache. */ static PyObject * get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, @@ -1202,8 +949,10 @@ get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, return NULL; /* Shouldn't happen */ importer = PyDict_GetItemWithError(path_importer_cache, p); - if (importer != NULL || _PyErr_Occurred(tstate)) + if (importer != NULL || _PyErr_Occurred(tstate)) { + Py_XINCREF(importer); return importer; + } /* set path_importer_cache[p] to None to avoid recursion */ if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0) @@ -1223,13 +972,11 @@ get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, _PyErr_Clear(tstate); } if (importer == NULL) { - return Py_None; + Py_RETURN_NONE; } - if (importer != NULL) { - int err = PyDict_SetItem(path_importer_cache, p, importer); + if (PyDict_SetItem(path_importer_cache, p, importer) < 0) { Py_DECREF(importer); - if (err != 0) - return NULL; + return NULL; } return importer; } @@ -1238,96 +985,87 @@ PyObject * PyImport_GetImporter(PyObject *path) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL; - - path_importer_cache = PySys_GetObject("path_importer_cache"); - path_hooks = PySys_GetObject("path_hooks"); - if (path_importer_cache != NULL && path_hooks != NULL) { - importer = get_path_importer(tstate, path_importer_cache, - path_hooks, path); + 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; } - Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */ - return importer; + return get_path_importer(tstate, path_importer_cache, path_hooks, path); } -/*[clinic input] -_imp.create_builtin - - spec: object - / - -Create an extension module. -[clinic start generated code]*/ - -static PyObject * -_imp_create_builtin(PyObject *module, PyObject *spec) -/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ +static PyObject* +create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) { - PyThreadState *tstate = _PyThreadState_GET(); - struct _inittab *p; - PyObject *name; - const char *namestr; - PyObject *mod; - - name = PyObject_GetAttrString(spec, "name"); - if (name == NULL) { - return NULL; - } - - mod = _PyImport_FindExtensionObject(name, name); + PyObject *mod = import_find_extension(tstate, name, name); if (mod || _PyErr_Occurred(tstate)) { - Py_DECREF(name); - Py_XINCREF(mod); return mod; } - namestr = PyUnicode_AsUTF8(name); - if (namestr == NULL) { - Py_DECREF(name); - return NULL; - } - PyObject *modules = tstate->interp->modules; - for (p = PyImport_Inittab; p->name != NULL; p++) { - PyModuleDef *def; + 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_AddModule(namestr); - Py_DECREF(name); - return mod; + return PyImport_AddModuleObject(name); } + mod = (*p->initfunc)(); if (mod == NULL) { - Py_DECREF(name); return NULL; } + if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) { - Py_DECREF(name); return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec); - } else { + } + else { /* Remember pointer to module init function. */ - def = PyModule_GetDef(mod); + PyModuleDef *def = PyModule_GetDef(mod); if (def == NULL) { - Py_DECREF(name); return NULL; } + def->m_base.m_init = p->initfunc; if (_PyImport_FixupExtensionObject(mod, name, name, modules) < 0) { - Py_DECREF(name); return NULL; } - Py_DECREF(name); return mod; } } } - Py_DECREF(name); + + // not found Py_RETURN_NONE; } + +/*[clinic input] +_imp.create_builtin + + spec: object + / + +Create an extension module. +[clinic start generated code]*/ + +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; + } + + PyObject *mod = create_builtin(tstate, name, spec); + Py_DECREF(name); + return mod; +} + + /* Frozen modules */ static const struct _frozen * @@ -1440,10 +1178,12 @@ PyImport_ImportFrozenModuleObject(PyObject *name) d = PyModule_GetDict(m); l = PyList_New(0); if (l == NULL) { + Py_DECREF(m); goto err_return; } err = PyDict_SetItemString(d, "__path__", l); Py_DECREF(l); + Py_DECREF(m); if (err != 0) goto err_return; } @@ -1452,6 +1192,7 @@ PyImport_ImportFrozenModuleObject(PyObject *name) goto err_return; } m = exec_code_in_module(tstate, name, d, co); + Py_DECREF(d); if (m == NULL) { goto err_return; } @@ -1670,10 +1411,14 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level goto error; } - if (_PyDict_GetItemIdWithError(globals, &PyId___path__) == NULL) { + int haspath = _PyDict_ContainsId(globals, &PyId___path__); + if (haspath < 0) { + goto error; + } + if (!haspath) { Py_ssize_t dot; - if (_PyErr_Occurred(tstate) || PyUnicode_READY(package) < 0) { + if (PyUnicode_READY(package) < 0) { goto error; } @@ -1806,7 +1551,7 @@ PyImport_GetModule(PyObject *name) mod = import_get_module(tstate, name); if (mod != NULL && mod != Py_None) { - if (import_ensure_initialized(tstate, mod, name) < 0) { + if (import_ensure_initialized(tstate->interp, mod, name) < 0) { Py_DECREF(mod); remove_importlib_frames(tstate); return NULL; @@ -1870,7 +1615,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, } if (mod != NULL && mod != Py_None) { - if (import_ensure_initialized(tstate, mod, abs_name) < 0) { + if (import_ensure_initialized(tstate->interp, mod, abs_name) < 0) { goto error; } } @@ -2021,26 +1766,29 @@ PyImport_ReloadModule(PyObject *m) PyObject * PyImport_Import(PyObject *module_name) { + _Py_IDENTIFIER(__import__); + _Py_IDENTIFIER(__builtins__); + PyThreadState *tstate = _PyThreadState_GET(); - static PyObject *silly_list = NULL; - static PyObject *builtins_str = NULL; - static PyObject *import_str = NULL; PyObject *globals = NULL; PyObject *import = NULL; PyObject *builtins = NULL; PyObject *r = NULL; /* Initialize constant string objects */ - if (silly_list == NULL) { - import_str = PyUnicode_InternFromString("__import__"); - if (import_str == NULL) - return NULL; - builtins_str = PyUnicode_InternFromString("__builtins__"); - if (builtins_str == NULL) - return NULL; - silly_list = PyList_New(0); - if (silly_list == NULL) - return NULL; + PyObject *import_str = _PyUnicode_FromId(&PyId___import__); // borrowed ref + if (import_str == NULL) { + return NULL; + } + + PyObject *builtins_str = _PyUnicode_FromId(&PyId___builtins__); // borrowed ref + if (builtins_str == NULL) { + return NULL; + } + + PyObject *from_list = PyList_New(0); + if (from_list == NULL) { + goto err; } /* Get the builtins from current globals */ @@ -2055,8 +1803,9 @@ PyImport_Import(PyObject *module_name) /* No globals -- use standard builtins, and fake globals */ builtins = PyImport_ImportModuleLevel("builtins", NULL, NULL, NULL, 0); - if (builtins == NULL) - return NULL; + if (builtins == NULL) { + goto err; + } globals = Py_BuildValue("{OO}", builtins_str, builtins); if (globals == NULL) goto err; @@ -2078,7 +1827,7 @@ PyImport_Import(PyObject *module_name) Always use absolute import here. Calling for side-effect of import. */ r = PyObject_CallFunction(import, "OOOOi", module_name, globals, - globals, silly_list, 0, NULL); + globals, from_list, 0, NULL); if (r == NULL) goto err; Py_DECREF(r); @@ -2092,6 +1841,7 @@ PyImport_Import(PyObject *module_name) Py_XDECREF(globals); Py_XDECREF(builtins); Py_XDECREF(import); + Py_XDECREF(from_list); return r; } @@ -2148,7 +1898,6 @@ _imp_init_frozen_impl(PyObject *module, PyObject *name) { PyThreadState *tstate = _PyThreadState_GET(); int ret; - PyObject *m; ret = PyImport_ImportFrozenModuleObject(name); if (ret < 0) @@ -2156,9 +1905,7 @@ _imp_init_frozen_impl(PyObject *module, PyObject *name) if (ret == 0) { Py_RETURN_NONE; } - m = import_add_module(tstate, name); - Py_XINCREF(m); - return m; + return import_add_module(tstate, name); } /*[clinic input] @@ -2282,11 +2029,11 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) return NULL; } - mod = _PyImport_FindExtensionObject(name, path); + PyThreadState *tstate = _PyThreadState_GET(); + mod = import_find_extension(tstate, name, path); if (mod != NULL || PyErr_Occurred()) { Py_DECREF(name); Py_DECREF(path); - Py_XINCREF(mod); return mod; } @@ -2397,46 +2144,88 @@ static PyMethodDef imp_methods[] = { }; -static struct PyModuleDef impmodule = { +static int +imp_module_exec(PyObject *module) +{ + const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode; + PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1); + if (pyc_mode == NULL) { + return -1; + } + if (PyModule_AddObjectRef(module, "check_hash_based_pycs", pyc_mode) < 0) { + Py_DECREF(pyc_mode); + return -1; + } + Py_DECREF(pyc_mode); + + return 0; +} + + +static PyModuleDef_Slot imp_slots[] = { + {Py_mod_exec, imp_module_exec}, + {0, NULL} +}; + +static struct PyModuleDef imp_module = { PyModuleDef_HEAD_INIT, - "_imp", - doc_imp, - 0, - imp_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_imp", + .m_doc = doc_imp, + .m_size = 0, + .m_methods = imp_methods, + .m_slots = imp_slots, }; PyMODINIT_FUNC PyInit__imp(void) { - PyObject *m, *d; + return PyModuleDef_Init(&imp_module); +} - m = PyModule_Create(&impmodule); - if (m == NULL) { - goto failure; + +// 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; } - d = PyModule_GetDict(m); - if (d == NULL) { - goto failure; + + // 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; } - const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode; - PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1); - if (pyc_mode == NULL) { - goto failure; + // 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; } - if (PyDict_SetItemString(d, "check_hash_based_pycs", pyc_mode) < 0) { - Py_DECREF(pyc_mode); - goto failure; + 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; } - Py_DECREF(pyc_mode); + return mod; - return m; - failure: - Py_XDECREF(m); +error: + Py_XDECREF(name); return NULL; } diff --git a/contrib/tools/python3/src/Python/importdl.c b/contrib/tools/python3/src/Python/importdl.c index 134f6680c44..6d2554741f9 100644 --- a/contrib/tools/python3/src/Python/importdl.c +++ b/contrib/tools/python3/src/Python/importdl.c @@ -223,10 +223,9 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) def->m_base.m_init = p0; /* Remember the filename as the __file__ attribute */ - if (PyModule_AddObject(m, "__file__", path) < 0) + if (PyModule_AddObjectRef(m, "__file__", path) < 0) { PyErr_Clear(); /* Not important enough to report */ - else - Py_INCREF(path); + } PyObject *modules = PyImport_GetModuleDict(); if (_PyImport_FixupExtensionObject(m, name_unicode, path, modules) < 0) diff --git a/contrib/tools/python3/src/Python/importlib.h b/contrib/tools/python3/src/Python/importlib.h index 1fb877a7534..dd1a9f172c0 100644 --- a/contrib/tools/python3/src/Python/importlib.h +++ b/contrib/tools/python3/src/Python/importlib.h @@ -1,537 +1,561 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_bootstrap[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,64,0,0,0,115,194,1,0,0,100,0, - 90,0,100,1,97,1,100,2,100,3,132,0,90,2,100,4, - 100,5,132,0,90,3,105,0,90,4,105,0,90,5,71,0, - 100,6,100,7,132,0,100,7,101,6,131,3,90,7,71,0, - 100,8,100,9,132,0,100,9,131,2,90,8,71,0,100,10, - 100,11,132,0,100,11,131,2,90,9,71,0,100,12,100,13, - 132,0,100,13,131,2,90,10,100,14,100,15,132,0,90,11, - 100,16,100,17,132,0,90,12,100,18,100,19,132,0,90,13, - 100,20,100,21,156,1,100,22,100,23,132,2,90,14,100,24, - 100,25,132,0,90,15,100,26,100,27,132,0,90,16,100,28, - 100,29,132,0,90,17,100,30,100,31,132,0,90,18,71,0, - 100,32,100,33,132,0,100,33,131,2,90,19,100,1,100,1, - 100,34,156,2,100,35,100,36,132,2,90,20,100,94,100,37, - 100,38,132,1,90,21,100,39,100,40,156,1,100,41,100,42, - 132,2,90,22,100,43,100,44,132,0,90,23,100,45,100,46, - 132,0,90,24,100,47,100,48,132,0,90,25,100,49,100,50, - 132,0,90,26,100,51,100,52,132,0,90,27,100,53,100,54, - 132,0,90,28,71,0,100,55,100,56,132,0,100,56,131,2, - 90,29,71,0,100,57,100,58,132,0,100,58,131,2,90,30, - 71,0,100,59,100,60,132,0,100,60,131,2,90,31,100,61, - 100,62,132,0,90,32,100,63,100,64,132,0,90,33,100,95, - 100,65,100,66,132,1,90,34,100,67,100,68,132,0,90,35, - 100,69,90,36,101,36,100,70,23,0,90,37,100,71,100,72, - 132,0,90,38,101,39,131,0,90,40,100,73,100,74,132,0, - 90,41,100,96,100,76,100,77,132,1,90,42,100,39,100,78, - 156,1,100,79,100,80,132,2,90,43,100,81,100,82,132,0, - 90,44,100,97,100,84,100,85,132,1,90,45,100,86,100,87, - 132,0,90,46,100,88,100,89,132,0,90,47,100,90,100,91, - 132,0,90,48,100,92,100,93,132,0,90,49,100,1,83,0, - 41,98,97,83,1,0,0,67,111,114,101,32,105,109,112,108, - 101,109,101,110,116,97,116,105,111,110,32,111,102,32,105,109, - 112,111,114,116,46,10,10,84,104,105,115,32,109,111,100,117, - 108,101,32,105,115,32,78,79,84,32,109,101,97,110,116,32, - 116,111,32,98,101,32,100,105,114,101,99,116,108,121,32,105, - 109,112,111,114,116,101,100,33,32,73,116,32,104,97,115,32, - 98,101,101,110,32,100,101,115,105,103,110,101,100,32,115,117, - 99,104,10,116,104,97,116,32,105,116,32,99,97,110,32,98, - 101,32,98,111,111,116,115,116,114,97,112,112,101,100,32,105, - 110,116,111,32,80,121,116,104,111,110,32,97,115,32,116,104, - 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, - 32,111,102,32,105,109,112,111,114,116,46,32,65,115,10,115, - 117,99,104,32,105,116,32,114,101,113,117,105,114,101,115,32, - 116,104,101,32,105,110,106,101,99,116,105,111,110,32,111,102, - 32,115,112,101,99,105,102,105,99,32,109,111,100,117,108,101, - 115,32,97,110,100,32,97,116,116,114,105,98,117,116,101,115, - 32,105,110,32,111,114,100,101,114,32,116,111,10,119,111,114, - 107,46,32,79,110,101,32,115,104,111,117,108,100,32,117,115, - 101,32,105,109,112,111,114,116,108,105,98,32,97,115,32,116, - 104,101,32,112,117,98,108,105,99,45,102,97,99,105,110,103, - 32,118,101,114,115,105,111,110,32,111,102,32,116,104,105,115, - 32,109,111,100,117,108,101,46,10,10,78,99,2,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,7,0,0,0, - 67,0,0,0,115,56,0,0,0,100,1,68,0,93,32,125, - 2,116,0,124,1,124,2,131,2,114,4,116,1,124,0,124, - 2,116,2,124,1,124,2,131,2,131,3,1,0,113,4,124, - 0,106,3,160,4,124,1,106,3,161,1,1,0,100,2,83, - 0,41,3,122,47,83,105,109,112,108,101,32,115,117,98,115, - 116,105,116,117,116,101,32,102,111,114,32,102,117,110,99,116, - 111,111,108,115,46,117,112,100,97,116,101,95,119,114,97,112, - 112,101,114,46,41,4,218,10,95,95,109,111,100,117,108,101, - 95,95,218,8,95,95,110,97,109,101,95,95,218,12,95,95, - 113,117,97,108,110,97,109,101,95,95,218,7,95,95,100,111, - 99,95,95,78,41,5,218,7,104,97,115,97,116,116,114,218, - 7,115,101,116,97,116,116,114,218,7,103,101,116,97,116,116, - 114,218,8,95,95,100,105,99,116,95,95,218,6,117,112,100, - 97,116,101,41,3,90,3,110,101,119,90,3,111,108,100,218, - 7,114,101,112,108,97,99,101,169,0,114,10,0,0,0,250, - 29,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, - 105,98,46,95,98,111,111,116,115,116,114,97,112,62,218,5, - 95,119,114,97,112,27,0,0,0,115,8,0,0,0,0,2, - 8,1,10,1,20,1,114,12,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0, - 67,0,0,0,115,12,0,0,0,116,0,116,1,131,1,124, - 0,131,1,83,0,169,1,78,41,2,218,4,116,121,112,101, - 218,3,115,121,115,169,1,218,4,110,97,109,101,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,11,95,110, - 101,119,95,109,111,100,117,108,101,35,0,0,0,115,2,0, - 0,0,0,1,114,18,0,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0, - 0,0,115,12,0,0,0,101,0,90,1,100,0,90,2,100, - 1,83,0,41,2,218,14,95,68,101,97,100,108,111,99,107, - 69,114,114,111,114,78,41,3,114,1,0,0,0,114,0,0, - 0,0,114,2,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,19,0,0,0, - 48,0,0,0,115,2,0,0,0,8,1,114,19,0,0,0, + 0,4,0,0,0,64,0,0,0,115,214,1,0,0,100,0, + 90,0,100,1,100,2,132,0,90,1,100,3,90,2,100,3, + 90,3,100,3,90,4,100,3,97,5,100,4,100,5,132,0, + 90,6,100,6,100,7,132,0,90,7,105,0,90,8,105,0, + 90,9,71,0,100,8,100,9,132,0,100,9,101,10,131,3, + 90,11,71,0,100,10,100,11,132,0,100,11,131,2,90,12, + 71,0,100,12,100,13,132,0,100,13,131,2,90,13,71,0, + 100,14,100,15,132,0,100,15,131,2,90,14,100,16,100,17, + 132,0,90,15,100,18,100,19,132,0,90,16,100,20,100,21, + 132,0,90,17,100,22,100,23,156,1,100,24,100,25,132,2, + 90,18,100,26,100,27,132,0,90,19,100,28,100,29,132,0, + 90,20,100,30,100,31,132,0,90,21,100,32,100,33,132,0, + 90,22,71,0,100,34,100,35,132,0,100,35,131,2,90,23, + 100,3,100,3,100,36,156,2,100,37,100,38,132,2,90,24, + 100,96,100,39,100,40,132,1,90,25,100,41,100,42,156,1, + 100,43,100,44,132,2,90,26,100,45,100,46,132,0,90,27, + 100,47,100,48,132,0,90,28,100,49,100,50,132,0,90,29, + 100,51,100,52,132,0,90,30,100,53,100,54,132,0,90,31, + 100,55,100,56,132,0,90,32,71,0,100,57,100,58,132,0, + 100,58,131,2,90,33,71,0,100,59,100,60,132,0,100,60, + 131,2,90,34,71,0,100,61,100,62,132,0,100,62,131,2, + 90,35,100,63,100,64,132,0,90,36,100,65,100,66,132,0, + 90,37,100,97,100,67,100,68,132,1,90,38,100,69,100,70, + 132,0,90,39,100,71,90,40,101,40,100,72,23,0,90,41, + 100,73,100,74,132,0,90,42,101,43,131,0,90,44,100,75, + 100,76,132,0,90,45,100,98,100,78,100,79,132,1,90,46, + 100,41,100,80,156,1,100,81,100,82,132,2,90,47,100,83, + 100,84,132,0,90,48,100,99,100,86,100,87,132,1,90,49, + 100,88,100,89,132,0,90,50,100,90,100,91,132,0,90,51, + 100,92,100,93,132,0,90,52,100,94,100,95,132,0,90,53, + 100,3,83,0,41,100,97,83,1,0,0,67,111,114,101,32, + 105,109,112,108,101,109,101,110,116,97,116,105,111,110,32,111, + 102,32,105,109,112,111,114,116,46,10,10,84,104,105,115,32, + 109,111,100,117,108,101,32,105,115,32,78,79,84,32,109,101, + 97,110,116,32,116,111,32,98,101,32,100,105,114,101,99,116, + 108,121,32,105,109,112,111,114,116,101,100,33,32,73,116,32, + 104,97,115,32,98,101,101,110,32,100,101,115,105,103,110,101, + 100,32,115,117,99,104,10,116,104,97,116,32,105,116,32,99, + 97,110,32,98,101,32,98,111,111,116,115,116,114,97,112,112, + 101,100,32,105,110,116,111,32,80,121,116,104,111,110,32,97, + 115,32,116,104,101,32,105,109,112,108,101,109,101,110,116,97, + 116,105,111,110,32,111,102,32,105,109,112,111,114,116,46,32, + 65,115,10,115,117,99,104,32,105,116,32,114,101,113,117,105, + 114,101,115,32,116,104,101,32,105,110,106,101,99,116,105,111, + 110,32,111,102,32,115,112,101,99,105,102,105,99,32,109,111, + 100,117,108,101,115,32,97,110,100,32,97,116,116,114,105,98, + 117,116,101,115,32,105,110,32,111,114,100,101,114,32,116,111, + 10,119,111,114,107,46,32,79,110,101,32,115,104,111,117,108, + 100,32,117,115,101,32,105,109,112,111,114,116,108,105,98,32, + 97,115,32,116,104,101,32,112,117,98,108,105,99,45,102,97, + 99,105,110,103,32,118,101,114,115,105,111,110,32,111,102,32, + 116,104,105,115,32,109,111,100,117,108,101,46,10,10,99,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8, + 0,0,0,67,0,0,0,115,38,0,0,0,122,4,124,0, + 106,0,87,0,83,0,4,0,116,1,121,18,1,0,1,0, + 1,0,116,2,124,0,131,1,106,0,6,0,89,0,83,0, + 119,0,169,1,78,41,3,218,12,95,95,113,117,97,108,110, + 97,109,101,95,95,218,14,65,116,116,114,105,98,117,116,101, + 69,114,114,111,114,218,4,116,121,112,101,41,1,218,3,111, + 98,106,169,0,114,5,0,0,0,250,29,60,102,114,111,122, + 101,110,32,105,109,112,111,114,116,108,105,98,46,95,98,111, + 111,116,115,116,114,97,112,62,218,12,95,111,98,106,101,99, + 116,95,110,97,109,101,23,0,0,0,115,10,0,0,0,2, + 1,8,1,12,1,14,1,2,255,114,7,0,0,0,78,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 7,0,0,0,67,0,0,0,115,56,0,0,0,100,1,68, + 0,93,16,125,2,116,0,124,1,124,2,131,2,114,18,116, + 1,124,0,124,2,116,2,124,1,124,2,131,2,131,3,1, + 0,113,2,124,0,106,3,160,4,124,1,106,3,161,1,1, + 0,100,2,83,0,41,3,122,47,83,105,109,112,108,101,32, + 115,117,98,115,116,105,116,117,116,101,32,102,111,114,32,102, + 117,110,99,116,111,111,108,115,46,117,112,100,97,116,101,95, + 119,114,97,112,112,101,114,46,41,4,218,10,95,95,109,111, + 100,117,108,101,95,95,218,8,95,95,110,97,109,101,95,95, + 114,1,0,0,0,218,7,95,95,100,111,99,95,95,78,41, + 5,218,7,104,97,115,97,116,116,114,218,7,115,101,116,97, + 116,116,114,218,7,103,101,116,97,116,116,114,218,8,95,95, + 100,105,99,116,95,95,218,6,117,112,100,97,116,101,41,3, + 90,3,110,101,119,90,3,111,108,100,218,7,114,101,112,108, + 97,99,101,114,5,0,0,0,114,5,0,0,0,114,6,0, + 0,0,218,5,95,119,114,97,112,40,0,0,0,115,10,0, + 0,0,8,2,10,1,18,1,2,128,18,1,114,17,0,0, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,2,0,0,0,67,0,0,0,115,12,0,0,0,116, + 0,116,1,131,1,124,0,131,1,83,0,114,0,0,0,0, + 41,2,114,3,0,0,0,218,3,115,121,115,169,1,218,4, + 110,97,109,101,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,218,11,95,110,101,119,95,109,111,100,117,108,101, + 48,0,0,0,115,2,0,0,0,12,1,114,21,0,0,0, 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,64,0,0,0,115,56,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, - 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, - 90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,0, - 90,8,100,12,83,0,41,13,218,11,95,77,111,100,117,108, - 101,76,111,99,107,122,169,65,32,114,101,99,117,114,115,105, - 118,101,32,108,111,99,107,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,119,104,105,99,104,32,105,115,32, - 97,98,108,101,32,116,111,32,100,101,116,101,99,116,32,100, - 101,97,100,108,111,99,107,115,10,32,32,32,32,40,101,46, - 103,46,32,116,104,114,101,97,100,32,49,32,116,114,121,105, - 110,103,32,116,111,32,116,97,107,101,32,108,111,99,107,115, - 32,65,32,116,104,101,110,32,66,44,32,97,110,100,32,116, - 104,114,101,97,100,32,50,32,116,114,121,105,110,103,32,116, - 111,10,32,32,32,32,116,97,107,101,32,108,111,99,107,115, - 32,66,32,116,104,101,110,32,65,41,46,10,32,32,32,32, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,2,0,0,0,67,0,0,0,115,48,0,0,0,116,0, - 160,1,161,0,124,0,95,2,116,0,160,1,161,0,124,0, - 95,3,124,1,124,0,95,4,100,0,124,0,95,5,100,1, - 124,0,95,6,100,1,124,0,95,7,100,0,83,0,169,2, - 78,233,0,0,0,0,41,8,218,7,95,116,104,114,101,97, - 100,90,13,97,108,108,111,99,97,116,101,95,108,111,99,107, - 218,4,108,111,99,107,218,6,119,97,107,101,117,112,114,17, - 0,0,0,218,5,111,119,110,101,114,218,5,99,111,117,110, - 116,218,7,119,97,105,116,101,114,115,169,2,218,4,115,101, - 108,102,114,17,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,8,95,95,105,110,105,116,95,95, - 58,0,0,0,115,12,0,0,0,0,1,10,1,10,1,6, - 1,6,1,6,1,122,20,95,77,111,100,117,108,101,76,111, - 99,107,46,95,95,105,110,105,116,95,95,99,1,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,3,0,0,0, - 67,0,0,0,115,88,0,0,0,116,0,160,1,161,0,125, - 1,124,0,106,2,125,2,116,3,131,0,125,3,116,4,160, - 5,124,2,161,1,125,4,124,4,100,0,117,0,114,42,100, - 1,83,0,124,4,106,2,125,2,124,2,124,1,107,2,114, - 60,100,2,83,0,124,2,124,3,118,0,114,72,100,1,83, - 0,124,3,160,6,124,2,161,1,1,0,113,20,100,0,83, - 0,41,3,78,70,84,41,7,114,23,0,0,0,218,9,103, - 101,116,95,105,100,101,110,116,114,26,0,0,0,218,3,115, - 101,116,218,12,95,98,108,111,99,107,105,110,103,95,111,110, - 218,3,103,101,116,218,3,97,100,100,41,5,114,30,0,0, - 0,90,2,109,101,218,3,116,105,100,90,4,115,101,101,110, - 114,24,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,12,104,97,115,95,100,101,97,100,108,111, - 99,107,66,0,0,0,115,24,0,0,0,0,2,8,1,6, - 1,6,2,10,1,8,1,4,1,6,1,8,1,4,1,8, - 6,4,1,122,24,95,77,111,100,117,108,101,76,111,99,107, - 46,104,97,115,95,100,101,97,100,108,111,99,107,99,1,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,8,0, - 0,0,67,0,0,0,115,210,0,0,0,116,0,160,1,161, - 0,125,1,124,0,116,2,124,1,60,0,122,180,124,0,106, - 3,143,126,1,0,124,0,106,4,100,1,107,2,115,46,124, - 0,106,5,124,1,107,2,114,90,124,1,124,0,95,5,124, - 0,4,0,106,4,100,2,55,0,2,0,95,4,87,0,100, - 3,4,0,4,0,131,3,1,0,87,0,116,2,124,1,61, - 0,100,4,83,0,124,0,160,6,161,0,114,110,116,7,100, - 5,124,0,22,0,131,1,130,1,124,0,106,8,160,9,100, - 6,161,1,114,136,124,0,4,0,106,10,100,2,55,0,2, - 0,95,10,87,0,100,3,4,0,4,0,131,3,1,0,110, - 16,49,0,115,156,48,0,1,0,1,0,1,0,89,0,1, - 0,124,0,106,8,160,9,161,0,1,0,124,0,106,8,160, - 11,161,0,1,0,113,18,87,0,116,2,124,1,61,0,110, - 8,116,2,124,1,61,0,48,0,100,3,83,0,41,7,122, - 185,10,32,32,32,32,32,32,32,32,65,99,113,117,105,114, - 101,32,116,104,101,32,109,111,100,117,108,101,32,108,111,99, - 107,46,32,32,73,102,32,97,32,112,111,116,101,110,116,105, - 97,108,32,100,101,97,100,108,111,99,107,32,105,115,32,100, - 101,116,101,99,116,101,100,44,10,32,32,32,32,32,32,32, - 32,97,32,95,68,101,97,100,108,111,99,107,69,114,114,111, - 114,32,105,115,32,114,97,105,115,101,100,46,10,32,32,32, - 32,32,32,32,32,79,116,104,101,114,119,105,115,101,44,32, - 116,104,101,32,108,111,99,107,32,105,115,32,97,108,119,97, - 121,115,32,97,99,113,117,105,114,101,100,32,97,110,100,32, - 84,114,117,101,32,105,115,32,114,101,116,117,114,110,101,100, - 46,10,32,32,32,32,32,32,32,32,114,22,0,0,0,233, - 1,0,0,0,78,84,122,23,100,101,97,100,108,111,99,107, - 32,100,101,116,101,99,116,101,100,32,98,121,32,37,114,70, - 41,12,114,23,0,0,0,114,32,0,0,0,114,34,0,0, - 0,114,24,0,0,0,114,27,0,0,0,114,26,0,0,0, - 114,38,0,0,0,114,19,0,0,0,114,25,0,0,0,218, - 7,97,99,113,117,105,114,101,114,28,0,0,0,218,7,114, - 101,108,101,97,115,101,169,2,114,30,0,0,0,114,37,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,40,0,0,0,87,0,0,0,115,34,0,0,0,0, - 6,8,1,8,1,2,2,8,1,20,1,6,1,14,1,14, - 9,6,247,4,1,8,1,12,1,12,1,44,2,10,1,14, - 2,122,19,95,77,111,100,117,108,101,76,111,99,107,46,97, - 99,113,117,105,114,101,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, - 142,0,0,0,116,0,160,1,161,0,125,1,124,0,106,2, - 143,108,1,0,124,0,106,3,124,1,107,3,114,34,116,4, - 100,1,131,1,130,1,124,0,106,5,100,2,107,4,115,48, - 74,0,130,1,124,0,4,0,106,5,100,3,56,0,2,0, - 95,5,124,0,106,5,100,2,107,2,114,108,100,0,124,0, - 95,3,124,0,106,6,114,108,124,0,4,0,106,6,100,3, - 56,0,2,0,95,6,124,0,106,7,160,8,161,0,1,0, - 87,0,100,0,4,0,4,0,131,3,1,0,110,16,49,0, - 115,128,48,0,1,0,1,0,1,0,89,0,1,0,100,0, - 83,0,41,4,78,250,31,99,97,110,110,111,116,32,114,101, - 108,101,97,115,101,32,117,110,45,97,99,113,117,105,114,101, - 100,32,108,111,99,107,114,22,0,0,0,114,39,0,0,0, - 41,9,114,23,0,0,0,114,32,0,0,0,114,24,0,0, - 0,114,26,0,0,0,218,12,82,117,110,116,105,109,101,69, - 114,114,111,114,114,27,0,0,0,114,28,0,0,0,114,25, - 0,0,0,114,41,0,0,0,114,42,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,41,0,0, - 0,112,0,0,0,115,22,0,0,0,0,1,8,1,8,1, - 10,1,8,1,14,1,14,1,10,1,6,1,6,1,14,1, - 122,19,95,77,111,100,117,108,101,76,111,99,107,46,114,101, - 108,101,97,115,101,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,5,0,0,0,67,0,0,0,115,18, - 0,0,0,100,1,160,0,124,0,106,1,116,2,124,0,131, - 1,161,2,83,0,41,2,78,122,23,95,77,111,100,117,108, - 101,76,111,99,107,40,123,33,114,125,41,32,97,116,32,123, - 125,169,3,218,6,102,111,114,109,97,116,114,17,0,0,0, - 218,2,105,100,169,1,114,30,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,8,95,95,114,101, - 112,114,95,95,125,0,0,0,115,2,0,0,0,0,1,122, - 20,95,77,111,100,117,108,101,76,111,99,107,46,95,95,114, - 101,112,114,95,95,78,41,9,114,1,0,0,0,114,0,0, - 0,0,114,2,0,0,0,114,3,0,0,0,114,31,0,0, - 0,114,38,0,0,0,114,40,0,0,0,114,41,0,0,0, - 114,49,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,20,0,0,0,52,0, - 0,0,115,12,0,0,0,8,1,4,5,8,8,8,21,8, - 25,8,13,114,20,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, - 0,115,48,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, - 90,5,100,6,100,7,132,0,90,6,100,8,100,9,132,0, - 90,7,100,10,83,0,41,11,218,16,95,68,117,109,109,121, - 77,111,100,117,108,101,76,111,99,107,122,86,65,32,115,105, - 109,112,108,101,32,95,77,111,100,117,108,101,76,111,99,107, - 32,101,113,117,105,118,97,108,101,110,116,32,102,111,114,32, - 80,121,116,104,111,110,32,98,117,105,108,100,115,32,119,105, - 116,104,111,117,116,10,32,32,32,32,109,117,108,116,105,45, - 116,104,114,101,97,100,105,110,103,32,115,117,112,112,111,114, - 116,46,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, - 124,1,124,0,95,0,100,1,124,0,95,1,100,0,83,0, - 114,21,0,0,0,41,2,114,17,0,0,0,114,27,0,0, - 0,114,29,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,31,0,0,0,133,0,0,0,115,4, - 0,0,0,0,1,6,1,122,25,95,68,117,109,109,121,77, - 111,100,117,108,101,76,111,99,107,46,95,95,105,110,105,116, - 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,67,0,0,0,115,18,0,0,0, - 124,0,4,0,106,0,100,1,55,0,2,0,95,0,100,2, - 83,0,41,3,78,114,39,0,0,0,84,41,1,114,27,0, - 0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,40,0,0,0,137,0,0,0,115, - 4,0,0,0,0,1,14,1,122,24,95,68,117,109,109,121, - 77,111,100,117,108,101,76,111,99,107,46,97,99,113,117,105, - 114,101,99,1,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,67,0,0,0,115,36,0,0,0, - 124,0,106,0,100,1,107,2,114,18,116,1,100,2,131,1, - 130,1,124,0,4,0,106,0,100,3,56,0,2,0,95,0, - 100,0,83,0,41,4,78,114,22,0,0,0,114,43,0,0, - 0,114,39,0,0,0,41,2,114,27,0,0,0,114,44,0, - 0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,41,0,0,0,141,0,0,0,115, - 6,0,0,0,0,1,10,1,8,1,122,24,95,68,117,109, - 109,121,77,111,100,117,108,101,76,111,99,107,46,114,101,108, - 101,97,115,101,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,5,0,0,0,67,0,0,0,115,18,0, - 0,0,100,1,160,0,124,0,106,1,116,2,124,0,131,1, - 161,2,83,0,41,2,78,122,28,95,68,117,109,109,121,77, - 111,100,117,108,101,76,111,99,107,40,123,33,114,125,41,32, - 97,116,32,123,125,114,45,0,0,0,114,48,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,49, - 0,0,0,146,0,0,0,115,2,0,0,0,0,1,122,25, + 0,1,0,0,0,64,0,0,0,115,12,0,0,0,101,0, + 90,1,100,0,90,2,100,1,83,0,41,2,218,14,95,68, + 101,97,100,108,111,99,107,69,114,114,111,114,78,41,3,114, + 9,0,0,0,114,8,0,0,0,114,1,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, + 0,0,114,22,0,0,0,61,0,0,0,115,4,0,0,0, + 8,0,4,1,114,22,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, + 0,0,115,56,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, + 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, + 0,90,7,100,10,100,11,132,0,90,8,100,12,83,0,41, + 13,218,11,95,77,111,100,117,108,101,76,111,99,107,122,169, + 65,32,114,101,99,117,114,115,105,118,101,32,108,111,99,107, + 32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,32, + 119,104,105,99,104,32,105,115,32,97,98,108,101,32,116,111, + 32,100,101,116,101,99,116,32,100,101,97,100,108,111,99,107, + 115,10,32,32,32,32,40,101,46,103,46,32,116,104,114,101, + 97,100,32,49,32,116,114,121,105,110,103,32,116,111,32,116, + 97,107,101,32,108,111,99,107,115,32,65,32,116,104,101,110, + 32,66,44,32,97,110,100,32,116,104,114,101,97,100,32,50, + 32,116,114,121,105,110,103,32,116,111,10,32,32,32,32,116, + 97,107,101,32,108,111,99,107,115,32,66,32,116,104,101,110, + 32,65,41,46,10,32,32,32,32,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, + 0,0,115,48,0,0,0,116,0,160,1,161,0,124,0,95, + 2,116,0,160,1,161,0,124,0,95,3,124,1,124,0,95, + 4,100,0,124,0,95,5,100,1,124,0,95,6,100,1,124, + 0,95,7,100,0,83,0,169,2,78,233,0,0,0,0,41, + 8,218,7,95,116,104,114,101,97,100,90,13,97,108,108,111, + 99,97,116,101,95,108,111,99,107,218,4,108,111,99,107,218, + 6,119,97,107,101,117,112,114,20,0,0,0,218,5,111,119, + 110,101,114,218,5,99,111,117,110,116,218,7,119,97,105,116, + 101,114,115,169,2,218,4,115,101,108,102,114,20,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, + 8,95,95,105,110,105,116,95,95,71,0,0,0,115,12,0, + 0,0,10,1,10,1,6,1,6,1,6,1,10,1,122,20, + 95,77,111,100,117,108,101,76,111,99,107,46,95,95,105,110, + 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,3,0,0,0,67,0,0,0,115,86,0, + 0,0,116,0,160,1,161,0,125,1,124,0,106,2,125,2, + 116,3,131,0,125,3,9,0,116,4,160,5,124,2,161,1, + 125,4,124,4,100,0,117,0,114,22,100,2,83,0,124,4, + 106,2,125,2,124,2,124,1,107,2,114,31,100,1,83,0, + 124,2,124,3,118,0,114,37,100,2,83,0,124,3,160,6, + 124,2,161,1,1,0,113,11,41,3,78,84,70,41,7,114, + 26,0,0,0,218,9,103,101,116,95,105,100,101,110,116,114, + 29,0,0,0,218,3,115,101,116,218,12,95,98,108,111,99, + 107,105,110,103,95,111,110,218,3,103,101,116,218,3,97,100, + 100,41,5,114,33,0,0,0,90,2,109,101,218,3,116,105, + 100,90,4,115,101,101,110,114,27,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,6,0,0,0,218,12,104,97,115, + 95,100,101,97,100,108,111,99,107,79,0,0,0,115,28,0, + 0,0,8,2,6,1,6,1,2,1,10,1,8,1,4,1, + 6,1,8,1,4,1,8,1,4,6,10,1,2,242,122,24, + 95,77,111,100,117,108,101,76,111,99,107,46,104,97,115,95, + 100,101,97,100,108,111,99,107,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,8,0,0,0,67,0,0, + 0,115,200,0,0,0,116,0,160,1,161,0,125,1,124,0, + 116,2,124,1,60,0,122,87,9,0,124,0,106,3,143,64, + 1,0,124,0,106,4,100,2,107,2,115,24,124,0,106,5, + 124,1,107,2,114,47,124,1,124,0,95,5,124,0,4,0, + 106,4,100,3,55,0,2,0,95,4,9,0,87,0,100,4, + 4,0,4,0,131,3,1,0,87,0,116,2,124,1,61,0, + 100,1,83,0,124,0,160,6,161,0,114,57,116,7,100,5, + 124,0,22,0,131,1,130,1,124,0,106,8,160,9,100,6, + 161,1,114,70,124,0,4,0,106,10,100,3,55,0,2,0, + 95,10,87,0,100,4,4,0,4,0,131,3,1,0,110,8, + 49,0,115,80,119,1,1,0,1,0,1,0,89,0,1,0, + 124,0,106,8,160,9,161,0,1,0,124,0,106,8,160,11, + 161,0,1,0,113,10,116,2,124,1,61,0,119,0,41,7, + 122,185,10,32,32,32,32,32,32,32,32,65,99,113,117,105, + 114,101,32,116,104,101,32,109,111,100,117,108,101,32,108,111, + 99,107,46,32,32,73,102,32,97,32,112,111,116,101,110,116, + 105,97,108,32,100,101,97,100,108,111,99,107,32,105,115,32, + 100,101,116,101,99,116,101,100,44,10,32,32,32,32,32,32, + 32,32,97,32,95,68,101,97,100,108,111,99,107,69,114,114, + 111,114,32,105,115,32,114,97,105,115,101,100,46,10,32,32, + 32,32,32,32,32,32,79,116,104,101,114,119,105,115,101,44, + 32,116,104,101,32,108,111,99,107,32,105,115,32,97,108,119, + 97,121,115,32,97,99,113,117,105,114,101,100,32,97,110,100, + 32,84,114,117,101,32,105,115,32,114,101,116,117,114,110,101, + 100,46,10,32,32,32,32,32,32,32,32,84,114,25,0,0, + 0,233,1,0,0,0,78,122,23,100,101,97,100,108,111,99, + 107,32,100,101,116,101,99,116,101,100,32,98,121,32,37,114, + 70,41,12,114,26,0,0,0,114,35,0,0,0,114,37,0, + 0,0,114,27,0,0,0,114,30,0,0,0,114,29,0,0, + 0,114,41,0,0,0,114,22,0,0,0,114,28,0,0,0, + 218,7,97,99,113,117,105,114,101,114,31,0,0,0,218,7, + 114,101,108,101,97,115,101,169,2,114,33,0,0,0,114,40, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, + 0,0,114,43,0,0,0,100,0,0,0,115,42,0,0,0, + 8,6,8,1,2,1,2,1,8,1,20,1,6,1,14,1, + 2,1,14,252,10,13,8,248,12,1,12,1,14,1,2,128, + 28,248,10,10,10,1,2,244,8,14,122,19,95,77,111,100, + 117,108,101,76,111,99,107,46,97,99,113,117,105,114,101,99, + 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 8,0,0,0,67,0,0,0,115,176,0,0,0,116,0,160, + 1,161,0,125,1,124,0,106,2,143,71,1,0,124,0,106, + 3,124,1,107,3,114,17,116,4,100,1,131,1,130,1,124, + 0,106,5,100,2,107,4,115,24,74,0,130,1,124,0,4, + 0,106,5,100,3,56,0,2,0,95,5,124,0,106,5,100, + 2,107,2,114,62,100,0,124,0,95,3,124,0,106,6,114, + 70,124,0,4,0,106,6,100,3,56,0,2,0,95,6,124, + 0,106,7,160,8,161,0,1,0,87,0,100,0,4,0,4, + 0,131,3,1,0,100,0,83,0,87,0,100,0,4,0,4, + 0,131,3,1,0,100,0,83,0,87,0,100,0,4,0,4, + 0,131,3,1,0,100,0,83,0,49,0,115,81,119,1,1, + 0,1,0,1,0,89,0,1,0,100,0,83,0,41,4,78, + 250,31,99,97,110,110,111,116,32,114,101,108,101,97,115,101, + 32,117,110,45,97,99,113,117,105,114,101,100,32,108,111,99, + 107,114,25,0,0,0,114,42,0,0,0,41,9,114,26,0, + 0,0,114,35,0,0,0,114,27,0,0,0,114,29,0,0, + 0,218,12,82,117,110,116,105,109,101,69,114,114,111,114,114, + 30,0,0,0,114,31,0,0,0,114,28,0,0,0,114,44, + 0,0,0,114,45,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,6,0,0,0,114,44,0,0,0,125,0,0,0, + 115,32,0,0,0,8,1,8,1,10,1,8,1,14,1,14, + 1,10,1,6,1,6,1,14,1,12,1,14,247,2,5,14, + 251,2,7,34,249,122,19,95,77,111,100,117,108,101,76,111, + 99,107,46,114,101,108,101,97,115,101,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,67, + 0,0,0,243,18,0,0,0,100,1,160,0,124,0,106,1, + 116,2,124,0,131,1,161,2,83,0,41,2,78,122,23,95, + 77,111,100,117,108,101,76,111,99,107,40,123,33,114,125,41, + 32,97,116,32,123,125,169,3,218,6,102,111,114,109,97,116, + 114,20,0,0,0,218,2,105,100,169,1,114,33,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, + 8,95,95,114,101,112,114,95,95,138,0,0,0,243,2,0, + 0,0,18,1,122,20,95,77,111,100,117,108,101,76,111,99, + 107,46,95,95,114,101,112,114,95,95,78,41,9,114,9,0, + 0,0,114,8,0,0,0,114,1,0,0,0,114,10,0,0, + 0,114,34,0,0,0,114,41,0,0,0,114,43,0,0,0, + 114,44,0,0,0,114,53,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,23, + 0,0,0,65,0,0,0,115,14,0,0,0,8,0,4,1, + 8,5,8,8,8,21,8,25,12,13,114,23,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,64,0,0,0,115,48,0,0,0,101,0,90, + 1,100,0,90,2,100,1,90,3,100,2,100,3,132,0,90, + 4,100,4,100,5,132,0,90,5,100,6,100,7,132,0,90, + 6,100,8,100,9,132,0,90,7,100,10,83,0,41,11,218, + 16,95,68,117,109,109,121,77,111,100,117,108,101,76,111,99, + 107,122,86,65,32,115,105,109,112,108,101,32,95,77,111,100, + 117,108,101,76,111,99,107,32,101,113,117,105,118,97,108,101, + 110,116,32,102,111,114,32,80,121,116,104,111,110,32,98,117, + 105,108,100,115,32,119,105,116,104,111,117,116,10,32,32,32, + 32,109,117,108,116,105,45,116,104,114,101,97,100,105,110,103, + 32,115,117,112,112,111,114,116,46,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, + 0,0,115,16,0,0,0,124,1,124,0,95,0,100,1,124, + 0,95,1,100,0,83,0,114,24,0,0,0,41,2,114,20, + 0,0,0,114,30,0,0,0,114,32,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,6,0,0,0,114,34,0,0, + 0,146,0,0,0,243,4,0,0,0,6,1,10,1,122,25, 95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107, - 46,95,95,114,101,112,114,95,95,78,41,8,114,1,0,0, - 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, - 114,31,0,0,0,114,40,0,0,0,114,41,0,0,0,114, - 49,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,50,0,0,0,129,0,0, - 0,115,10,0,0,0,8,1,4,3,8,4,8,4,8,5, - 114,50,0,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,36, - 0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,132, - 0,90,3,100,3,100,4,132,0,90,4,100,5,100,6,132, - 0,90,5,100,7,83,0,41,8,218,18,95,77,111,100,117, - 108,101,76,111,99,107,77,97,110,97,103,101,114,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0, - 0,0,67,0,0,0,115,16,0,0,0,124,1,124,0,95, - 0,100,0,124,0,95,1,100,0,83,0,114,13,0,0,0, - 41,2,218,5,95,110,97,109,101,218,5,95,108,111,99,107, - 114,29,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,31,0,0,0,152,0,0,0,115,4,0, - 0,0,0,1,6,1,122,27,95,77,111,100,117,108,101,76, - 111,99,107,77,97,110,97,103,101,114,46,95,95,105,110,105, - 116,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,2,0,0,0,67,0,0,0,115,26,0,0, - 0,116,0,124,0,106,1,131,1,124,0,95,2,124,0,106, - 2,160,3,161,0,1,0,100,0,83,0,114,13,0,0,0, - 41,4,218,16,95,103,101,116,95,109,111,100,117,108,101,95, - 108,111,99,107,114,52,0,0,0,114,53,0,0,0,114,40, - 0,0,0,114,48,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,9,95,95,101,110,116,101,114, - 95,95,156,0,0,0,115,4,0,0,0,0,1,12,1,122, - 28,95,77,111,100,117,108,101,76,111,99,107,77,97,110,97, - 103,101,114,46,95,95,101,110,116,101,114,95,95,99,1,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0, - 0,0,79,0,0,0,115,14,0,0,0,124,0,106,0,160, - 1,161,0,1,0,100,0,83,0,114,13,0,0,0,41,2, - 114,53,0,0,0,114,41,0,0,0,41,3,114,30,0,0, - 0,218,4,97,114,103,115,90,6,107,119,97,114,103,115,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 95,95,101,120,105,116,95,95,160,0,0,0,115,2,0,0, - 0,0,1,122,27,95,77,111,100,117,108,101,76,111,99,107, - 77,97,110,97,103,101,114,46,95,95,101,120,105,116,95,95, - 78,41,6,114,1,0,0,0,114,0,0,0,0,114,2,0, - 0,0,114,31,0,0,0,114,55,0,0,0,114,57,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,51,0,0,0,150,0,0,0,115,6, - 0,0,0,8,2,8,4,8,4,114,51,0,0,0,99,1, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,8, - 0,0,0,67,0,0,0,115,136,0,0,0,116,0,160,1, - 161,0,1,0,122,112,122,14,116,2,124,0,25,0,131,0, - 125,1,87,0,110,22,4,0,116,3,121,46,1,0,1,0, - 1,0,100,1,125,1,89,0,110,2,48,0,124,1,100,1, - 117,0,114,110,116,4,100,1,117,0,114,74,116,5,124,0, - 131,1,125,1,110,8,116,6,124,0,131,1,125,1,124,0, - 102,1,100,2,100,3,132,1,125,2,116,7,160,8,124,1, - 124,2,161,2,116,2,124,0,60,0,87,0,116,0,160,9, - 161,0,1,0,110,10,116,0,160,9,161,0,1,0,48,0, - 124,1,83,0,41,4,122,139,71,101,116,32,111,114,32,99, - 114,101,97,116,101,32,116,104,101,32,109,111,100,117,108,101, - 32,108,111,99,107,32,102,111,114,32,97,32,103,105,118,101, - 110,32,109,111,100,117,108,101,32,110,97,109,101,46,10,10, - 32,32,32,32,65,99,113,117,105,114,101,47,114,101,108,101, - 97,115,101,32,105,110,116,101,114,110,97,108,108,121,32,116, - 104,101,32,103,108,111,98,97,108,32,105,109,112,111,114,116, - 32,108,111,99,107,32,116,111,32,112,114,111,116,101,99,116, - 10,32,32,32,32,95,109,111,100,117,108,101,95,108,111,99, - 107,115,46,78,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,8,0,0,0,83,0,0,0,115,56,0, - 0,0,116,0,160,1,161,0,1,0,122,32,116,2,160,3, - 124,1,161,1,124,0,117,0,114,30,116,2,124,1,61,0, - 87,0,116,0,160,4,161,0,1,0,110,10,116,0,160,4, - 161,0,1,0,48,0,100,0,83,0,114,13,0,0,0,41, - 5,218,4,95,105,109,112,218,12,97,99,113,117,105,114,101, - 95,108,111,99,107,218,13,95,109,111,100,117,108,101,95,108, - 111,99,107,115,114,35,0,0,0,218,12,114,101,108,101,97, - 115,101,95,108,111,99,107,41,2,218,3,114,101,102,114,17, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,2,99,98,185,0,0,0,115,10,0,0,0,0, - 1,8,1,2,4,14,1,8,2,122,28,95,103,101,116,95, - 109,111,100,117,108,101,95,108,111,99,107,46,60,108,111,99, - 97,108,115,62,46,99,98,41,10,114,58,0,0,0,114,59, - 0,0,0,114,60,0,0,0,218,8,75,101,121,69,114,114, - 111,114,114,23,0,0,0,114,50,0,0,0,114,20,0,0, - 0,218,8,95,119,101,97,107,114,101,102,114,62,0,0,0, - 114,61,0,0,0,41,3,114,17,0,0,0,114,24,0,0, - 0,114,63,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,54,0,0,0,166,0,0,0,115,28, - 0,0,0,0,6,8,1,2,1,2,1,14,1,12,1,10, - 2,8,1,8,1,10,2,8,2,12,11,18,2,20,2,114, - 54,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,8,0,0,0,67,0,0,0,115,52,0, - 0,0,116,0,124,0,131,1,125,1,122,12,124,1,160,1, - 161,0,1,0,87,0,110,18,4,0,116,2,121,38,1,0, - 1,0,1,0,89,0,110,10,48,0,124,1,160,3,161,0, - 1,0,100,1,83,0,41,2,122,189,65,99,113,117,105,114, - 101,115,32,116,104,101,110,32,114,101,108,101,97,115,101,115, - 32,116,104,101,32,109,111,100,117,108,101,32,108,111,99,107, - 32,102,111,114,32,97,32,103,105,118,101,110,32,109,111,100, - 117,108,101,32,110,97,109,101,46,10,10,32,32,32,32,84, - 104,105,115,32,105,115,32,117,115,101,100,32,116,111,32,101, - 110,115,117,114,101,32,97,32,109,111,100,117,108,101,32,105, - 115,32,99,111,109,112,108,101,116,101,108,121,32,105,110,105, - 116,105,97,108,105,122,101,100,44,32,105,110,32,116,104,101, - 10,32,32,32,32,101,118,101,110,116,32,105,116,32,105,115, - 32,98,101,105,110,103,32,105,109,112,111,114,116,101,100,32, - 98,121,32,97,110,111,116,104,101,114,32,116,104,114,101,97, - 100,46,10,32,32,32,32,78,41,4,114,54,0,0,0,114, - 40,0,0,0,114,19,0,0,0,114,41,0,0,0,41,2, - 114,17,0,0,0,114,24,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,19,95,108,111,99,107, - 95,117,110,108,111,99,107,95,109,111,100,117,108,101,203,0, - 0,0,115,12,0,0,0,0,6,8,1,2,1,12,1,12, - 3,6,2,114,66,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,4,0,0,0,79,0,0, - 0,115,14,0,0,0,124,0,124,1,105,0,124,2,164,1, - 142,1,83,0,41,1,97,46,1,0,0,114,101,109,111,118, - 101,95,105,109,112,111,114,116,108,105,98,95,102,114,97,109, - 101,115,32,105,110,32,105,109,112,111,114,116,46,99,32,119, - 105,108,108,32,97,108,119,97,121,115,32,114,101,109,111,118, - 101,32,115,101,113,117,101,110,99,101,115,10,32,32,32,32, - 111,102,32,105,109,112,111,114,116,108,105,98,32,102,114,97, - 109,101,115,32,116,104,97,116,32,101,110,100,32,119,105,116, - 104,32,97,32,99,97,108,108,32,116,111,32,116,104,105,115, - 32,102,117,110,99,116,105,111,110,10,10,32,32,32,32,85, - 115,101,32,105,116,32,105,110,115,116,101,97,100,32,111,102, - 32,97,32,110,111,114,109,97,108,32,99,97,108,108,32,105, - 110,32,112,108,97,99,101,115,32,119,104,101,114,101,32,105, - 110,99,108,117,100,105,110,103,32,116,104,101,32,105,109,112, - 111,114,116,108,105,98,10,32,32,32,32,102,114,97,109,101, - 115,32,105,110,116,114,111,100,117,99,101,115,32,117,110,119, - 97,110,116,101,100,32,110,111,105,115,101,32,105,110,116,111, - 32,116,104,101,32,116,114,97,99,101,98,97,99,107,32,40, - 101,46,103,46,32,119,104,101,110,32,101,120,101,99,117,116, - 105,110,103,10,32,32,32,32,109,111,100,117,108,101,32,99, - 111,100,101,41,10,32,32,32,32,114,10,0,0,0,41,3, - 218,1,102,114,56,0,0,0,90,4,107,119,100,115,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,25,95, - 99,97,108,108,95,119,105,116,104,95,102,114,97,109,101,115, - 95,114,101,109,111,118,101,100,220,0,0,0,115,2,0,0, - 0,0,8,114,68,0,0,0,114,39,0,0,0,41,1,218, - 9,118,101,114,98,111,115,105,116,121,99,1,0,0,0,0, - 0,0,0,1,0,0,0,3,0,0,0,4,0,0,0,71, - 0,0,0,115,54,0,0,0,116,0,106,1,106,2,124,1, - 107,5,114,50,124,0,160,3,100,1,161,1,115,30,100,2, - 124,0,23,0,125,0,116,4,124,0,106,5,124,2,142,0, - 116,0,106,6,100,3,141,2,1,0,100,4,83,0,41,5, - 122,61,80,114,105,110,116,32,116,104,101,32,109,101,115,115, - 97,103,101,32,116,111,32,115,116,100,101,114,114,32,105,102, - 32,45,118,47,80,89,84,72,79,78,86,69,82,66,79,83, - 69,32,105,115,32,116,117,114,110,101,100,32,111,110,46,41, - 2,250,1,35,122,7,105,109,112,111,114,116,32,122,2,35, - 32,41,1,90,4,102,105,108,101,78,41,7,114,15,0,0, - 0,218,5,102,108,97,103,115,218,7,118,101,114,98,111,115, - 101,218,10,115,116,97,114,116,115,119,105,116,104,218,5,112, - 114,105,110,116,114,46,0,0,0,218,6,115,116,100,101,114, - 114,41,3,218,7,109,101,115,115,97,103,101,114,69,0,0, - 0,114,56,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,16,95,118,101,114,98,111,115,101,95, - 109,101,115,115,97,103,101,231,0,0,0,115,8,0,0,0, - 0,2,12,1,10,1,8,1,114,77,0,0,0,99,1,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, - 0,0,3,0,0,0,115,26,0,0,0,135,0,102,1,100, - 1,100,2,132,8,125,1,116,0,124,1,136,0,131,2,1, - 0,124,1,83,0,41,3,122,49,68,101,99,111,114,97,116, - 111,114,32,116,111,32,118,101,114,105,102,121,32,116,104,101, - 32,110,97,109,101,100,32,109,111,100,117,108,101,32,105,115, - 32,98,117,105,108,116,45,105,110,46,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,19, - 0,0,0,115,38,0,0,0,124,1,116,0,106,1,118,1, - 114,28,116,2,100,1,160,3,124,1,161,1,124,1,100,2, - 141,2,130,1,136,0,124,0,124,1,131,2,83,0,41,3, - 78,250,29,123,33,114,125,32,105,115,32,110,111,116,32,97, - 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101, - 114,16,0,0,0,41,4,114,15,0,0,0,218,20,98,117, - 105,108,116,105,110,95,109,111,100,117,108,101,95,110,97,109, - 101,115,218,11,73,109,112,111,114,116,69,114,114,111,114,114, - 46,0,0,0,169,2,114,30,0,0,0,218,8,102,117,108, - 108,110,97,109,101,169,1,218,3,102,120,110,114,10,0,0, - 0,114,11,0,0,0,218,25,95,114,101,113,117,105,114,101, - 115,95,98,117,105,108,116,105,110,95,119,114,97,112,112,101, - 114,241,0,0,0,115,10,0,0,0,0,1,10,1,10,1, - 2,255,6,2,122,52,95,114,101,113,117,105,114,101,115,95, - 98,117,105,108,116,105,110,46,60,108,111,99,97,108,115,62, - 46,95,114,101,113,117,105,114,101,115,95,98,117,105,108,116, - 105,110,95,119,114,97,112,112,101,114,169,1,114,12,0,0, - 0,41,2,114,84,0,0,0,114,85,0,0,0,114,10,0, - 0,0,114,83,0,0,0,114,11,0,0,0,218,17,95,114, - 101,113,117,105,114,101,115,95,98,117,105,108,116,105,110,239, - 0,0,0,115,6,0,0,0,0,2,12,5,10,1,114,87, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,3,0,0,0,3,0,0,0,115,26,0,0, - 0,135,0,102,1,100,1,100,2,132,8,125,1,116,0,124, - 1,136,0,131,2,1,0,124,1,83,0,41,3,122,47,68, - 101,99,111,114,97,116,111,114,32,116,111,32,118,101,114,105, - 102,121,32,116,104,101,32,110,97,109,101,100,32,109,111,100, - 117,108,101,32,105,115,32,102,114,111,122,101,110,46,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, - 0,0,0,19,0,0,0,115,38,0,0,0,116,0,160,1, - 124,1,161,1,115,28,116,2,100,1,160,3,124,1,161,1, - 124,1,100,2,141,2,130,1,136,0,124,0,124,1,131,2, - 83,0,169,3,78,122,27,123,33,114,125,32,105,115,32,110, - 111,116,32,97,32,102,114,111,122,101,110,32,109,111,100,117, - 108,101,114,16,0,0,0,41,4,114,58,0,0,0,218,9, - 105,115,95,102,114,111,122,101,110,114,80,0,0,0,114,46, - 0,0,0,114,81,0,0,0,114,83,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,24,95,114,101,113,117,105,114, - 101,115,95,102,114,111,122,101,110,95,119,114,97,112,112,101, - 114,252,0,0,0,115,10,0,0,0,0,1,10,1,10,1, - 2,255,6,2,122,50,95,114,101,113,117,105,114,101,115,95, - 102,114,111,122,101,110,46,60,108,111,99,97,108,115,62,46, - 95,114,101,113,117,105,114,101,115,95,102,114,111,122,101,110, - 95,119,114,97,112,112,101,114,114,86,0,0,0,41,2,114, - 84,0,0,0,114,90,0,0,0,114,10,0,0,0,114,83, - 0,0,0,114,11,0,0,0,218,16,95,114,101,113,117,105, - 114,101,115,95,102,114,111,122,101,110,250,0,0,0,115,6, - 0,0,0,0,2,12,5,10,1,114,91,0,0,0,99,2, - 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,3, - 0,0,0,67,0,0,0,115,62,0,0,0,116,0,124,1, - 124,0,131,2,125,2,124,1,116,1,106,2,118,0,114,50, - 116,1,106,2,124,1,25,0,125,3,116,3,124,2,124,3, - 131,2,1,0,116,1,106,2,124,1,25,0,83,0,116,4, - 124,2,131,1,83,0,100,1,83,0,41,2,122,128,76,111, - 97,100,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,32,105,110,116,111,32,115,121,115, - 46,109,111,100,117,108,101,115,32,97,110,100,32,114,101,116, - 117,114,110,32,105,116,46,10,10,32,32,32,32,84,104,105, - 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, - 101,99,97,116,101,100,46,32,32,85,115,101,32,108,111,97, - 100,101,114,46,101,120,101,99,95,109,111,100,117,108,101,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,78,41, - 5,218,16,115,112,101,99,95,102,114,111,109,95,108,111,97, - 100,101,114,114,15,0,0,0,218,7,109,111,100,117,108,101, - 115,218,5,95,101,120,101,99,218,5,95,108,111,97,100,41, - 4,114,30,0,0,0,114,82,0,0,0,218,4,115,112,101, - 99,218,6,109,111,100,117,108,101,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,17,95,108,111,97,100,95, - 109,111,100,117,108,101,95,115,104,105,109,6,1,0,0,115, - 12,0,0,0,0,6,10,1,10,1,10,1,10,1,10,2, - 114,98,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,5,0,0,0,8,0,0,0,67,0,0,0,115,218, - 0,0,0,116,0,124,0,100,1,100,0,131,3,125,1,116, - 1,124,1,100,2,131,2,114,54,122,12,124,1,160,2,124, - 0,161,1,87,0,83,0,4,0,116,3,121,52,1,0,1, - 0,1,0,89,0,110,2,48,0,122,10,124,0,106,4,125, - 2,87,0,110,18,4,0,116,5,121,82,1,0,1,0,1, - 0,89,0,110,18,48,0,124,2,100,0,117,1,114,100,116, - 6,124,2,131,1,83,0,122,10,124,0,106,7,125,3,87, - 0,110,22,4,0,116,5,121,132,1,0,1,0,1,0,100, - 3,125,3,89,0,110,2,48,0,122,10,124,0,106,8,125, - 4,87,0,110,56,4,0,116,5,121,200,1,0,1,0,1, - 0,124,1,100,0,117,0,114,180,100,4,160,9,124,3,161, - 1,6,0,89,0,83,0,100,5,160,9,124,3,124,1,161, - 2,6,0,89,0,83,0,89,0,110,14,48,0,100,6,160, - 9,124,3,124,4,161,2,83,0,100,0,83,0,41,7,78, - 218,10,95,95,108,111,97,100,101,114,95,95,218,11,109,111, - 100,117,108,101,95,114,101,112,114,250,1,63,250,13,60,109, - 111,100,117,108,101,32,123,33,114,125,62,250,20,60,109,111, - 100,117,108,101,32,123,33,114,125,32,40,123,33,114,125,41, - 62,250,23,60,109,111,100,117,108,101,32,123,33,114,125,32, - 102,114,111,109,32,123,33,114,125,62,41,10,114,6,0,0, - 0,114,4,0,0,0,114,100,0,0,0,218,9,69,120,99, - 101,112,116,105,111,110,218,8,95,95,115,112,101,99,95,95, - 218,14,65,116,116,114,105,98,117,116,101,69,114,114,111,114, - 218,22,95,109,111,100,117,108,101,95,114,101,112,114,95,102, - 114,111,109,95,115,112,101,99,114,1,0,0,0,218,8,95, - 95,102,105,108,101,95,95,114,46,0,0,0,41,5,114,97, - 0,0,0,218,6,108,111,97,100,101,114,114,96,0,0,0, - 114,17,0,0,0,218,8,102,105,108,101,110,97,109,101,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,12, - 95,109,111,100,117,108,101,95,114,101,112,114,22,1,0,0, - 115,46,0,0,0,0,2,12,1,10,4,2,1,12,1,12, - 1,6,1,2,1,10,1,12,1,6,2,8,1,8,4,2, - 1,10,1,12,1,10,1,2,1,10,1,12,1,8,1,14, - 2,22,2,114,112,0,0,0,99,0,0,0,0,0,0,0, + 46,95,95,105,110,105,116,95,95,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,18,0,0,0,124,0,4,0,106,0,100,1,55, + 0,2,0,95,0,100,2,83,0,41,3,78,114,42,0,0, + 0,84,41,1,114,30,0,0,0,114,52,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,114,43,0, + 0,0,150,0,0,0,115,4,0,0,0,14,1,4,1,122, + 24,95,68,117,109,109,121,77,111,100,117,108,101,76,111,99, + 107,46,97,99,113,117,105,114,101,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,36,0,0,0,124,0,106,0,100,1,107,2,114, + 9,116,1,100,2,131,1,130,1,124,0,4,0,106,0,100, + 3,56,0,2,0,95,0,100,0,83,0,41,4,78,114,25, + 0,0,0,114,46,0,0,0,114,42,0,0,0,41,2,114, + 30,0,0,0,114,47,0,0,0,114,52,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,114,44,0, + 0,0,154,0,0,0,115,6,0,0,0,10,1,8,1,18, + 1,122,24,95,68,117,109,109,121,77,111,100,117,108,101,76, + 111,99,107,46,114,101,108,101,97,115,101,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0, + 67,0,0,0,114,48,0,0,0,41,2,78,122,28,95,68, + 117,109,109,121,77,111,100,117,108,101,76,111,99,107,40,123, + 33,114,125,41,32,97,116,32,123,125,114,49,0,0,0,114, + 52,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,114,53,0,0,0,159,0,0,0,114,54,0,0, + 0,122,25,95,68,117,109,109,121,77,111,100,117,108,101,76, + 111,99,107,46,95,95,114,101,112,114,95,95,78,41,8,114, + 9,0,0,0,114,8,0,0,0,114,1,0,0,0,114,10, + 0,0,0,114,34,0,0,0,114,43,0,0,0,114,44,0, + 0,0,114,53,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,6,0,0,0,114,55,0,0,0, + 142,0,0,0,115,12,0,0,0,8,0,4,1,8,3,8, + 4,8,4,12,5,114,55,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, + 0,0,0,115,36,0,0,0,101,0,90,1,100,0,90,2, + 100,1,100,2,132,0,90,3,100,3,100,4,132,0,90,4, + 100,5,100,6,132,0,90,5,100,7,83,0,41,8,218,18, + 95,77,111,100,117,108,101,76,111,99,107,77,97,110,97,103, + 101,114,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, + 124,1,124,0,95,0,100,0,124,0,95,1,100,0,83,0, + 114,0,0,0,0,41,2,218,5,95,110,97,109,101,218,5, + 95,108,111,99,107,114,32,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,6,0,0,0,114,34,0,0,0,165,0, + 0,0,114,56,0,0,0,122,27,95,77,111,100,117,108,101, + 76,111,99,107,77,97,110,97,103,101,114,46,95,95,105,110, + 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,2,0,0,0,67,0,0,0,115,26,0, + 0,0,116,0,124,0,106,1,131,1,124,0,95,2,124,0, + 106,2,160,3,161,0,1,0,100,0,83,0,114,0,0,0, + 0,41,4,218,16,95,103,101,116,95,109,111,100,117,108,101, + 95,108,111,99,107,114,58,0,0,0,114,59,0,0,0,114, + 43,0,0,0,114,52,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,6,0,0,0,218,9,95,95,101,110,116,101, + 114,95,95,169,0,0,0,115,4,0,0,0,12,1,14,1, + 122,28,95,77,111,100,117,108,101,76,111,99,107,77,97,110, + 97,103,101,114,46,95,95,101,110,116,101,114,95,95,99,1, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2, + 0,0,0,79,0,0,0,115,14,0,0,0,124,0,106,0, + 160,1,161,0,1,0,100,0,83,0,114,0,0,0,0,41, + 2,114,59,0,0,0,114,44,0,0,0,41,3,114,33,0, + 0,0,218,4,97,114,103,115,90,6,107,119,97,114,103,115, + 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, + 8,95,95,101,120,105,116,95,95,173,0,0,0,115,2,0, + 0,0,14,1,122,27,95,77,111,100,117,108,101,76,111,99, + 107,77,97,110,97,103,101,114,46,95,95,101,120,105,116,95, + 95,78,41,6,114,9,0,0,0,114,8,0,0,0,114,1, + 0,0,0,114,34,0,0,0,114,61,0,0,0,114,63,0, + 0,0,114,5,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,6,0,0,0,114,57,0,0,0,163,0,0,0,115, + 8,0,0,0,8,0,8,2,8,4,12,4,114,57,0,0, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,8,0,0,0,67,0,0,0,115,148,0,0,0,116, + 0,160,1,161,0,1,0,122,64,122,7,116,2,124,0,25, + 0,131,0,125,1,87,0,110,11,4,0,116,3,121,23,1, + 0,1,0,1,0,100,1,125,1,89,0,110,1,119,0,124, + 1,100,1,117,0,114,62,116,4,100,1,117,0,114,37,116, + 5,124,0,131,1,125,1,110,4,116,6,124,0,131,1,125, + 1,124,0,102,1,100,2,100,3,132,1,125,2,116,7,160, + 8,124,1,124,2,161,2,116,2,124,0,60,0,87,0,116, + 0,160,9,161,0,1,0,124,1,83,0,87,0,116,0,160, + 9,161,0,1,0,124,1,83,0,116,0,160,9,161,0,1, + 0,119,0,41,4,122,139,71,101,116,32,111,114,32,99,114, + 101,97,116,101,32,116,104,101,32,109,111,100,117,108,101,32, + 108,111,99,107,32,102,111,114,32,97,32,103,105,118,101,110, + 32,109,111,100,117,108,101,32,110,97,109,101,46,10,10,32, + 32,32,32,65,99,113,117,105,114,101,47,114,101,108,101,97, + 115,101,32,105,110,116,101,114,110,97,108,108,121,32,116,104, + 101,32,103,108,111,98,97,108,32,105,109,112,111,114,116,32, + 108,111,99,107,32,116,111,32,112,114,111,116,101,99,116,10, + 32,32,32,32,95,109,111,100,117,108,101,95,108,111,99,107, + 115,46,78,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,8,0,0,0,83,0,0,0,115,68,0,0, + 0,116,0,160,1,161,0,1,0,122,24,116,2,160,3,124, + 1,161,1,124,0,117,0,114,22,116,2,124,1,61,0,87, + 0,116,0,160,4,161,0,1,0,100,0,83,0,87,0,116, + 0,160,4,161,0,1,0,100,0,83,0,116,0,160,4,161, + 0,1,0,119,0,114,0,0,0,0,41,5,218,4,95,105, + 109,112,218,12,97,99,113,117,105,114,101,95,108,111,99,107, + 218,13,95,109,111,100,117,108,101,95,108,111,99,107,115,114, + 38,0,0,0,218,12,114,101,108,101,97,115,101,95,108,111, + 99,107,41,2,218,3,114,101,102,114,20,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,218,2,99, + 98,198,0,0,0,115,14,0,0,0,8,1,2,1,14,4, + 8,1,12,2,2,253,22,3,122,28,95,103,101,116,95,109, + 111,100,117,108,101,95,108,111,99,107,46,60,108,111,99,97, + 108,115,62,46,99,98,41,10,114,64,0,0,0,114,65,0, + 0,0,114,66,0,0,0,218,8,75,101,121,69,114,114,111, + 114,114,26,0,0,0,114,55,0,0,0,114,23,0,0,0, + 218,8,95,119,101,97,107,114,101,102,114,68,0,0,0,114, + 67,0,0,0,41,3,114,20,0,0,0,114,27,0,0,0, + 114,69,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 6,0,0,0,114,60,0,0,0,179,0,0,0,115,38,0, + 0,0,8,6,2,1,2,1,14,1,12,1,8,1,2,255, + 8,3,8,1,10,1,8,2,12,2,18,11,8,2,4,2, + 2,235,8,19,4,2,10,254,114,60,0,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,8,0, + 0,0,67,0,0,0,115,54,0,0,0,116,0,124,0,131, + 1,125,1,122,6,124,1,160,1,161,0,1,0,87,0,110, + 10,4,0,116,2,121,20,1,0,1,0,1,0,89,0,100, + 1,83,0,119,0,124,1,160,3,161,0,1,0,100,1,83, + 0,41,2,122,189,65,99,113,117,105,114,101,115,32,116,104, + 101,110,32,114,101,108,101,97,115,101,115,32,116,104,101,32, + 109,111,100,117,108,101,32,108,111,99,107,32,102,111,114,32, + 97,32,103,105,118,101,110,32,109,111,100,117,108,101,32,110, + 97,109,101,46,10,10,32,32,32,32,84,104,105,115,32,105, + 115,32,117,115,101,100,32,116,111,32,101,110,115,117,114,101, + 32,97,32,109,111,100,117,108,101,32,105,115,32,99,111,109, + 112,108,101,116,101,108,121,32,105,110,105,116,105,97,108,105, + 122,101,100,44,32,105,110,32,116,104,101,10,32,32,32,32, + 101,118,101,110,116,32,105,116,32,105,115,32,98,101,105,110, + 103,32,105,109,112,111,114,116,101,100,32,98,121,32,97,110, + 111,116,104,101,114,32,116,104,114,101,97,100,46,10,32,32, + 32,32,78,41,4,114,60,0,0,0,114,43,0,0,0,114, + 22,0,0,0,114,44,0,0,0,41,2,114,20,0,0,0, + 114,27,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 6,0,0,0,218,19,95,108,111,99,107,95,117,110,108,111, + 99,107,95,109,111,100,117,108,101,216,0,0,0,115,14,0, + 0,0,8,6,2,1,12,1,12,1,6,3,2,253,12,5, + 114,72,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,4,0,0,0,79,0,0,0,115,14, + 0,0,0,124,0,124,1,105,0,124,2,164,1,142,1,83, + 0,41,1,97,46,1,0,0,114,101,109,111,118,101,95,105, + 109,112,111,114,116,108,105,98,95,102,114,97,109,101,115,32, + 105,110,32,105,109,112,111,114,116,46,99,32,119,105,108,108, + 32,97,108,119,97,121,115,32,114,101,109,111,118,101,32,115, + 101,113,117,101,110,99,101,115,10,32,32,32,32,111,102,32, + 105,109,112,111,114,116,108,105,98,32,102,114,97,109,101,115, + 32,116,104,97,116,32,101,110,100,32,119,105,116,104,32,97, + 32,99,97,108,108,32,116,111,32,116,104,105,115,32,102,117, + 110,99,116,105,111,110,10,10,32,32,32,32,85,115,101,32, + 105,116,32,105,110,115,116,101,97,100,32,111,102,32,97,32, + 110,111,114,109,97,108,32,99,97,108,108,32,105,110,32,112, + 108,97,99,101,115,32,119,104,101,114,101,32,105,110,99,108, + 117,100,105,110,103,32,116,104,101,32,105,109,112,111,114,116, + 108,105,98,10,32,32,32,32,102,114,97,109,101,115,32,105, + 110,116,114,111,100,117,99,101,115,32,117,110,119,97,110,116, + 101,100,32,110,111,105,115,101,32,105,110,116,111,32,116,104, + 101,32,116,114,97,99,101,98,97,99,107,32,40,101,46,103, + 46,32,119,104,101,110,32,101,120,101,99,117,116,105,110,103, + 10,32,32,32,32,109,111,100,117,108,101,32,99,111,100,101, + 41,10,32,32,32,32,114,5,0,0,0,41,3,218,1,102, + 114,62,0,0,0,90,4,107,119,100,115,114,5,0,0,0, + 114,5,0,0,0,114,6,0,0,0,218,25,95,99,97,108, + 108,95,119,105,116,104,95,102,114,97,109,101,115,95,114,101, + 109,111,118,101,100,233,0,0,0,115,2,0,0,0,14,8, + 114,74,0,0,0,114,42,0,0,0,41,1,218,9,118,101, + 114,98,111,115,105,116,121,99,1,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,4,0,0,0,71,0,0,0, + 115,58,0,0,0,116,0,106,1,106,2,124,1,107,5,114, + 27,124,0,160,3,100,1,161,1,115,15,100,2,124,0,23, + 0,125,0,116,4,124,0,106,5,124,2,142,0,116,0,106, + 6,100,3,141,2,1,0,100,4,83,0,100,4,83,0,41, + 5,122,61,80,114,105,110,116,32,116,104,101,32,109,101,115, + 115,97,103,101,32,116,111,32,115,116,100,101,114,114,32,105, + 102,32,45,118,47,80,89,84,72,79,78,86,69,82,66,79, + 83,69,32,105,115,32,116,117,114,110,101,100,32,111,110,46, + 41,2,250,1,35,122,7,105,109,112,111,114,116,32,122,2, + 35,32,41,1,90,4,102,105,108,101,78,41,7,114,18,0, + 0,0,218,5,102,108,97,103,115,218,7,118,101,114,98,111, + 115,101,218,10,115,116,97,114,116,115,119,105,116,104,218,5, + 112,114,105,110,116,114,50,0,0,0,218,6,115,116,100,101, + 114,114,41,3,218,7,109,101,115,115,97,103,101,114,75,0, + 0,0,114,62,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,6,0,0,0,218,16,95,118,101,114,98,111,115,101, + 95,109,101,115,115,97,103,101,244,0,0,0,115,10,0,0, + 0,12,2,10,1,8,1,24,1,4,253,114,83,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,3,0,0,0,3,0,0,0,243,26,0,0,0,135,0, + 102,1,100,1,100,2,132,8,125,1,116,0,124,1,136,0, + 131,2,1,0,124,1,83,0,41,3,122,49,68,101,99,111, + 114,97,116,111,114,32,116,111,32,118,101,114,105,102,121,32, + 116,104,101,32,110,97,109,101,100,32,109,111,100,117,108,101, + 32,105,115,32,98,117,105,108,116,45,105,110,46,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,19,0,0,0,115,38,0,0,0,124,1,116,0,106, + 1,118,1,114,14,116,2,100,1,160,3,124,1,161,1,124, + 1,100,2,141,2,130,1,136,0,124,0,124,1,131,2,83, + 0,41,3,78,250,29,123,33,114,125,32,105,115,32,110,111, + 116,32,97,32,98,117,105,108,116,45,105,110,32,109,111,100, + 117,108,101,114,19,0,0,0,41,4,114,18,0,0,0,218, + 20,98,117,105,108,116,105,110,95,109,111,100,117,108,101,95, + 110,97,109,101,115,218,11,73,109,112,111,114,116,69,114,114, + 111,114,114,50,0,0,0,169,2,114,33,0,0,0,218,8, + 102,117,108,108,110,97,109,101,169,1,218,3,102,120,110,114, + 5,0,0,0,114,6,0,0,0,218,25,95,114,101,113,117, + 105,114,101,115,95,98,117,105,108,116,105,110,95,119,114,97, + 112,112,101,114,254,0,0,0,243,10,0,0,0,10,1,10, + 1,2,1,6,255,10,2,122,52,95,114,101,113,117,105,114, + 101,115,95,98,117,105,108,116,105,110,46,60,108,111,99,97, + 108,115,62,46,95,114,101,113,117,105,114,101,115,95,98,117, + 105,108,116,105,110,95,119,114,97,112,112,101,114,169,1,114, + 17,0,0,0,41,2,114,91,0,0,0,114,92,0,0,0, + 114,5,0,0,0,114,90,0,0,0,114,6,0,0,0,218, + 17,95,114,101,113,117,105,114,101,115,95,98,117,105,108,116, + 105,110,252,0,0,0,243,6,0,0,0,12,2,10,5,4, + 1,114,95,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,114, + 84,0,0,0,41,3,122,47,68,101,99,111,114,97,116,111, + 114,32,116,111,32,118,101,114,105,102,121,32,116,104,101,32, + 110,97,109,101,100,32,109,111,100,117,108,101,32,105,115,32, + 102,114,111,122,101,110,46,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,4,0,0,0,19,0,0,0, + 115,38,0,0,0,116,0,160,1,124,1,161,1,115,14,116, + 2,100,1,160,3,124,1,161,1,124,1,100,2,141,2,130, + 1,136,0,124,0,124,1,131,2,83,0,169,3,78,122,27, + 123,33,114,125,32,105,115,32,110,111,116,32,97,32,102,114, + 111,122,101,110,32,109,111,100,117,108,101,114,19,0,0,0, + 41,4,114,64,0,0,0,218,9,105,115,95,102,114,111,122, + 101,110,114,87,0,0,0,114,50,0,0,0,114,88,0,0, + 0,114,90,0,0,0,114,5,0,0,0,114,6,0,0,0, + 218,24,95,114,101,113,117,105,114,101,115,95,102,114,111,122, + 101,110,95,119,114,97,112,112,101,114,9,1,0,0,114,93, + 0,0,0,122,50,95,114,101,113,117,105,114,101,115,95,102, + 114,111,122,101,110,46,60,108,111,99,97,108,115,62,46,95, + 114,101,113,117,105,114,101,115,95,102,114,111,122,101,110,95, + 119,114,97,112,112,101,114,114,94,0,0,0,41,2,114,91, + 0,0,0,114,99,0,0,0,114,5,0,0,0,114,90,0, + 0,0,114,6,0,0,0,218,16,95,114,101,113,117,105,114, + 101,115,95,102,114,111,122,101,110,7,1,0,0,114,96,0, + 0,0,114,100,0,0,0,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,4,0,0,0,67,0,0,0, + 115,74,0,0,0,100,1,125,2,116,0,160,1,124,2,116, + 2,161,2,1,0,116,3,124,1,124,0,131,2,125,3,124, + 1,116,4,106,5,118,0,114,33,116,4,106,5,124,1,25, + 0,125,4,116,6,124,3,124,4,131,2,1,0,116,4,106, + 5,124,1,25,0,83,0,116,7,124,3,131,1,83,0,41, + 2,122,130,76,111,97,100,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,109,111,100,117,108,101,32,105,110,116, + 111,32,115,121,115,46,109,111,100,117,108,101,115,32,97,110, + 100,32,114,101,116,117,114,110,32,105,116,46,10,10,32,32, + 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, + 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, + 101,32,108,111,97,100,101,114,46,101,120,101,99,95,109,111, + 100,117,108,101,40,41,32,105,110,115,116,101,97,100,46,10, + 10,32,32,32,32,122,103,116,104,101,32,108,111,97,100,95, + 109,111,100,117,108,101,40,41,32,109,101,116,104,111,100,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,32,97,110, + 100,32,115,108,97,116,101,100,32,102,111,114,32,114,101,109, + 111,118,97,108,32,105,110,32,80,121,116,104,111,110,32,51, + 46,49,50,59,32,117,115,101,32,101,120,101,99,95,109,111, + 100,117,108,101,40,41,32,105,110,115,116,101,97,100,41,8, + 218,9,95,119,97,114,110,105,110,103,115,218,4,119,97,114, + 110,218,18,68,101,112,114,101,99,97,116,105,111,110,87,97, + 114,110,105,110,103,218,16,115,112,101,99,95,102,114,111,109, + 95,108,111,97,100,101,114,114,18,0,0,0,218,7,109,111, + 100,117,108,101,115,218,5,95,101,120,101,99,218,5,95,108, + 111,97,100,41,5,114,33,0,0,0,114,89,0,0,0,218, + 3,109,115,103,218,4,115,112,101,99,218,6,109,111,100,117, + 108,101,114,5,0,0,0,114,5,0,0,0,114,6,0,0, + 0,218,17,95,108,111,97,100,95,109,111,100,117,108,101,95, + 115,104,105,109,19,1,0,0,115,16,0,0,0,4,6,12, + 2,10,1,10,1,10,1,10,1,10,1,8,2,114,111,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,5, + 0,0,0,8,0,0,0,67,0,0,0,115,188,0,0,0, + 116,0,124,0,100,1,100,2,131,3,125,1,116,0,124,0, + 100,3,100,2,131,3,4,0,125,2,114,18,116,1,124,2, + 131,1,83,0,116,2,124,1,100,4,131,2,114,39,122,6, + 124,1,160,3,124,0,161,1,87,0,83,0,4,0,116,4, + 121,38,1,0,1,0,1,0,89,0,110,1,119,0,122,5, + 124,0,106,5,125,3,87,0,110,11,4,0,116,6,121,55, + 1,0,1,0,1,0,100,5,125,3,89,0,110,1,119,0, + 122,5,124,0,106,7,125,4,87,0,110,26,4,0,116,6, + 121,87,1,0,1,0,1,0,124,1,100,2,117,0,114,79, + 100,6,160,8,124,3,161,1,6,0,89,0,83,0,100,7, + 160,8,124,3,124,1,161,2,6,0,89,0,83,0,119,0, + 100,8,160,8,124,3,124,4,161,2,83,0,41,9,122,44, + 84,104,101,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,111,102,32,77,111,100,117,108,101,84,121,112,101, + 46,95,95,114,101,112,114,95,95,40,41,46,218,10,95,95, + 108,111,97,100,101,114,95,95,78,218,8,95,95,115,112,101, + 99,95,95,218,11,109,111,100,117,108,101,95,114,101,112,114, + 250,1,63,250,13,60,109,111,100,117,108,101,32,123,33,114, + 125,62,250,20,60,109,111,100,117,108,101,32,123,33,114,125, + 32,40,123,33,114,125,41,62,250,23,60,109,111,100,117,108, + 101,32,123,33,114,125,32,102,114,111,109,32,123,33,114,125, + 62,41,9,114,13,0,0,0,218,22,95,109,111,100,117,108, + 101,95,114,101,112,114,95,102,114,111,109,95,115,112,101,99, + 114,11,0,0,0,114,114,0,0,0,218,9,69,120,99,101, + 112,116,105,111,110,114,9,0,0,0,114,2,0,0,0,218, + 8,95,95,102,105,108,101,95,95,114,50,0,0,0,41,5, + 114,110,0,0,0,218,6,108,111,97,100,101,114,114,109,0, + 0,0,114,20,0,0,0,218,8,102,105,108,101,110,97,109, + 101,114,5,0,0,0,114,5,0,0,0,114,6,0,0,0, + 218,12,95,109,111,100,117,108,101,95,114,101,112,114,38,1, + 0,0,115,44,0,0,0,12,2,16,1,8,1,10,1,2, + 1,12,1,12,1,4,1,2,255,2,3,10,1,12,1,8, + 1,2,255,2,2,10,1,12,1,8,1,14,1,16,2,2, + 252,12,6,114,124,0,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,0, 0,115,114,0,0,0,101,0,90,1,100,0,90,2,100,1, 90,3,100,2,100,2,100,2,100,3,156,3,100,4,100,5, @@ -640,25 +664,25 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 99,3,0,0,0,0,0,0,0,3,0,0,0,6,0,0, 0,2,0,0,0,67,0,0,0,115,54,0,0,0,124,1, 124,0,95,0,124,2,124,0,95,1,124,3,124,0,95,2, - 124,4,124,0,95,3,124,5,114,32,103,0,110,2,100,0, + 124,4,124,0,95,3,124,5,114,16,103,0,110,1,100,0, 124,0,95,4,100,1,124,0,95,5,100,0,124,0,95,6, - 100,0,83,0,41,2,78,70,41,7,114,17,0,0,0,114, - 110,0,0,0,114,114,0,0,0,114,115,0,0,0,218,26, + 100,0,83,0,41,2,78,70,41,7,114,20,0,0,0,114, + 122,0,0,0,114,126,0,0,0,114,127,0,0,0,218,26, 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, 95,108,111,99,97,116,105,111,110,115,218,13,95,115,101,116, 95,102,105,108,101,97,116,116,114,218,7,95,99,97,99,104, - 101,100,41,6,114,30,0,0,0,114,17,0,0,0,114,110, - 0,0,0,114,114,0,0,0,114,115,0,0,0,114,116,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,31,0,0,0,95,1,0,0,115,14,0,0,0,0, - 2,6,1,6,1,6,1,6,1,14,3,6,1,122,19,77, + 101,100,41,6,114,33,0,0,0,114,20,0,0,0,114,122, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,128,0, + 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, + 0,114,34,0,0,0,101,1,0,0,115,14,0,0,0,6, + 2,6,1,6,1,6,1,14,1,6,3,10,1,122,19,77, 111,100,117,108,101,83,112,101,99,46,95,95,105,110,105,116, 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,2, 0,0,0,6,0,0,0,67,0,0,0,115,102,0,0,0, 100,1,160,0,124,0,106,1,161,1,100,2,160,0,124,0, 106,2,161,1,103,2,125,1,124,0,106,3,100,0,117,1, - 114,52,124,1,160,4,100,3,160,0,124,0,106,3,161,1, - 161,1,1,0,124,0,106,5,100,0,117,1,114,80,124,1, + 114,26,124,1,160,4,100,3,160,0,124,0,106,3,161,1, + 161,1,1,0,124,0,106,5,100,0,117,1,114,40,124,1, 160,4,100,4,160,0,124,0,106,5,161,1,161,1,1,0, 100,5,160,0,124,0,106,6,106,7,100,6,160,8,124,1, 161,1,161,2,83,0,41,7,78,122,9,110,97,109,101,61, @@ -666,1147 +690,1196 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 125,122,11,111,114,105,103,105,110,61,123,33,114,125,122,29, 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, 95,108,111,99,97,116,105,111,110,115,61,123,125,122,6,123, - 125,40,123,125,41,122,2,44,32,41,9,114,46,0,0,0, - 114,17,0,0,0,114,110,0,0,0,114,114,0,0,0,218, - 6,97,112,112,101,110,100,114,117,0,0,0,218,9,95,95, - 99,108,97,115,115,95,95,114,1,0,0,0,218,4,106,111, - 105,110,41,2,114,30,0,0,0,114,56,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,49,0, - 0,0,107,1,0,0,115,20,0,0,0,0,1,10,1,10, - 255,4,2,10,1,18,1,10,1,8,1,4,255,6,2,122, + 125,40,123,125,41,122,2,44,32,41,9,114,50,0,0,0, + 114,20,0,0,0,114,122,0,0,0,114,126,0,0,0,218, + 6,97,112,112,101,110,100,114,129,0,0,0,218,9,95,95, + 99,108,97,115,115,95,95,114,9,0,0,0,218,4,106,111, + 105,110,41,2,114,33,0,0,0,114,62,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,114,53,0, + 0,0,113,1,0,0,115,20,0,0,0,10,1,10,1,4, + 255,10,2,18,1,10,1,6,1,8,1,4,255,22,2,122, 19,77,111,100,117,108,101,83,112,101,99,46,95,95,114,101, 112,114,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,8,0,0,0,67,0,0,0,115,106,0, - 0,0,124,0,106,0,125,2,122,72,124,0,106,1,124,1, - 106,1,107,2,111,76,124,0,106,2,124,1,106,2,107,2, - 111,76,124,0,106,3,124,1,106,3,107,2,111,76,124,2, - 124,1,106,0,107,2,111,76,124,0,106,4,124,1,106,4, - 107,2,111,76,124,0,106,5,124,1,106,5,107,2,87,0, - 83,0,4,0,116,6,121,100,1,0,1,0,1,0,116,7, - 6,0,89,0,83,0,48,0,100,0,83,0,114,13,0,0, - 0,41,8,114,117,0,0,0,114,17,0,0,0,114,110,0, - 0,0,114,114,0,0,0,218,6,99,97,99,104,101,100,218, - 12,104,97,115,95,108,111,99,97,116,105,111,110,114,107,0, - 0,0,218,14,78,111,116,73,109,112,108,101,109,101,110,116, - 101,100,41,3,114,30,0,0,0,90,5,111,116,104,101,114, - 90,4,115,109,115,108,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,6,95,95,101,113,95,95,117,1,0, - 0,115,30,0,0,0,0,1,6,1,2,1,12,1,10,255, - 2,2,10,254,2,3,8,253,2,4,10,252,2,5,10,251, - 4,6,12,1,122,17,77,111,100,117,108,101,83,112,101,99, - 46,95,95,101,113,95,95,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, - 115,58,0,0,0,124,0,106,0,100,0,117,0,114,52,124, - 0,106,1,100,0,117,1,114,52,124,0,106,2,114,52,116, - 3,100,0,117,0,114,38,116,4,130,1,116,3,160,5,124, - 0,106,1,161,1,124,0,95,0,124,0,106,0,83,0,114, - 13,0,0,0,41,6,114,119,0,0,0,114,114,0,0,0, - 114,118,0,0,0,218,19,95,98,111,111,116,115,116,114,97, - 112,95,101,120,116,101,114,110,97,108,218,19,78,111,116,73, - 109,112,108,101,109,101,110,116,101,100,69,114,114,111,114,90, - 11,95,103,101,116,95,99,97,99,104,101,100,114,48,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,123,0,0,0,129,1,0,0,115,12,0,0,0,0,2, - 10,1,16,1,8,1,4,1,14,1,122,17,77,111,100,117, - 108,101,83,112,101,99,46,99,97,99,104,101,100,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0, - 0,0,67,0,0,0,115,10,0,0,0,124,1,124,0,95, - 0,100,0,83,0,114,13,0,0,0,41,1,114,119,0,0, - 0,41,2,114,30,0,0,0,114,123,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,123,0,0, - 0,138,1,0,0,115,2,0,0,0,0,2,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, - 0,67,0,0,0,115,36,0,0,0,124,0,106,0,100,1, - 117,0,114,26,124,0,106,1,160,2,100,2,161,1,100,3, - 25,0,83,0,124,0,106,1,83,0,100,1,83,0,41,4, - 122,32,84,104,101,32,110,97,109,101,32,111,102,32,116,104, - 101,32,109,111,100,117,108,101,39,115,32,112,97,114,101,110, - 116,46,78,218,1,46,114,22,0,0,0,41,3,114,117,0, - 0,0,114,17,0,0,0,218,10,114,112,97,114,116,105,116, - 105,111,110,114,48,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,6,112,97,114,101,110,116,142, - 1,0,0,115,6,0,0,0,0,3,10,1,16,2,122,17, - 77,111,100,117,108,101,83,112,101,99,46,112,97,114,101,110, - 116,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,1,0,0,0,67,0,0,0,115,6,0,0,0,124, - 0,106,0,83,0,114,13,0,0,0,41,1,114,118,0,0, - 0,114,48,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,124,0,0,0,150,1,0,0,115,2, - 0,0,0,0,2,122,23,77,111,100,117,108,101,83,112,101, - 99,46,104,97,115,95,108,111,99,97,116,105,111,110,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, - 0,0,0,67,0,0,0,115,14,0,0,0,116,0,124,1, - 131,1,124,0,95,1,100,0,83,0,114,13,0,0,0,41, - 2,218,4,98,111,111,108,114,118,0,0,0,41,2,114,30, - 0,0,0,218,5,118,97,108,117,101,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,124,0,0,0,154,1, - 0,0,115,2,0,0,0,0,2,41,12,114,1,0,0,0, - 114,0,0,0,0,114,2,0,0,0,114,3,0,0,0,114, - 31,0,0,0,114,49,0,0,0,114,126,0,0,0,218,8, - 112,114,111,112,101,114,116,121,114,123,0,0,0,218,6,115, - 101,116,116,101,114,114,131,0,0,0,114,124,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,113,0,0,0,58,1,0,0,115,32,0,0, - 0,8,1,4,36,4,1,2,255,12,12,8,10,8,12,2, - 1,10,8,4,1,10,3,2,1,10,7,2,1,10,3,4, - 1,114,113,0,0,0,169,2,114,114,0,0,0,114,116,0, - 0,0,99,2,0,0,0,0,0,0,0,2,0,0,0,6, - 0,0,0,8,0,0,0,67,0,0,0,115,152,0,0,0, - 116,0,124,1,100,1,131,2,114,74,116,1,100,2,117,0, - 114,22,116,2,130,1,116,1,106,3,125,4,124,3,100,2, - 117,0,114,48,124,4,124,0,124,1,100,3,141,2,83,0, - 124,3,114,56,103,0,110,2,100,2,125,5,124,4,124,0, - 124,1,124,5,100,4,141,3,83,0,124,3,100,2,117,0, - 114,136,116,0,124,1,100,5,131,2,114,132,122,14,124,1, - 160,4,124,0,161,1,125,3,87,0,113,136,4,0,116,5, - 121,128,1,0,1,0,1,0,100,2,125,3,89,0,113,136, - 48,0,110,4,100,6,125,3,116,6,124,0,124,1,124,2, - 124,3,100,7,141,4,83,0,41,8,122,53,82,101,116,117, - 114,110,32,97,32,109,111,100,117,108,101,32,115,112,101,99, - 32,98,97,115,101,100,32,111,110,32,118,97,114,105,111,117, - 115,32,108,111,97,100,101,114,32,109,101,116,104,111,100,115, - 46,90,12,103,101,116,95,102,105,108,101,110,97,109,101,78, - 41,1,114,110,0,0,0,41,2,114,110,0,0,0,114,117, - 0,0,0,114,116,0,0,0,70,114,136,0,0,0,41,7, - 114,4,0,0,0,114,127,0,0,0,114,128,0,0,0,218, - 23,115,112,101,99,95,102,114,111,109,95,102,105,108,101,95, - 108,111,99,97,116,105,111,110,114,116,0,0,0,114,80,0, - 0,0,114,113,0,0,0,41,6,114,17,0,0,0,114,110, - 0,0,0,114,114,0,0,0,114,116,0,0,0,114,137,0, - 0,0,90,6,115,101,97,114,99,104,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,92,0,0,0,159,1, - 0,0,115,36,0,0,0,0,2,10,1,8,1,4,1,6, - 2,8,1,12,1,12,1,6,1,2,255,6,3,8,1,10, - 1,2,1,14,1,12,1,12,3,4,2,114,92,0,0,0, - 99,3,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,8,0,0,0,67,0,0,0,115,42,1,0,0,122,10, - 124,0,106,0,125,3,87,0,110,18,4,0,116,1,121,28, - 1,0,1,0,1,0,89,0,110,14,48,0,124,3,100,0, - 117,1,114,42,124,3,83,0,124,0,106,2,125,4,124,1, - 100,0,117,0,114,86,122,10,124,0,106,3,125,1,87,0, - 110,18,4,0,116,1,121,84,1,0,1,0,1,0,89,0, - 110,2,48,0,122,10,124,0,106,4,125,5,87,0,110,22, - 4,0,116,1,121,118,1,0,1,0,1,0,100,0,125,5, - 89,0,110,2,48,0,124,2,100,0,117,0,114,176,124,5, - 100,0,117,0,114,172,122,10,124,1,106,5,125,2,87,0, - 113,176,4,0,116,1,121,168,1,0,1,0,1,0,100,0, - 125,2,89,0,113,176,48,0,110,4,124,5,125,2,122,10, - 124,0,106,6,125,6,87,0,110,22,4,0,116,1,121,208, - 1,0,1,0,1,0,100,0,125,6,89,0,110,2,48,0, - 122,14,116,7,124,0,106,8,131,1,125,7,87,0,110,22, - 4,0,116,1,121,246,1,0,1,0,1,0,100,0,125,7, - 89,0,110,2,48,0,116,9,124,4,124,1,124,2,100,1, - 141,3,125,3,124,5,100,0,117,0,144,1,114,20,100,2, - 110,2,100,3,124,3,95,10,124,6,124,3,95,11,124,7, - 124,3,95,12,124,3,83,0,41,4,78,169,1,114,114,0, - 0,0,70,84,41,13,114,106,0,0,0,114,107,0,0,0, - 114,1,0,0,0,114,99,0,0,0,114,109,0,0,0,218, - 7,95,79,82,73,71,73,78,218,10,95,95,99,97,99,104, - 101,100,95,95,218,4,108,105,115,116,218,8,95,95,112,97, - 116,104,95,95,114,113,0,0,0,114,118,0,0,0,114,123, - 0,0,0,114,117,0,0,0,41,8,114,97,0,0,0,114, - 110,0,0,0,114,114,0,0,0,114,96,0,0,0,114,17, - 0,0,0,90,8,108,111,99,97,116,105,111,110,114,123,0, - 0,0,114,117,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,17,95,115,112,101,99,95,102,114, - 111,109,95,109,111,100,117,108,101,185,1,0,0,115,72,0, - 0,0,0,2,2,1,10,1,12,1,6,2,8,1,4,2, - 6,1,8,1,2,1,10,1,12,2,6,1,2,1,10,1, - 12,1,10,1,8,1,8,1,2,1,10,1,12,1,12,2, - 4,1,2,1,10,1,12,1,10,1,2,1,14,1,12,1, - 10,2,14,1,20,1,6,1,6,1,114,143,0,0,0,70, - 169,1,218,8,111,118,101,114,114,105,100,101,99,2,0,0, - 0,0,0,0,0,1,0,0,0,5,0,0,0,8,0,0, - 0,67,0,0,0,115,210,1,0,0,124,2,115,20,116,0, - 124,1,100,1,100,0,131,3,100,0,117,0,114,52,122,12, - 124,0,106,1,124,1,95,2,87,0,110,18,4,0,116,3, - 121,50,1,0,1,0,1,0,89,0,110,2,48,0,124,2, - 115,72,116,0,124,1,100,2,100,0,131,3,100,0,117,0, - 114,174,124,0,106,4,125,3,124,3,100,0,117,0,114,144, - 124,0,106,5,100,0,117,1,114,144,116,6,100,0,117,0, - 114,108,116,7,130,1,116,6,106,8,125,4,124,4,160,9, - 124,4,161,1,125,3,124,0,106,5,124,3,95,10,124,3, - 124,0,95,4,100,0,124,1,95,11,122,10,124,3,124,1, - 95,12,87,0,110,18,4,0,116,3,121,172,1,0,1,0, - 1,0,89,0,110,2,48,0,124,2,115,194,116,0,124,1, - 100,3,100,0,131,3,100,0,117,0,114,226,122,12,124,0, - 106,13,124,1,95,14,87,0,110,18,4,0,116,3,121,224, - 1,0,1,0,1,0,89,0,110,2,48,0,122,10,124,0, - 124,1,95,15,87,0,110,18,4,0,116,3,121,254,1,0, - 1,0,1,0,89,0,110,2,48,0,124,2,144,1,115,24, - 116,0,124,1,100,4,100,0,131,3,100,0,117,0,144,1, - 114,70,124,0,106,5,100,0,117,1,144,1,114,70,122,12, - 124,0,106,5,124,1,95,16,87,0,110,20,4,0,116,3, - 144,1,121,68,1,0,1,0,1,0,89,0,110,2,48,0, - 124,0,106,17,144,1,114,206,124,2,144,1,115,102,116,0, - 124,1,100,5,100,0,131,3,100,0,117,0,144,1,114,136, - 122,12,124,0,106,18,124,1,95,11,87,0,110,20,4,0, - 116,3,144,1,121,134,1,0,1,0,1,0,89,0,110,2, - 48,0,124,2,144,1,115,160,116,0,124,1,100,6,100,0, - 131,3,100,0,117,0,144,1,114,206,124,0,106,19,100,0, - 117,1,144,1,114,206,122,12,124,0,106,19,124,1,95,20, - 87,0,110,20,4,0,116,3,144,1,121,204,1,0,1,0, - 1,0,89,0,110,2,48,0,124,1,83,0,41,7,78,114, - 1,0,0,0,114,99,0,0,0,218,11,95,95,112,97,99, - 107,97,103,101,95,95,114,142,0,0,0,114,109,0,0,0, - 114,140,0,0,0,41,21,114,6,0,0,0,114,17,0,0, - 0,114,1,0,0,0,114,107,0,0,0,114,110,0,0,0, - 114,117,0,0,0,114,127,0,0,0,114,128,0,0,0,218, + 0,3,0,0,0,8,0,0,0,67,0,0,0,115,102,0, + 0,0,124,0,106,0,125,2,122,36,124,0,106,1,124,1, + 106,1,107,2,111,38,124,0,106,2,124,1,106,2,107,2, + 111,38,124,0,106,3,124,1,106,3,107,2,111,38,124,2, + 124,1,106,0,107,2,111,38,124,0,106,4,124,1,106,4, + 107,2,111,38,124,0,106,5,124,1,106,5,107,2,87,0, + 83,0,4,0,116,6,121,50,1,0,1,0,1,0,116,7, + 6,0,89,0,83,0,119,0,114,0,0,0,0,41,8,114, + 129,0,0,0,114,20,0,0,0,114,122,0,0,0,114,126, + 0,0,0,218,6,99,97,99,104,101,100,218,12,104,97,115, + 95,108,111,99,97,116,105,111,110,114,2,0,0,0,218,14, + 78,111,116,73,109,112,108,101,109,101,110,116,101,100,41,3, + 114,33,0,0,0,90,5,111,116,104,101,114,90,4,115,109, + 115,108,114,5,0,0,0,114,5,0,0,0,114,6,0,0, + 0,218,6,95,95,101,113,95,95,123,1,0,0,115,32,0, + 0,0,6,1,2,1,12,1,10,1,2,255,10,2,2,254, + 8,3,2,253,10,4,2,252,10,5,4,251,12,6,8,1, + 2,255,122,17,77,111,100,117,108,101,83,112,101,99,46,95, + 95,101,113,95,95,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,58, + 0,0,0,124,0,106,0,100,0,117,0,114,26,124,0,106, + 1,100,0,117,1,114,26,124,0,106,2,114,26,116,3,100, + 0,117,0,114,19,116,4,130,1,116,3,160,5,124,0,106, + 1,161,1,124,0,95,0,124,0,106,0,83,0,114,0,0, + 0,0,41,6,114,131,0,0,0,114,126,0,0,0,114,130, + 0,0,0,218,19,95,98,111,111,116,115,116,114,97,112,95, + 101,120,116,101,114,110,97,108,218,19,78,111,116,73,109,112, + 108,101,109,101,110,116,101,100,69,114,114,111,114,90,11,95, + 103,101,116,95,99,97,99,104,101,100,114,52,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,135, + 0,0,0,135,1,0,0,115,12,0,0,0,10,2,16,1, + 8,1,4,1,14,1,6,1,122,17,77,111,100,117,108,101, + 83,112,101,99,46,99,97,99,104,101,100,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, + 67,0,0,0,115,10,0,0,0,124,1,124,0,95,0,100, + 0,83,0,114,0,0,0,0,41,1,114,131,0,0,0,41, + 2,114,33,0,0,0,114,135,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,6,0,0,0,114,135,0,0,0,144, + 1,0,0,115,2,0,0,0,10,2,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,32,0,0,0,124,0,106,0,100,1,117,0, + 114,13,124,0,106,1,160,2,100,2,161,1,100,3,25,0, + 83,0,124,0,106,1,83,0,41,4,122,32,84,104,101,32, + 110,97,109,101,32,111,102,32,116,104,101,32,109,111,100,117, + 108,101,39,115,32,112,97,114,101,110,116,46,78,218,1,46, + 114,25,0,0,0,41,3,114,129,0,0,0,114,20,0,0, + 0,218,10,114,112,97,114,116,105,116,105,111,110,114,52,0, + 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, + 0,218,6,112,97,114,101,110,116,148,1,0,0,115,6,0, + 0,0,10,3,16,1,6,2,122,17,77,111,100,117,108,101, + 83,112,101,99,46,112,97,114,101,110,116,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0, + 67,0,0,0,115,6,0,0,0,124,0,106,0,83,0,114, + 0,0,0,0,41,1,114,130,0,0,0,114,52,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,114, + 136,0,0,0,156,1,0,0,115,2,0,0,0,6,2,122, + 23,77,111,100,117,108,101,83,112,101,99,46,104,97,115,95, + 108,111,99,97,116,105,111,110,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0, + 0,115,14,0,0,0,116,0,124,1,131,1,124,0,95,1, + 100,0,83,0,114,0,0,0,0,41,2,218,4,98,111,111, + 108,114,130,0,0,0,41,2,114,33,0,0,0,218,5,118, + 97,108,117,101,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,114,136,0,0,0,160,1,0,0,115,2,0,0, + 0,14,2,41,12,114,9,0,0,0,114,8,0,0,0,114, + 1,0,0,0,114,10,0,0,0,114,34,0,0,0,114,53, + 0,0,0,114,138,0,0,0,218,8,112,114,111,112,101,114, + 116,121,114,135,0,0,0,218,6,115,101,116,116,101,114,114, + 143,0,0,0,114,136,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,114,125,0, + 0,0,64,1,0,0,115,34,0,0,0,8,0,4,1,4, + 36,2,1,12,255,8,12,8,10,2,12,10,1,4,8,10, + 1,2,3,10,1,2,7,10,1,4,3,14,1,114,125,0, + 0,0,169,2,114,126,0,0,0,114,128,0,0,0,99,2, + 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,8, + 0,0,0,67,0,0,0,115,150,0,0,0,116,0,124,1, + 100,1,131,2,114,37,116,1,100,2,117,0,114,11,116,2, + 130,1,116,1,106,3,125,4,124,3,100,2,117,0,114,24, + 124,4,124,0,124,1,100,3,141,2,83,0,124,3,114,28, + 103,0,110,1,100,2,125,5,124,4,124,0,124,1,124,5, + 100,4,141,3,83,0,124,3,100,2,117,0,114,67,116,0, + 124,1,100,5,131,2,114,65,122,7,124,1,160,4,124,0, + 161,1,125,3,87,0,110,13,4,0,116,5,121,64,1,0, + 1,0,1,0,100,2,125,3,89,0,110,3,119,0,100,6, + 125,3,116,6,124,0,124,1,124,2,124,3,100,7,141,4, + 83,0,41,8,122,53,82,101,116,117,114,110,32,97,32,109, + 111,100,117,108,101,32,115,112,101,99,32,98,97,115,101,100, + 32,111,110,32,118,97,114,105,111,117,115,32,108,111,97,100, + 101,114,32,109,101,116,104,111,100,115,46,90,12,103,101,116, + 95,102,105,108,101,110,97,109,101,78,41,1,114,122,0,0, + 0,41,2,114,122,0,0,0,114,129,0,0,0,114,128,0, + 0,0,70,114,148,0,0,0,41,7,114,11,0,0,0,114, + 139,0,0,0,114,140,0,0,0,218,23,115,112,101,99,95, + 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, + 111,110,114,128,0,0,0,114,87,0,0,0,114,125,0,0, + 0,41,6,114,20,0,0,0,114,122,0,0,0,114,126,0, + 0,0,114,128,0,0,0,114,149,0,0,0,90,6,115,101, + 97,114,99,104,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,114,104,0,0,0,165,1,0,0,115,38,0,0, + 0,10,2,8,1,4,1,6,1,8,2,12,1,12,1,6, + 1,2,1,6,255,8,3,10,1,2,1,14,1,12,1,8, + 1,2,255,4,4,16,2,114,104,0,0,0,99,3,0,0, + 0,0,0,0,0,0,0,0,0,8,0,0,0,8,0,0, + 0,67,0,0,0,115,38,1,0,0,122,5,124,0,106,0, + 125,3,87,0,110,9,4,0,116,1,121,14,1,0,1,0, + 1,0,89,0,110,7,119,0,124,3,100,0,117,1,114,21, + 124,3,83,0,124,0,106,2,125,4,124,1,100,0,117,0, + 114,43,122,5,124,0,106,3,125,1,87,0,110,9,4,0, + 116,1,121,42,1,0,1,0,1,0,89,0,110,1,119,0, + 122,5,124,0,106,4,125,5,87,0,110,11,4,0,116,1, + 121,59,1,0,1,0,1,0,100,0,125,5,89,0,110,1, + 119,0,124,2,100,0,117,0,114,87,124,5,100,0,117,0, + 114,85,122,5,124,1,106,5,125,2,87,0,110,13,4,0, + 116,1,121,84,1,0,1,0,1,0,100,0,125,2,89,0, + 110,3,119,0,124,5,125,2,122,5,124,0,106,6,125,6, + 87,0,110,11,4,0,116,1,121,103,1,0,1,0,1,0, + 100,0,125,6,89,0,110,1,119,0,122,7,116,7,124,0, + 106,8,131,1,125,7,87,0,110,11,4,0,116,1,121,122, + 1,0,1,0,1,0,100,0,125,7,89,0,110,1,119,0, + 116,9,124,4,124,1,124,2,100,1,141,3,125,3,124,5, + 100,0,117,0,114,136,100,2,110,1,100,3,124,3,95,10, + 124,6,124,3,95,11,124,7,124,3,95,12,124,3,83,0, + 41,4,78,169,1,114,126,0,0,0,70,84,41,13,114,113, + 0,0,0,114,2,0,0,0,114,9,0,0,0,114,112,0, + 0,0,114,121,0,0,0,218,7,95,79,82,73,71,73,78, + 218,10,95,95,99,97,99,104,101,100,95,95,218,4,108,105, + 115,116,218,8,95,95,112,97,116,104,95,95,114,125,0,0, + 0,114,130,0,0,0,114,135,0,0,0,114,129,0,0,0, + 41,8,114,110,0,0,0,114,122,0,0,0,114,126,0,0, + 0,114,109,0,0,0,114,20,0,0,0,90,8,108,111,99, + 97,116,105,111,110,114,135,0,0,0,114,129,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,6,0,0,0,218,17, + 95,115,112,101,99,95,102,114,111,109,95,109,111,100,117,108, + 101,191,1,0,0,115,84,0,0,0,2,2,10,1,12,1, + 4,1,2,255,8,3,4,1,6,2,8,1,2,1,10,1, + 12,1,4,2,2,254,2,3,10,1,12,1,8,1,2,255, + 8,2,8,1,2,1,10,1,12,1,8,1,2,255,4,3, + 2,1,10,1,12,1,8,1,2,255,2,2,14,1,12,1, + 8,1,2,255,14,3,18,1,6,1,6,1,4,1,114,155, + 0,0,0,70,169,1,218,8,111,118,101,114,114,105,100,101, + 99,2,0,0,0,0,0,0,0,1,0,0,0,5,0,0, + 0,8,0,0,0,67,0,0,0,115,190,1,0,0,124,2, + 115,10,116,0,124,1,100,1,100,0,131,3,100,0,117,0, + 114,26,122,6,124,0,106,1,124,1,95,2,87,0,110,9, + 4,0,116,3,121,25,1,0,1,0,1,0,89,0,110,1, + 119,0,124,2,115,36,116,0,124,1,100,2,100,0,131,3, + 100,0,117,0,114,87,124,0,106,4,125,3,124,3,100,0, + 117,0,114,72,124,0,106,5,100,0,117,1,114,72,116,6, + 100,0,117,0,114,54,116,7,130,1,116,6,106,8,125,4, + 124,4,160,9,124,4,161,1,125,3,124,0,106,5,124,3, + 95,10,124,3,124,0,95,4,100,0,124,1,95,11,122,5, + 124,3,124,1,95,12,87,0,110,9,4,0,116,3,121,86, + 1,0,1,0,1,0,89,0,110,1,119,0,124,2,115,97, + 116,0,124,1,100,3,100,0,131,3,100,0,117,0,114,113, + 122,6,124,0,106,13,124,1,95,14,87,0,110,9,4,0, + 116,3,121,112,1,0,1,0,1,0,89,0,110,1,119,0, + 122,5,124,0,124,1,95,15,87,0,110,9,4,0,116,3, + 121,127,1,0,1,0,1,0,89,0,110,1,119,0,124,2, + 115,138,116,0,124,1,100,4,100,0,131,3,100,0,117,0, + 114,159,124,0,106,5,100,0,117,1,114,159,122,6,124,0, + 106,5,124,1,95,16,87,0,110,9,4,0,116,3,121,158, + 1,0,1,0,1,0,89,0,110,1,119,0,124,0,106,17, + 114,221,124,2,115,172,116,0,124,1,100,5,100,0,131,3, + 100,0,117,0,114,188,122,6,124,0,106,18,124,1,95,11, + 87,0,110,9,4,0,116,3,121,187,1,0,1,0,1,0, + 89,0,110,1,119,0,124,2,115,198,116,0,124,1,100,6, + 100,0,131,3,100,0,117,0,114,221,124,0,106,19,100,0, + 117,1,114,221,122,7,124,0,106,19,124,1,95,20,87,0, + 124,1,83,0,4,0,116,3,121,220,1,0,1,0,1,0, + 89,0,124,1,83,0,119,0,124,1,83,0,41,7,78,114, + 9,0,0,0,114,112,0,0,0,218,11,95,95,112,97,99, + 107,97,103,101,95,95,114,154,0,0,0,114,121,0,0,0, + 114,152,0,0,0,41,21,114,13,0,0,0,114,20,0,0, + 0,114,9,0,0,0,114,2,0,0,0,114,122,0,0,0, + 114,129,0,0,0,114,139,0,0,0,114,140,0,0,0,218, 16,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, 114,218,7,95,95,110,101,119,95,95,90,5,95,112,97,116, - 104,114,109,0,0,0,114,99,0,0,0,114,131,0,0,0, - 114,146,0,0,0,114,106,0,0,0,114,142,0,0,0,114, - 124,0,0,0,114,114,0,0,0,114,123,0,0,0,114,140, - 0,0,0,41,5,114,96,0,0,0,114,97,0,0,0,114, - 145,0,0,0,114,110,0,0,0,114,147,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, + 104,114,121,0,0,0,114,112,0,0,0,114,143,0,0,0, + 114,158,0,0,0,114,113,0,0,0,114,154,0,0,0,114, + 136,0,0,0,114,126,0,0,0,114,135,0,0,0,114,152, + 0,0,0,41,5,114,109,0,0,0,114,110,0,0,0,114, + 157,0,0,0,114,122,0,0,0,114,159,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,218,18,95, 105,110,105,116,95,109,111,100,117,108,101,95,97,116,116,114, - 115,230,1,0,0,115,96,0,0,0,0,4,20,1,2,1, - 12,1,12,1,6,2,20,1,6,1,8,2,10,1,8,1, - 4,1,6,2,10,1,8,1,6,11,6,1,2,1,10,1, - 12,1,6,2,20,1,2,1,12,1,12,1,6,2,2,1, - 10,1,12,1,6,2,24,1,12,1,2,1,12,1,14,1, - 6,2,8,1,24,1,2,1,12,1,14,1,6,2,24,1, - 12,1,2,1,12,1,14,1,6,1,114,149,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,67,0,0,0,115,82,0,0,0,100,1,125, - 1,116,0,124,0,106,1,100,2,131,2,114,30,124,0,106, - 1,160,2,124,0,161,1,125,1,110,20,116,0,124,0,106, - 1,100,3,131,2,114,50,116,3,100,4,131,1,130,1,124, - 1,100,1,117,0,114,68,116,4,124,0,106,5,131,1,125, - 1,116,6,124,0,124,1,131,2,1,0,124,1,83,0,41, - 5,122,43,67,114,101,97,116,101,32,97,32,109,111,100,117, - 108,101,32,98,97,115,101,100,32,111,110,32,116,104,101,32, - 112,114,111,118,105,100,101,100,32,115,112,101,99,46,78,218, - 13,99,114,101,97,116,101,95,109,111,100,117,108,101,218,11, - 101,120,101,99,95,109,111,100,117,108,101,122,66,108,111,97, - 100,101,114,115,32,116,104,97,116,32,100,101,102,105,110,101, - 32,101,120,101,99,95,109,111,100,117,108,101,40,41,32,109, - 117,115,116,32,97,108,115,111,32,100,101,102,105,110,101,32, - 99,114,101,97,116,101,95,109,111,100,117,108,101,40,41,41, - 7,114,4,0,0,0,114,110,0,0,0,114,150,0,0,0, - 114,80,0,0,0,114,18,0,0,0,114,17,0,0,0,114, - 149,0,0,0,169,2,114,96,0,0,0,114,97,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 16,109,111,100,117,108,101,95,102,114,111,109,95,115,112,101, - 99,46,2,0,0,115,18,0,0,0,0,3,4,1,12,3, - 14,1,12,1,8,2,8,1,10,1,10,1,114,153,0,0, + 115,236,1,0,0,115,114,0,0,0,20,4,2,1,12,1, + 12,1,4,1,2,255,20,3,6,1,8,1,10,2,8,1, + 4,1,6,1,10,2,8,1,6,1,6,11,2,1,10,1, + 12,1,4,1,2,255,20,3,2,1,12,1,12,1,4,1, + 2,255,2,3,10,1,12,1,4,1,2,255,20,3,10,1, + 2,1,12,1,12,1,4,1,2,255,6,3,20,1,2,1, + 12,1,12,1,4,1,2,255,20,3,10,1,2,1,10,1, + 4,3,12,254,2,1,4,1,2,254,4,2,114,161,0,0, 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,4,0,0,0,67,0,0,0,115,106,0,0,0,124, - 0,106,0,100,1,117,0,114,14,100,2,110,4,124,0,106, - 0,125,1,124,0,106,1,100,1,117,0,114,66,124,0,106, - 2,100,1,117,0,114,50,100,3,160,3,124,1,161,1,83, - 0,100,4,160,3,124,1,124,0,106,2,161,2,83,0,110, - 36,124,0,106,4,114,86,100,5,160,3,124,1,124,0,106, + 0,0,3,0,0,0,67,0,0,0,115,82,0,0,0,100, + 1,125,1,116,0,124,0,106,1,100,2,131,2,114,15,124, + 0,106,1,160,2,124,0,161,1,125,1,110,10,116,0,124, + 0,106,1,100,3,131,2,114,25,116,3,100,4,131,1,130, + 1,124,1,100,1,117,0,114,34,116,4,124,0,106,5,131, + 1,125,1,116,6,124,0,124,1,131,2,1,0,124,1,83, + 0,41,5,122,43,67,114,101,97,116,101,32,97,32,109,111, + 100,117,108,101,32,98,97,115,101,100,32,111,110,32,116,104, + 101,32,112,114,111,118,105,100,101,100,32,115,112,101,99,46, + 78,218,13,99,114,101,97,116,101,95,109,111,100,117,108,101, + 218,11,101,120,101,99,95,109,111,100,117,108,101,122,66,108, + 111,97,100,101,114,115,32,116,104,97,116,32,100,101,102,105, + 110,101,32,101,120,101,99,95,109,111,100,117,108,101,40,41, + 32,109,117,115,116,32,97,108,115,111,32,100,101,102,105,110, + 101,32,99,114,101,97,116,101,95,109,111,100,117,108,101,40, + 41,41,7,114,11,0,0,0,114,122,0,0,0,114,162,0, + 0,0,114,87,0,0,0,114,21,0,0,0,114,20,0,0, + 0,114,161,0,0,0,169,2,114,109,0,0,0,114,110,0, + 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, + 0,218,16,109,111,100,117,108,101,95,102,114,111,109,95,115, + 112,101,99,52,2,0,0,115,18,0,0,0,4,3,12,1, + 14,3,12,1,8,1,8,2,10,1,10,1,4,1,114,165, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,4,0,0,0,67,0,0,0,115,100,0,0, + 0,124,0,106,0,100,1,117,0,114,7,100,2,110,2,124, + 0,106,0,125,1,124,0,106,1,100,1,117,0,114,32,124, + 0,106,2,100,1,117,0,114,25,100,3,160,3,124,1,161, + 1,83,0,100,4,160,3,124,1,124,0,106,2,161,2,83, + 0,124,0,106,4,114,42,100,5,160,3,124,1,124,0,106, 1,161,2,83,0,100,6,160,3,124,0,106,0,124,0,106, - 1,161,2,83,0,100,1,83,0,41,7,122,38,82,101,116, - 117,114,110,32,116,104,101,32,114,101,112,114,32,116,111,32, - 117,115,101,32,102,111,114,32,116,104,101,32,109,111,100,117, - 108,101,46,78,114,101,0,0,0,114,102,0,0,0,114,103, - 0,0,0,114,104,0,0,0,250,18,60,109,111,100,117,108, - 101,32,123,33,114,125,32,40,123,125,41,62,41,5,114,17, - 0,0,0,114,114,0,0,0,114,110,0,0,0,114,46,0, - 0,0,114,124,0,0,0,41,2,114,96,0,0,0,114,17, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,108,0,0,0,63,2,0,0,115,16,0,0,0, - 0,3,20,1,10,1,10,1,10,2,16,2,6,1,14,2, - 114,108,0,0,0,99,2,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,10,0,0,0,67,0,0,0,115,250, - 0,0,0,124,0,106,0,125,2,116,1,124,2,131,1,143, - 216,1,0,116,2,106,3,160,4,124,2,161,1,124,1,117, - 1,114,54,100,1,160,5,124,2,161,1,125,3,116,6,124, - 3,124,2,100,2,141,2,130,1,122,132,124,0,106,7,100, - 3,117,0,114,106,124,0,106,8,100,3,117,0,114,90,116, - 6,100,4,124,0,106,0,100,2,141,2,130,1,116,9,124, - 0,124,1,100,5,100,6,141,3,1,0,110,52,116,9,124, - 0,124,1,100,5,100,6,141,3,1,0,116,10,124,0,106, - 7,100,7,131,2,115,146,124,0,106,7,160,11,124,2,161, - 1,1,0,110,12,124,0,106,7,160,12,124,1,161,1,1, - 0,87,0,116,2,106,3,160,13,124,0,106,0,161,1,125, - 1,124,1,116,2,106,3,124,0,106,0,60,0,110,28,116, - 2,106,3,160,13,124,0,106,0,161,1,125,1,124,1,116, - 2,106,3,124,0,106,0,60,0,48,0,87,0,100,3,4, - 0,4,0,131,3,1,0,110,16,49,0,115,236,48,0,1, - 0,1,0,1,0,89,0,1,0,124,1,83,0,41,8,122, - 70,69,120,101,99,117,116,101,32,116,104,101,32,115,112,101, - 99,39,115,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,117,108,101,32,105,110,32,97,110,32,101,120,105,115,116, - 105,110,103,32,109,111,100,117,108,101,39,115,32,110,97,109, - 101,115,112,97,99,101,46,122,30,109,111,100,117,108,101,32, - 123,33,114,125,32,110,111,116,32,105,110,32,115,121,115,46, - 109,111,100,117,108,101,115,114,16,0,0,0,78,250,14,109, - 105,115,115,105,110,103,32,108,111,97,100,101,114,84,114,144, - 0,0,0,114,151,0,0,0,41,14,114,17,0,0,0,114, - 51,0,0,0,114,15,0,0,0,114,93,0,0,0,114,35, - 0,0,0,114,46,0,0,0,114,80,0,0,0,114,110,0, - 0,0,114,117,0,0,0,114,149,0,0,0,114,4,0,0, - 0,218,11,108,111,97,100,95,109,111,100,117,108,101,114,151, - 0,0,0,218,3,112,111,112,41,4,114,96,0,0,0,114, - 97,0,0,0,114,17,0,0,0,218,3,109,115,103,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,94,0, - 0,0,80,2,0,0,115,38,0,0,0,0,2,6,1,10, - 1,16,1,10,1,12,1,2,1,10,1,10,1,14,2,16, - 2,14,1,12,4,14,2,14,4,14,1,14,255,14,1,44, - 1,114,94,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, - 20,1,0,0,122,18,124,0,106,0,160,1,124,0,106,2, - 161,1,1,0,87,0,110,52,1,0,1,0,1,0,124,0, - 106,2,116,3,106,4,118,0,114,64,116,3,106,4,160,5, - 124,0,106,2,161,1,125,1,124,1,116,3,106,4,124,0, - 106,2,60,0,130,0,89,0,110,2,48,0,116,3,106,4, - 160,5,124,0,106,2,161,1,125,1,124,1,116,3,106,4, - 124,0,106,2,60,0,116,6,124,1,100,1,100,0,131,3, - 100,0,117,0,114,146,122,12,124,0,106,0,124,1,95,7, - 87,0,110,18,4,0,116,8,121,144,1,0,1,0,1,0, - 89,0,110,2,48,0,116,6,124,1,100,2,100,0,131,3, - 100,0,117,0,114,222,122,40,124,1,106,9,124,1,95,10, - 116,11,124,1,100,3,131,2,115,200,124,0,106,2,160,12, - 100,4,161,1,100,5,25,0,124,1,95,10,87,0,110,18, - 4,0,116,8,121,220,1,0,1,0,1,0,89,0,110,2, - 48,0,116,6,124,1,100,6,100,0,131,3,100,0,117,0, - 144,1,114,16,122,10,124,0,124,1,95,13,87,0,110,20, - 4,0,116,8,144,1,121,14,1,0,1,0,1,0,89,0, - 110,2,48,0,124,1,83,0,41,7,78,114,99,0,0,0, - 114,146,0,0,0,114,142,0,0,0,114,129,0,0,0,114, - 22,0,0,0,114,106,0,0,0,41,14,114,110,0,0,0, - 114,156,0,0,0,114,17,0,0,0,114,15,0,0,0,114, - 93,0,0,0,114,157,0,0,0,114,6,0,0,0,114,99, - 0,0,0,114,107,0,0,0,114,1,0,0,0,114,146,0, - 0,0,114,4,0,0,0,114,130,0,0,0,114,106,0,0, - 0,114,152,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,25,95,108,111,97,100,95,98,97,99, - 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101, - 110,2,0,0,115,54,0,0,0,0,4,2,1,18,1,6, - 1,12,1,14,1,12,1,8,3,14,1,12,1,16,1,2, - 1,12,1,12,1,6,1,16,1,2,4,8,1,10,1,22, - 1,12,1,6,1,18,1,2,1,10,1,14,1,6,1,114, - 159,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,11,0,0,0,67,0,0,0,115,224,0, - 0,0,124,0,106,0,100,0,117,1,114,30,116,1,124,0, - 106,0,100,1,131,2,115,30,116,2,124,0,131,1,83,0, - 116,3,124,0,131,1,125,1,100,2,124,0,95,4,122,166, - 124,1,116,5,106,6,124,0,106,7,60,0,122,52,124,0, - 106,0,100,0,117,0,114,96,124,0,106,8,100,0,117,0, - 114,108,116,9,100,3,124,0,106,7,100,4,141,2,130,1, - 110,12,124,0,106,0,160,10,124,1,161,1,1,0,87,0, - 110,48,1,0,1,0,1,0,122,14,116,5,106,6,124,0, - 106,7,61,0,87,0,110,18,4,0,116,11,121,150,1,0, - 1,0,1,0,89,0,110,2,48,0,130,0,89,0,110,2, - 48,0,116,5,106,6,160,12,124,0,106,7,161,1,125,1, - 124,1,116,5,106,6,124,0,106,7,60,0,116,13,100,5, - 124,0,106,7,124,0,106,0,131,3,1,0,87,0,100,6, - 124,0,95,4,110,8,100,6,124,0,95,4,48,0,124,1, - 83,0,41,7,78,114,151,0,0,0,84,114,155,0,0,0, - 114,16,0,0,0,122,18,105,109,112,111,114,116,32,123,33, - 114,125,32,35,32,123,33,114,125,70,41,14,114,110,0,0, - 0,114,4,0,0,0,114,159,0,0,0,114,153,0,0,0, - 90,13,95,105,110,105,116,105,97,108,105,122,105,110,103,114, - 15,0,0,0,114,93,0,0,0,114,17,0,0,0,114,117, - 0,0,0,114,80,0,0,0,114,151,0,0,0,114,64,0, - 0,0,114,157,0,0,0,114,77,0,0,0,114,152,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,14,95,108,111,97,100,95,117,110,108,111,99,107,101,100, - 147,2,0,0,115,46,0,0,0,0,2,10,2,12,1,8, - 2,8,5,6,1,2,1,12,1,2,1,10,1,10,1,16, - 3,16,1,6,1,2,1,14,1,12,1,6,1,8,5,14, - 1,12,1,18,2,16,2,114,160,0,0,0,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0, - 0,67,0,0,0,115,54,0,0,0,116,0,124,0,106,1, - 131,1,143,24,1,0,116,2,124,0,131,1,87,0,2,0, - 100,1,4,0,4,0,131,3,1,0,83,0,49,0,115,40, - 48,0,1,0,1,0,1,0,89,0,1,0,100,1,83,0, - 41,2,122,191,82,101,116,117,114,110,32,97,32,110,101,119, - 32,109,111,100,117,108,101,32,111,98,106,101,99,116,44,32, - 108,111,97,100,101,100,32,98,121,32,116,104,101,32,115,112, - 101,99,39,115,32,108,111,97,100,101,114,46,10,10,32,32, - 32,32,84,104,101,32,109,111,100,117,108,101,32,105,115,32, - 110,111,116,32,97,100,100,101,100,32,116,111,32,105,116,115, - 32,112,97,114,101,110,116,46,10,10,32,32,32,32,73,102, - 32,97,32,109,111,100,117,108,101,32,105,115,32,97,108,114, - 101,97,100,121,32,105,110,32,115,121,115,46,109,111,100,117, - 108,101,115,44,32,116,104,97,116,32,101,120,105,115,116,105, - 110,103,32,109,111,100,117,108,101,32,103,101,116,115,10,32, - 32,32,32,99,108,111,98,98,101,114,101,100,46,10,10,32, - 32,32,32,78,41,3,114,51,0,0,0,114,17,0,0,0, - 114,160,0,0,0,41,1,114,96,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,95,0,0,0, - 189,2,0,0,115,4,0,0,0,0,9,12,1,114,95,0, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,64,0,0,0,115,140,0,0,0, - 101,0,90,1,100,0,90,2,100,1,90,3,100,2,90,4, - 101,5,100,3,100,4,132,0,131,1,90,6,101,7,100,20, - 100,6,100,7,132,1,131,1,90,8,101,7,100,21,100,8, - 100,9,132,1,131,1,90,9,101,7,100,10,100,11,132,0, - 131,1,90,10,101,7,100,12,100,13,132,0,131,1,90,11, - 101,7,101,12,100,14,100,15,132,0,131,1,131,1,90,13, - 101,7,101,12,100,16,100,17,132,0,131,1,131,1,90,14, - 101,7,101,12,100,18,100,19,132,0,131,1,131,1,90,15, - 101,7,101,16,131,1,90,17,100,5,83,0,41,22,218,15, - 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,122, - 144,77,101,116,97,32,112,97,116,104,32,105,109,112,111,114, - 116,32,102,111,114,32,98,117,105,108,116,45,105,110,32,109, - 111,100,117,108,101,115,46,10,10,32,32,32,32,65,108,108, - 32,109,101,116,104,111,100,115,32,97,114,101,32,101,105,116, - 104,101,114,32,99,108,97,115,115,32,111,114,32,115,116,97, - 116,105,99,32,109,101,116,104,111,100,115,32,116,111,32,97, - 118,111,105,100,32,116,104,101,32,110,101,101,100,32,116,111, - 10,32,32,32,32,105,110,115,116,97,110,116,105,97,116,101, - 32,116,104,101,32,99,108,97,115,115,46,10,10,32,32,32, - 32,122,8,98,117,105,108,116,45,105,110,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0, - 67,0,0,0,115,22,0,0,0,100,1,124,0,106,0,155, - 2,100,2,116,1,106,2,155,0,100,3,157,5,83,0,41, - 4,250,115,82,101,116,117,114,110,32,114,101,112,114,32,102, - 111,114,32,116,104,101,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,101,32,109,101,116,104, + 1,161,2,83,0,41,7,122,38,82,101,116,117,114,110,32, + 116,104,101,32,114,101,112,114,32,116,111,32,117,115,101,32, + 102,111,114,32,116,104,101,32,109,111,100,117,108,101,46,78, + 114,115,0,0,0,114,116,0,0,0,114,117,0,0,0,114, + 118,0,0,0,250,18,60,109,111,100,117,108,101,32,123,33, + 114,125,32,40,123,125,41,62,41,5,114,20,0,0,0,114, + 126,0,0,0,114,122,0,0,0,114,50,0,0,0,114,136, + 0,0,0,41,2,114,109,0,0,0,114,20,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,119, + 0,0,0,69,2,0,0,115,16,0,0,0,20,3,10,1, + 10,1,10,1,14,2,6,2,14,1,16,2,114,119,0,0, + 0,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,10,0,0,0,67,0,0,0,115,24,1,0,0,124, + 0,106,0,125,2,116,1,124,2,131,1,143,123,1,0,116, + 2,106,3,160,4,124,2,161,1,124,1,117,1,114,27,100, + 1,160,5,124,2,161,1,125,3,116,6,124,3,124,2,100, + 2,141,2,130,1,122,80,124,0,106,7,100,3,117,0,114, + 53,124,0,106,8,100,3,117,0,114,45,116,6,100,4,124, + 0,106,0,100,2,141,2,130,1,116,9,124,0,124,1,100, + 5,100,6,141,3,1,0,110,40,116,9,124,0,124,1,100, + 5,100,6,141,3,1,0,116,10,124,0,106,7,100,7,131, + 2,115,87,116,11,124,0,106,7,131,1,155,0,100,8,157, + 2,125,3,116,12,160,13,124,3,116,14,161,2,1,0,124, + 0,106,7,160,15,124,2,161,1,1,0,110,6,124,0,106, + 7,160,16,124,1,161,1,1,0,87,0,116,2,106,3,160, + 17,124,0,106,0,161,1,125,1,124,1,116,2,106,3,124, + 0,106,0,60,0,110,14,116,2,106,3,160,17,124,0,106, + 0,161,1,125,1,124,1,116,2,106,3,124,0,106,0,60, + 0,119,0,87,0,100,3,4,0,4,0,131,3,1,0,124, + 1,83,0,49,0,115,133,119,1,1,0,1,0,1,0,89, + 0,1,0,124,1,83,0,41,9,122,70,69,120,101,99,117, + 116,101,32,116,104,101,32,115,112,101,99,39,115,32,115,112, + 101,99,105,102,105,101,100,32,109,111,100,117,108,101,32,105, + 110,32,97,110,32,101,120,105,115,116,105,110,103,32,109,111, + 100,117,108,101,39,115,32,110,97,109,101,115,112,97,99,101, + 46,122,30,109,111,100,117,108,101,32,123,33,114,125,32,110, + 111,116,32,105,110,32,115,121,115,46,109,111,100,117,108,101, + 115,114,19,0,0,0,78,250,14,109,105,115,115,105,110,103, + 32,108,111,97,100,101,114,84,114,156,0,0,0,114,163,0, + 0,0,250,55,46,101,120,101,99,95,109,111,100,117,108,101, + 40,41,32,110,111,116,32,102,111,117,110,100,59,32,102,97, + 108,108,105,110,103,32,98,97,99,107,32,116,111,32,108,111, + 97,100,95,109,111,100,117,108,101,40,41,41,18,114,20,0, + 0,0,114,57,0,0,0,114,18,0,0,0,114,105,0,0, + 0,114,38,0,0,0,114,50,0,0,0,114,87,0,0,0, + 114,122,0,0,0,114,129,0,0,0,114,161,0,0,0,114, + 11,0,0,0,114,7,0,0,0,114,101,0,0,0,114,102, + 0,0,0,218,13,73,109,112,111,114,116,87,97,114,110,105, + 110,103,218,11,108,111,97,100,95,109,111,100,117,108,101,114, + 163,0,0,0,218,3,112,111,112,41,4,114,109,0,0,0, + 114,110,0,0,0,114,20,0,0,0,114,108,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,106, + 0,0,0,86,2,0,0,115,50,0,0,0,6,2,10,1, + 16,1,10,1,12,1,2,1,10,1,10,1,14,1,16,2, + 14,2,12,1,16,1,12,2,14,1,12,2,2,128,14,4, + 14,1,14,255,16,1,10,233,4,24,16,232,4,24,114,106, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,8,0,0,0,67,0,0,0,115,14,1,0, + 0,122,9,124,0,106,0,160,1,124,0,106,2,161,1,1, + 0,87,0,110,23,1,0,1,0,1,0,124,0,106,2,116, + 3,106,4,118,0,114,32,116,3,106,4,160,5,124,0,106, + 2,161,1,125,1,124,1,116,3,106,4,124,0,106,2,60, + 0,130,0,116,3,106,4,160,5,124,0,106,2,161,1,125, + 1,124,1,116,3,106,4,124,0,106,2,60,0,116,6,124, + 1,100,1,100,0,131,3,100,0,117,0,114,70,122,6,124, + 0,106,0,124,1,95,7,87,0,110,9,4,0,116,8,121, + 69,1,0,1,0,1,0,89,0,110,1,119,0,116,6,124, + 1,100,2,100,0,131,3,100,0,117,0,114,108,122,20,124, + 1,106,9,124,1,95,10,116,11,124,1,100,3,131,2,115, + 97,124,0,106,2,160,12,100,4,161,1,100,5,25,0,124, + 1,95,10,87,0,110,9,4,0,116,8,121,107,1,0,1, + 0,1,0,89,0,110,1,119,0,116,6,124,1,100,6,100, + 0,131,3,100,0,117,0,114,133,122,6,124,0,124,1,95, + 13,87,0,124,1,83,0,4,0,116,8,121,132,1,0,1, + 0,1,0,89,0,124,1,83,0,119,0,124,1,83,0,41, + 7,78,114,112,0,0,0,114,158,0,0,0,114,154,0,0, + 0,114,141,0,0,0,114,25,0,0,0,114,113,0,0,0, + 41,14,114,122,0,0,0,114,170,0,0,0,114,20,0,0, + 0,114,18,0,0,0,114,105,0,0,0,114,171,0,0,0, + 114,13,0,0,0,114,112,0,0,0,114,2,0,0,0,114, + 9,0,0,0,114,158,0,0,0,114,11,0,0,0,114,142, + 0,0,0,114,113,0,0,0,114,164,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,6,0,0,0,218,25,95,108, + 111,97,100,95,98,97,99,107,119,97,114,100,95,99,111,109, + 112,97,116,105,98,108,101,116,2,0,0,115,66,0,0,0, + 2,3,18,1,6,1,12,1,14,1,12,1,2,1,14,3, + 12,1,16,1,2,1,12,1,12,1,4,1,2,255,16,2, + 2,1,8,4,10,1,18,1,4,128,12,1,4,1,2,255, + 16,2,2,1,8,1,4,3,12,254,2,1,4,1,2,254, + 4,2,114,172,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,11,0,0,0,67,0,0,0, + 115,242,0,0,0,124,0,106,0,100,0,117,1,114,29,116, + 1,124,0,106,0,100,1,131,2,115,29,116,2,124,0,106, + 0,131,1,155,0,100,2,157,2,125,1,116,3,160,4,124, + 1,116,5,161,2,1,0,116,6,124,0,131,1,83,0,116, + 7,124,0,131,1,125,2,100,3,124,0,95,8,122,80,124, + 2,116,9,106,10,124,0,106,11,60,0,122,26,124,0,106, + 0,100,0,117,0,114,62,124,0,106,12,100,0,117,0,114, + 61,116,13,100,4,124,0,106,11,100,5,141,2,130,1,110, + 6,124,0,106,0,160,14,124,2,161,1,1,0,87,0,110, + 20,1,0,1,0,1,0,122,7,116,9,106,10,124,0,106, + 11,61,0,87,0,130,0,4,0,116,15,121,89,1,0,1, + 0,1,0,89,0,130,0,119,0,116,9,106,10,160,16,124, + 0,106,11,161,1,125,2,124,2,116,9,106,10,124,0,106, + 11,60,0,116,17,100,6,124,0,106,11,124,0,106,0,131, + 3,1,0,87,0,100,7,124,0,95,8,124,2,83,0,100, + 7,124,0,95,8,119,0,41,8,78,114,163,0,0,0,114, + 168,0,0,0,84,114,167,0,0,0,114,19,0,0,0,122, + 18,105,109,112,111,114,116,32,123,33,114,125,32,35,32,123, + 33,114,125,70,41,18,114,122,0,0,0,114,11,0,0,0, + 114,7,0,0,0,114,101,0,0,0,114,102,0,0,0,114, + 169,0,0,0,114,172,0,0,0,114,165,0,0,0,90,13, + 95,105,110,105,116,105,97,108,105,122,105,110,103,114,18,0, + 0,0,114,105,0,0,0,114,20,0,0,0,114,129,0,0, + 0,114,87,0,0,0,114,163,0,0,0,114,70,0,0,0, + 114,171,0,0,0,114,83,0,0,0,41,3,114,109,0,0, + 0,114,108,0,0,0,114,110,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,6,0,0,0,218,14,95,108,111,97, + 100,95,117,110,108,111,99,107,101,100,152,2,0,0,115,60, + 0,0,0,10,2,12,2,16,1,12,2,8,1,8,2,6, + 5,2,1,12,1,2,1,10,1,10,1,14,1,2,255,12, + 4,4,128,6,1,2,1,12,1,2,3,12,254,2,1,2, + 1,2,254,14,7,12,1,18,1,6,2,4,2,8,254,114, + 173,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,8,0,0,0,67,0,0,0,115,54,0, + 0,0,116,0,124,0,106,1,131,1,143,12,1,0,116,2, + 124,0,131,1,87,0,2,0,100,1,4,0,4,0,131,3, + 1,0,83,0,49,0,115,20,119,1,1,0,1,0,1,0, + 89,0,1,0,100,1,83,0,41,2,122,191,82,101,116,117, + 114,110,32,97,32,110,101,119,32,109,111,100,117,108,101,32, + 111,98,106,101,99,116,44,32,108,111,97,100,101,100,32,98, + 121,32,116,104,101,32,115,112,101,99,39,115,32,108,111,97, + 100,101,114,46,10,10,32,32,32,32,84,104,101,32,109,111, + 100,117,108,101,32,105,115,32,110,111,116,32,97,100,100,101, + 100,32,116,111,32,105,116,115,32,112,97,114,101,110,116,46, + 10,10,32,32,32,32,73,102,32,97,32,109,111,100,117,108, + 101,32,105,115,32,97,108,114,101,97,100,121,32,105,110,32, + 115,121,115,46,109,111,100,117,108,101,115,44,32,116,104,97, + 116,32,101,120,105,115,116,105,110,103,32,109,111,100,117,108, + 101,32,103,101,116,115,10,32,32,32,32,99,108,111,98,98, + 101,114,101,100,46,10,10,32,32,32,32,78,41,3,114,57, + 0,0,0,114,20,0,0,0,114,173,0,0,0,169,1,114, + 109,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,114,107,0,0,0,197,2,0,0,115,6,0,0, + 0,12,9,6,1,36,255,114,107,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,64,0,0,0,115,140,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,90,4,101,5,100,3,100,4, + 132,0,131,1,90,6,101,7,100,20,100,6,100,7,132,1, + 131,1,90,8,101,7,100,21,100,8,100,9,132,1,131,1, + 90,9,101,5,100,10,100,11,132,0,131,1,90,10,101,5, + 100,12,100,13,132,0,131,1,90,11,101,7,101,12,100,14, + 100,15,132,0,131,1,131,1,90,13,101,7,101,12,100,16, + 100,17,132,0,131,1,131,1,90,14,101,7,101,12,100,18, + 100,19,132,0,131,1,131,1,90,15,101,7,101,16,131,1, + 90,17,100,5,83,0,41,22,218,15,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,122,144,77,101,116,97,32, + 112,97,116,104,32,105,109,112,111,114,116,32,102,111,114,32, + 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, + 46,10,10,32,32,32,32,65,108,108,32,109,101,116,104,111, + 100,115,32,97,114,101,32,101,105,116,104,101,114,32,99,108, + 97,115,115,32,111,114,32,115,116,97,116,105,99,32,109,101, + 116,104,111,100,115,32,116,111,32,97,118,111,105,100,32,116, + 104,101,32,110,101,101,100,32,116,111,10,32,32,32,32,105, + 110,115,116,97,110,116,105,97,116,101,32,116,104,101,32,99, + 108,97,115,115,46,10,10,32,32,32,32,122,8,98,117,105, + 108,116,45,105,110,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,5,0,0,0,67,0,0,0,115,34, + 0,0,0,116,0,160,1,100,1,116,2,161,2,1,0,100, + 2,124,0,106,3,155,2,100,3,116,4,106,5,155,0,100, + 4,157,5,83,0,41,5,250,115,82,101,116,117,114,110,32, + 114,101,112,114,32,102,111,114,32,116,104,101,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 101,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,46,32,32,84,104,101,32,105,109,112, + 111,114,116,32,109,97,99,104,105,110,101,114,121,32,100,111, + 101,115,32,116,104,101,32,106,111,98,32,105,116,115,101,108, + 102,46,10,10,32,32,32,32,32,32,32,32,122,81,66,117, + 105,108,116,105,110,73,109,112,111,114,116,101,114,46,109,111, + 100,117,108,101,95,114,101,112,114,40,41,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,32,97,110,100,32,115,108, + 97,116,101,100,32,102,111,114,32,114,101,109,111,118,97,108, + 32,105,110,32,80,121,116,104,111,110,32,51,46,49,50,122, + 8,60,109,111,100,117,108,101,32,122,2,32,40,122,2,41, + 62,41,6,114,101,0,0,0,114,102,0,0,0,114,103,0, + 0,0,114,9,0,0,0,114,175,0,0,0,114,151,0,0, + 0,169,1,114,110,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,6,0,0,0,114,114,0,0,0,223,2,0,0, + 115,8,0,0,0,6,7,2,1,4,255,22,2,122,27,66, + 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,109, + 111,100,117,108,101,95,114,101,112,114,78,99,4,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0, + 67,0,0,0,115,42,0,0,0,124,2,100,0,117,1,114, + 6,100,0,83,0,116,0,160,1,124,1,161,1,114,19,116, + 2,124,1,124,0,124,0,106,3,100,1,141,3,83,0,100, + 0,83,0,169,2,78,114,150,0,0,0,41,4,114,64,0, + 0,0,90,10,105,115,95,98,117,105,108,116,105,110,114,104, + 0,0,0,114,151,0,0,0,169,4,218,3,99,108,115,114, + 89,0,0,0,218,4,112,97,116,104,218,6,116,97,114,103, + 101,116,114,5,0,0,0,114,5,0,0,0,114,6,0,0, + 0,218,9,102,105,110,100,95,115,112,101,99,234,2,0,0, + 115,10,0,0,0,8,2,4,1,10,1,16,1,4,2,122, + 25,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, + 46,102,105,110,100,95,115,112,101,99,99,3,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, + 0,0,0,115,42,0,0,0,116,0,160,1,100,1,116,2, + 161,2,1,0,124,0,160,3,124,1,124,2,161,2,125,3, + 124,3,100,2,117,1,114,19,124,3,106,4,83,0,100,2, + 83,0,41,3,122,175,70,105,110,100,32,116,104,101,32,98, + 117,105,108,116,45,105,110,32,109,111,100,117,108,101,46,10, + 10,32,32,32,32,32,32,32,32,73,102,32,39,112,97,116, + 104,39,32,105,115,32,101,118,101,114,32,115,112,101,99,105, + 102,105,101,100,32,116,104,101,110,32,116,104,101,32,115,101, + 97,114,99,104,32,105,115,32,99,111,110,115,105,100,101,114, + 101,100,32,97,32,102,97,105,108,117,114,101,46,10,10,32, + 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,84,104,101,32,105,109,112,111,114,116,32,109,97, - 99,104,105,110,101,114,121,32,100,111,101,115,32,116,104,101, - 32,106,111,98,32,105,116,115,101,108,102,46,10,10,32,32, - 32,32,32,32,32,32,122,8,60,109,111,100,117,108,101,32, - 122,2,32,40,122,2,41,62,41,3,114,1,0,0,0,114, - 161,0,0,0,114,139,0,0,0,41,1,114,97,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 100,0,0,0,215,2,0,0,115,2,0,0,0,0,7,122, - 27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, - 46,109,111,100,117,108,101,95,114,101,112,114,78,99,4,0, - 0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0, - 0,0,67,0,0,0,115,46,0,0,0,124,2,100,0,117, - 1,114,12,100,0,83,0,116,0,160,1,124,1,161,1,114, - 38,116,2,124,1,124,0,124,0,106,3,100,1,141,3,83, - 0,100,0,83,0,100,0,83,0,169,2,78,114,138,0,0, - 0,41,4,114,58,0,0,0,90,10,105,115,95,98,117,105, - 108,116,105,110,114,92,0,0,0,114,139,0,0,0,169,4, - 218,3,99,108,115,114,82,0,0,0,218,4,112,97,116,104, - 218,6,116,97,114,103,101,116,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,9,102,105,110,100,95,115,112, - 101,99,224,2,0,0,115,10,0,0,0,0,2,8,1,4, - 1,10,1,16,2,122,25,66,117,105,108,116,105,110,73,109, - 112,111,114,116,101,114,46,102,105,110,100,95,115,112,101,99, - 99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,4,0,0,0,67,0,0,0,115,30,0,0,0,124,0, - 160,0,124,1,124,2,161,2,125,3,124,3,100,1,117,1, - 114,26,124,3,106,1,83,0,100,1,83,0,41,2,122,175, - 70,105,110,100,32,116,104,101,32,98,117,105,108,116,45,105, - 110,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, - 32,32,32,73,102,32,39,112,97,116,104,39,32,105,115,32, - 101,118,101,114,32,115,112,101,99,105,102,105,101,100,32,116, - 104,101,110,32,116,104,101,32,115,101,97,114,99,104,32,105, - 115,32,99,111,110,115,105,100,101,114,101,100,32,97,32,102, - 97,105,108,117,114,101,46,10,10,32,32,32,32,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, - 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, - 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, - 41,2,114,168,0,0,0,114,110,0,0,0,41,4,114,165, - 0,0,0,114,82,0,0,0,114,166,0,0,0,114,96,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,11,102,105,110,100,95,109,111,100,117,108,101,233,2, - 0,0,115,4,0,0,0,0,9,12,1,122,27,66,117,105, - 108,116,105,110,73,109,112,111,114,116,101,114,46,102,105,110, - 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, - 0,115,46,0,0,0,124,1,106,0,116,1,106,2,118,1, - 114,34,116,3,100,1,160,4,124,1,106,0,161,1,124,1, - 106,0,100,2,141,2,130,1,116,5,116,6,106,7,124,1, - 131,2,83,0,41,3,122,24,67,114,101,97,116,101,32,97, - 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101, - 114,78,0,0,0,114,16,0,0,0,41,8,114,17,0,0, - 0,114,15,0,0,0,114,79,0,0,0,114,80,0,0,0, - 114,46,0,0,0,114,68,0,0,0,114,58,0,0,0,90, - 14,99,114,101,97,116,101,95,98,117,105,108,116,105,110,41, - 2,114,30,0,0,0,114,96,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,150,0,0,0,245, - 2,0,0,115,10,0,0,0,0,3,12,1,12,1,4,255, - 6,2,122,29,66,117,105,108,116,105,110,73,109,112,111,114, + 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, + 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, + 32,32,32,32,32,122,106,66,117,105,108,116,105,110,73,109, + 112,111,114,116,101,114,46,102,105,110,100,95,109,111,100,117, + 108,101,40,41,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,32,97,110,100,32,115,108,97,116,101,100,32,102,111, + 114,32,114,101,109,111,118,97,108,32,105,110,32,80,121,116, + 104,111,110,32,51,46,49,50,59,32,117,115,101,32,102,105, + 110,100,95,115,112,101,99,40,41,32,105,110,115,116,101,97, + 100,78,41,5,114,101,0,0,0,114,102,0,0,0,114,103, + 0,0,0,114,183,0,0,0,114,122,0,0,0,41,4,114, + 180,0,0,0,114,89,0,0,0,114,181,0,0,0,114,109, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, + 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,243, + 2,0,0,115,10,0,0,0,6,9,2,2,4,254,12,3, + 18,1,122,27,66,117,105,108,116,105,110,73,109,112,111,114, + 116,101,114,46,102,105,110,100,95,109,111,100,117,108,101,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 4,0,0,0,67,0,0,0,115,46,0,0,0,124,0,106, + 0,116,1,106,2,118,1,114,17,116,3,100,1,160,4,124, + 0,106,0,161,1,124,0,106,0,100,2,141,2,130,1,116, + 5,116,6,106,7,124,0,131,2,83,0,41,3,122,24,67, + 114,101,97,116,101,32,97,32,98,117,105,108,116,45,105,110, + 32,109,111,100,117,108,101,114,85,0,0,0,114,19,0,0, + 0,41,8,114,20,0,0,0,114,18,0,0,0,114,86,0, + 0,0,114,87,0,0,0,114,50,0,0,0,114,74,0,0, + 0,114,64,0,0,0,90,14,99,114,101,97,116,101,95,98, + 117,105,108,116,105,110,114,174,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,6,0,0,0,114,162,0,0,0,2, + 3,0,0,115,10,0,0,0,12,3,12,1,4,1,6,255, + 12,2,122,29,66,117,105,108,116,105,110,73,109,112,111,114, 116,101,114,46,99,114,101,97,116,101,95,109,111,100,117,108, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 101,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,116, - 0,116,1,106,2,124,1,131,2,1,0,100,1,83,0,41, + 0,116,1,106,2,124,0,131,2,1,0,100,1,83,0,41, 2,122,22,69,120,101,99,32,97,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,78,41,3,114,68,0,0, - 0,114,58,0,0,0,90,12,101,120,101,99,95,98,117,105, - 108,116,105,110,41,2,114,30,0,0,0,114,97,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 151,0,0,0,253,2,0,0,115,2,0,0,0,0,3,122, - 27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,2, - 122,57,82,101,116,117,114,110,32,78,111,110,101,32,97,115, - 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101, - 115,32,100,111,32,110,111,116,32,104,97,118,101,32,99,111, - 100,101,32,111,98,106,101,99,116,115,46,78,114,10,0,0, - 0,169,2,114,165,0,0,0,114,82,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,8,103,101, - 116,95,99,111,100,101,2,3,0,0,115,2,0,0,0,0, - 4,122,24,66,117,105,108,116,105,110,73,109,112,111,114,116, - 101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122, - 56,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, - 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, - 32,100,111,32,110,111,116,32,104,97,118,101,32,115,111,117, - 114,99,101,32,99,111,100,101,46,78,114,10,0,0,0,114, - 170,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,10,103,101,116,95,115,111,117,114,99,101,8, - 3,0,0,115,2,0,0,0,0,4,122,26,66,117,105,108, + 105,110,32,109,111,100,117,108,101,78,41,3,114,74,0,0, + 0,114,64,0,0,0,90,12,101,120,101,99,95,98,117,105, + 108,116,105,110,114,177,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,6,0,0,0,114,163,0,0,0,10,3,0, + 0,115,2,0,0,0,16,3,122,27,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,101,120,101,99,95,109, + 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,243,4, + 0,0,0,100,1,83,0,41,2,122,57,82,101,116,117,114, + 110,32,78,111,110,101,32,97,115,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,115,32,100,111,32,110,111, + 116,32,104,97,118,101,32,99,111,100,101,32,111,98,106,101, + 99,116,115,46,78,114,5,0,0,0,169,2,114,180,0,0, + 0,114,89,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,6,0,0,0,218,8,103,101,116,95,99,111,100,101,15, + 3,0,0,243,2,0,0,0,4,4,122,24,66,117,105,108, 116,105,110,73,109,112,111,114,116,101,114,46,103,101,116,95, - 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,83,0,41,2,122,52,82,101,116,117, - 114,110,32,70,97,108,115,101,32,97,115,32,98,117,105,108, - 116,45,105,110,32,109,111,100,117,108,101,115,32,97,114,101, - 32,110,101,118,101,114,32,112,97,99,107,97,103,101,115,46, - 70,114,10,0,0,0,114,170,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,116,0,0,0,14, - 3,0,0,115,2,0,0,0,0,4,122,26,66,117,105,108, - 116,105,110,73,109,112,111,114,116,101,114,46,105,115,95,112, - 97,99,107,97,103,101,41,2,78,78,41,1,78,41,18,114, - 1,0,0,0,114,0,0,0,0,114,2,0,0,0,114,3, - 0,0,0,114,139,0,0,0,218,12,115,116,97,116,105,99, - 109,101,116,104,111,100,114,100,0,0,0,218,11,99,108,97, - 115,115,109,101,116,104,111,100,114,168,0,0,0,114,169,0, - 0,0,114,150,0,0,0,114,151,0,0,0,114,87,0,0, - 0,114,171,0,0,0,114,172,0,0,0,114,116,0,0,0, - 114,98,0,0,0,114,156,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,161, - 0,0,0,204,2,0,0,115,44,0,0,0,8,2,4,7, - 4,2,2,1,10,8,2,1,12,8,2,1,12,11,2,1, - 10,7,2,1,10,4,2,1,2,1,12,4,2,1,2,1, - 12,4,2,1,2,1,12,4,114,161,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,64,0,0,0,115,144,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,90,4,101,5,100,3,100, - 4,132,0,131,1,90,6,101,7,100,22,100,6,100,7,132, - 1,131,1,90,8,101,7,100,23,100,8,100,9,132,1,131, - 1,90,9,101,7,100,10,100,11,132,0,131,1,90,10,101, - 5,100,12,100,13,132,0,131,1,90,11,101,7,100,14,100, - 15,132,0,131,1,90,12,101,7,101,13,100,16,100,17,132, - 0,131,1,131,1,90,14,101,7,101,13,100,18,100,19,132, - 0,131,1,131,1,90,15,101,7,101,13,100,20,100,21,132, - 0,131,1,131,1,90,16,100,5,83,0,41,24,218,14,70, - 114,111,122,101,110,73,109,112,111,114,116,101,114,122,142,77, - 101,116,97,32,112,97,116,104,32,105,109,112,111,114,116,32, - 102,111,114,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,46,10,10,32,32,32,32,65,108,108,32,109,101,116, - 104,111,100,115,32,97,114,101,32,101,105,116,104,101,114,32, - 99,108,97,115,115,32,111,114,32,115,116,97,116,105,99,32, - 109,101,116,104,111,100,115,32,116,111,32,97,118,111,105,100, - 32,116,104,101,32,110,101,101,100,32,116,111,10,32,32,32, - 32,105,110,115,116,97,110,116,105,97,116,101,32,116,104,101, - 32,99,108,97,115,115,46,10,10,32,32,32,32,90,6,102, - 114,111,122,101,110,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,16, - 0,0,0,100,1,160,0,124,0,106,1,116,2,106,3,161, - 2,83,0,41,2,114,162,0,0,0,114,154,0,0,0,41, - 4,114,46,0,0,0,114,1,0,0,0,114,175,0,0,0, - 114,139,0,0,0,41,1,218,1,109,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,100,0,0,0,34,3, - 0,0,115,2,0,0,0,0,7,122,26,70,114,111,122,101, - 110,73,109,112,111,114,116,101,114,46,109,111,100,117,108,101, - 95,114,101,112,114,78,99,4,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115, - 34,0,0,0,116,0,160,1,124,1,161,1,114,26,116,2, - 124,1,124,0,124,0,106,3,100,1,141,3,83,0,100,0, - 83,0,100,0,83,0,114,163,0,0,0,41,4,114,58,0, - 0,0,114,89,0,0,0,114,92,0,0,0,114,139,0,0, - 0,114,164,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,168,0,0,0,43,3,0,0,115,6, - 0,0,0,0,2,10,1,16,2,122,24,70,114,111,122,101, + 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,114,185,0, + 0,0,41,2,122,56,82,101,116,117,114,110,32,78,111,110, + 101,32,97,115,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,115,32,100,111,32,110,111,116,32,104,97,118, + 101,32,115,111,117,114,99,101,32,99,111,100,101,46,78,114, + 5,0,0,0,114,186,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,6,0,0,0,218,10,103,101,116,95,115,111, + 117,114,99,101,21,3,0,0,114,188,0,0,0,122,26,66, + 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,103, + 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,114,185,0,0,0,41,2,122,52,82,101,116,117,114, + 110,32,70,97,108,115,101,32,97,115,32,98,117,105,108,116, + 45,105,110,32,109,111,100,117,108,101,115,32,97,114,101,32, + 110,101,118,101,114,32,112,97,99,107,97,103,101,115,46,70, + 114,5,0,0,0,114,186,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,6,0,0,0,114,128,0,0,0,27,3, + 0,0,114,188,0,0,0,122,26,66,117,105,108,116,105,110, + 73,109,112,111,114,116,101,114,46,105,115,95,112,97,99,107, + 97,103,101,169,2,78,78,114,0,0,0,0,41,18,114,9, + 0,0,0,114,8,0,0,0,114,1,0,0,0,114,10,0, + 0,0,114,151,0,0,0,218,12,115,116,97,116,105,99,109, + 101,116,104,111,100,114,114,0,0,0,218,11,99,108,97,115, + 115,109,101,116,104,111,100,114,183,0,0,0,114,184,0,0, + 0,114,162,0,0,0,114,163,0,0,0,114,95,0,0,0, + 114,187,0,0,0,114,189,0,0,0,114,128,0,0,0,114, + 111,0,0,0,114,170,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,114,175,0, + 0,0,212,2,0,0,115,46,0,0,0,8,0,4,2,4, + 7,2,2,10,1,2,10,12,1,2,8,12,1,2,14,10, + 1,2,7,10,1,2,4,2,1,12,1,2,4,2,1,12, + 1,2,4,2,1,12,1,12,4,114,175,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,64,0,0,0,115,144,0,0,0,101,0,90,1, + 100,0,90,2,100,1,90,3,100,2,90,4,101,5,100,3, + 100,4,132,0,131,1,90,6,101,7,100,22,100,6,100,7, + 132,1,131,1,90,8,101,7,100,23,100,8,100,9,132,1, + 131,1,90,9,101,5,100,10,100,11,132,0,131,1,90,10, + 101,5,100,12,100,13,132,0,131,1,90,11,101,7,100,14, + 100,15,132,0,131,1,90,12,101,7,101,13,100,16,100,17, + 132,0,131,1,131,1,90,14,101,7,101,13,100,18,100,19, + 132,0,131,1,131,1,90,15,101,7,101,13,100,20,100,21, + 132,0,131,1,131,1,90,16,100,5,83,0,41,24,218,14, + 70,114,111,122,101,110,73,109,112,111,114,116,101,114,122,142, + 77,101,116,97,32,112,97,116,104,32,105,109,112,111,114,116, + 32,102,111,114,32,102,114,111,122,101,110,32,109,111,100,117, + 108,101,115,46,10,10,32,32,32,32,65,108,108,32,109,101, + 116,104,111,100,115,32,97,114,101,32,101,105,116,104,101,114, + 32,99,108,97,115,115,32,111,114,32,115,116,97,116,105,99, + 32,109,101,116,104,111,100,115,32,116,111,32,97,118,111,105, + 100,32,116,104,101,32,110,101,101,100,32,116,111,10,32,32, + 32,32,105,110,115,116,97,110,116,105,97,116,101,32,116,104, + 101,32,99,108,97,115,115,46,10,10,32,32,32,32,90,6, + 102,114,111,122,101,110,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,4,0,0,0,67,0,0,0,115, + 28,0,0,0,116,0,160,1,100,1,116,2,161,2,1,0, + 100,2,160,3,124,0,106,4,116,5,106,6,161,2,83,0, + 41,3,114,176,0,0,0,122,80,70,114,111,122,101,110,73, + 109,112,111,114,116,101,114,46,109,111,100,117,108,101,95,114, + 101,112,114,40,41,32,105,115,32,100,101,112,114,101,99,97, + 116,101,100,32,97,110,100,32,115,108,97,116,101,100,32,102, + 111,114,32,114,101,109,111,118,97,108,32,105,110,32,80,121, + 116,104,111,110,32,51,46,49,50,114,166,0,0,0,41,7, + 114,101,0,0,0,114,102,0,0,0,114,103,0,0,0,114, + 50,0,0,0,114,9,0,0,0,114,193,0,0,0,114,151, + 0,0,0,41,1,218,1,109,114,5,0,0,0,114,5,0, + 0,0,114,6,0,0,0,114,114,0,0,0,47,3,0,0, + 115,8,0,0,0,6,7,2,1,4,255,16,2,122,26,70, + 114,111,122,101,110,73,109,112,111,114,116,101,114,46,109,111, + 100,117,108,101,95,114,101,112,114,78,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,67, + 0,0,0,115,30,0,0,0,116,0,160,1,124,1,161,1, + 114,13,116,2,124,1,124,0,124,0,106,3,100,1,141,3, + 83,0,100,0,83,0,114,178,0,0,0,41,4,114,64,0, + 0,0,114,98,0,0,0,114,104,0,0,0,114,151,0,0, + 0,114,179,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,6,0,0,0,114,183,0,0,0,58,3,0,0,115,6, + 0,0,0,10,2,16,1,4,2,122,24,70,114,111,122,101, 110,73,109,112,111,114,116,101,114,46,102,105,110,100,95,115, 112,101,99,99,3,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,67,0,0,0,115,18,0,0, - 0,116,0,160,1,124,1,161,1,114,14,124,0,83,0,100, - 1,83,0,41,2,122,93,70,105,110,100,32,97,32,102,114, - 111,122,101,110,32,109,111,100,117,108,101,46,10,10,32,32, - 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111, - 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 32,32,85,115,101,32,102,105,110,100,95,115,112,101,99,40, - 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32, - 32,32,32,32,78,41,2,114,58,0,0,0,114,89,0,0, - 0,41,3,114,165,0,0,0,114,82,0,0,0,114,166,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,169,0,0,0,50,3,0,0,115,2,0,0,0,0, - 7,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101, - 114,46,102,105,110,100,95,109,111,100,117,108,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,122,42,85,115,101,32,100,101,102,97,117,108,116,32,115, - 101,109,97,110,116,105,99,115,32,102,111,114,32,109,111,100, - 117,108,101,32,99,114,101,97,116,105,111,110,46,78,114,10, - 0,0,0,41,2,114,165,0,0,0,114,96,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,150, - 0,0,0,59,3,0,0,115,2,0,0,0,0,2,122,28, - 70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,99, - 114,101,97,116,101,95,109,111,100,117,108,101,99,1,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, - 0,67,0,0,0,115,64,0,0,0,124,0,106,0,106,1, - 125,1,116,2,160,3,124,1,161,1,115,36,116,4,100,1, - 160,5,124,1,161,1,124,1,100,2,141,2,130,1,116,6, - 116,2,106,7,124,1,131,2,125,2,116,8,124,2,124,0, - 106,9,131,2,1,0,100,0,83,0,114,88,0,0,0,41, - 10,114,106,0,0,0,114,17,0,0,0,114,58,0,0,0, - 114,89,0,0,0,114,80,0,0,0,114,46,0,0,0,114, - 68,0,0,0,218,17,103,101,116,95,102,114,111,122,101,110, - 95,111,98,106,101,99,116,218,4,101,120,101,99,114,7,0, - 0,0,41,3,114,97,0,0,0,114,17,0,0,0,218,4, - 99,111,100,101,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,151,0,0,0,63,3,0,0,115,14,0,0, - 0,0,2,8,1,10,1,10,1,2,255,6,2,12,1,122, - 26,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, - 101,120,101,99,95,109,111,100,117,108,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,10,0,0,0,116,0,124,0,124,1,131, - 2,83,0,41,1,122,95,76,111,97,100,32,97,32,102,114, - 111,122,101,110,32,109,111,100,117,108,101,46,10,10,32,32, - 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111, - 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 32,32,85,115,101,32,101,120,101,99,95,109,111,100,117,108, - 101,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, - 32,32,32,32,32,32,41,1,114,98,0,0,0,114,170,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,156,0,0,0,72,3,0,0,115,2,0,0,0,0, - 7,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101, - 114,46,108,111,97,100,95,109,111,100,117,108,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, - 0,0,67,0,0,0,115,10,0,0,0,116,0,160,1,124, - 1,161,1,83,0,41,1,122,45,82,101,116,117,114,110,32, - 116,104,101,32,99,111,100,101,32,111,98,106,101,99,116,32, - 102,111,114,32,116,104,101,32,102,114,111,122,101,110,32,109, - 111,100,117,108,101,46,41,2,114,58,0,0,0,114,177,0, - 0,0,114,170,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,171,0,0,0,81,3,0,0,115, - 2,0,0,0,0,4,122,23,70,114,111,122,101,110,73,109, - 112,111,114,116,101,114,46,103,101,116,95,99,111,100,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, - 0,41,2,122,54,82,101,116,117,114,110,32,78,111,110,101, - 32,97,115,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,32,100,111,32,110,111,116,32,104,97,118,101,32,115, - 111,117,114,99,101,32,99,111,100,101,46,78,114,10,0,0, - 0,114,170,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,172,0,0,0,87,3,0,0,115,2, - 0,0,0,0,4,122,25,70,114,111,122,101,110,73,109,112, - 111,114,116,101,114,46,103,101,116,95,115,111,117,114,99,101, + 3,0,0,0,4,0,0,0,67,0,0,0,115,30,0,0, + 0,116,0,160,1,100,1,116,2,161,2,1,0,116,3,160, + 4,124,1,161,1,114,13,124,0,83,0,100,2,83,0,41, + 3,122,93,70,105,110,100,32,97,32,102,114,111,122,101,110, + 32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32, + 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, + 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, + 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, + 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, + 122,105,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,102,105,110,100,95,109,111,100,117,108,101,40,41,32,105, + 115,32,100,101,112,114,101,99,97,116,101,100,32,97,110,100, + 32,115,108,97,116,101,100,32,102,111,114,32,114,101,109,111, + 118,97,108,32,105,110,32,80,121,116,104,111,110,32,51,46, + 49,50,59,32,117,115,101,32,102,105,110,100,95,115,112,101, + 99,40,41,32,105,110,115,116,101,97,100,78,41,5,114,101, + 0,0,0,114,102,0,0,0,114,103,0,0,0,114,64,0, + 0,0,114,98,0,0,0,41,3,114,180,0,0,0,114,89, + 0,0,0,114,181,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,6,0,0,0,114,184,0,0,0,65,3,0,0, + 115,8,0,0,0,6,7,2,2,4,254,18,3,122,26,70, + 114,111,122,101,110,73,109,112,111,114,116,101,114,46,102,105, + 110,100,95,109,111,100,117,108,101,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,1,0,0,0,67,0, + 0,0,114,185,0,0,0,41,2,122,42,85,115,101,32,100, + 101,102,97,117,108,116,32,115,101,109,97,110,116,105,99,115, + 32,102,111,114,32,109,111,100,117,108,101,32,99,114,101,97, + 116,105,111,110,46,78,114,5,0,0,0,114,174,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,114, + 162,0,0,0,77,3,0,0,115,2,0,0,0,4,0,122, + 28,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, + 99,114,101,97,116,101,95,109,111,100,117,108,101,99,1,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,64,0,0,0,124,0,106,0,106, + 1,125,1,116,2,160,3,124,1,161,1,115,18,116,4,100, + 1,160,5,124,1,161,1,124,1,100,2,141,2,130,1,116, + 6,116,2,106,7,124,1,131,2,125,2,116,8,124,2,124, + 0,106,9,131,2,1,0,100,0,83,0,114,97,0,0,0, + 41,10,114,113,0,0,0,114,20,0,0,0,114,64,0,0, + 0,114,98,0,0,0,114,87,0,0,0,114,50,0,0,0, + 114,74,0,0,0,218,17,103,101,116,95,102,114,111,122,101, + 110,95,111,98,106,101,99,116,218,4,101,120,101,99,114,14, + 0,0,0,41,3,114,110,0,0,0,114,20,0,0,0,218, + 4,99,111,100,101,114,5,0,0,0,114,5,0,0,0,114, + 6,0,0,0,114,163,0,0,0,81,3,0,0,115,14,0, + 0,0,8,2,10,1,10,1,2,1,6,255,12,2,16,1, + 122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, + 0,67,0,0,0,115,10,0,0,0,116,0,124,0,124,1, + 131,2,83,0,41,1,122,95,76,111,97,100,32,97,32,102, + 114,111,122,101,110,32,109,111,100,117,108,101,46,10,10,32, + 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, + 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 46,32,32,85,115,101,32,101,120,101,99,95,109,111,100,117, + 108,101,40,41,32,105,110,115,116,101,97,100,46,10,10,32, + 32,32,32,32,32,32,32,41,1,114,111,0,0,0,114,186, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, + 0,0,114,170,0,0,0,90,3,0,0,115,2,0,0,0, + 10,8,122,26,70,114,111,122,101,110,73,109,112,111,114,116, + 101,114,46,108,111,97,100,95,109,111,100,117,108,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,67,0,0,0,243,10,0,0,0,116,0,160,1, + 124,1,161,1,83,0,41,1,122,45,82,101,116,117,114,110, + 32,116,104,101,32,99,111,100,101,32,111,98,106,101,99,116, + 32,102,111,114,32,116,104,101,32,102,114,111,122,101,110,32, + 109,111,100,117,108,101,46,41,2,114,64,0,0,0,114,195, + 0,0,0,114,186,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,6,0,0,0,114,187,0,0,0,100,3,0,0, + 243,2,0,0,0,10,4,122,23,70,114,111,122,101,110,73, + 109,112,111,114,116,101,114,46,103,101,116,95,99,111,100,101, 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,3,0,0,0,67,0,0,0,115,10,0,0,0,116,0, - 160,1,124,1,161,1,83,0,41,1,122,46,82,101,116,117, - 114,110,32,84,114,117,101,32,105,102,32,116,104,101,32,102, - 114,111,122,101,110,32,109,111,100,117,108,101,32,105,115,32, - 97,32,112,97,99,107,97,103,101,46,41,2,114,58,0,0, - 0,90,17,105,115,95,102,114,111,122,101,110,95,112,97,99, - 107,97,103,101,114,170,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,116,0,0,0,93,3,0, - 0,115,2,0,0,0,0,4,122,25,70,114,111,122,101,110, - 73,109,112,111,114,116,101,114,46,105,115,95,112,97,99,107, - 97,103,101,41,2,78,78,41,1,78,41,17,114,1,0,0, - 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, - 114,139,0,0,0,114,173,0,0,0,114,100,0,0,0,114, - 174,0,0,0,114,168,0,0,0,114,169,0,0,0,114,150, - 0,0,0,114,151,0,0,0,114,156,0,0,0,114,91,0, - 0,0,114,171,0,0,0,114,172,0,0,0,114,116,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,175,0,0,0,23,3,0,0,115,46, - 0,0,0,8,2,4,7,4,2,2,1,10,8,2,1,12, - 6,2,1,12,8,2,1,10,3,2,1,10,8,2,1,10, - 8,2,1,2,1,12,4,2,1,2,1,12,4,2,1,2, - 1,114,175,0,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115, - 32,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5, - 100,6,83,0,41,7,218,18,95,73,109,112,111,114,116,76, - 111,99,107,67,111,110,116,101,120,116,122,36,67,111,110,116, - 101,120,116,32,109,97,110,97,103,101,114,32,102,111,114,32, - 116,104,101,32,105,109,112,111,114,116,32,108,111,99,107,46, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,2,0,0,0,67,0,0,0,115,12,0,0,0,116,0, - 160,1,161,0,1,0,100,1,83,0,41,2,122,24,65,99, - 113,117,105,114,101,32,116,104,101,32,105,109,112,111,114,116, - 32,108,111,99,107,46,78,41,2,114,58,0,0,0,114,59, - 0,0,0,114,48,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,55,0,0,0,106,3,0,0, - 115,2,0,0,0,0,2,122,28,95,73,109,112,111,114,116, - 76,111,99,107,67,111,110,116,101,120,116,46,95,95,101,110, - 116,101,114,95,95,99,4,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,2,0,0,0,67,0,0,0,115,12, - 0,0,0,116,0,160,1,161,0,1,0,100,1,83,0,41, - 2,122,60,82,101,108,101,97,115,101,32,116,104,101,32,105, - 109,112,111,114,116,32,108,111,99,107,32,114,101,103,97,114, - 100,108,101,115,115,32,111,102,32,97,110,121,32,114,97,105, - 115,101,100,32,101,120,99,101,112,116,105,111,110,115,46,78, - 41,2,114,58,0,0,0,114,61,0,0,0,41,4,114,30, - 0,0,0,218,8,101,120,99,95,116,121,112,101,218,9,101, - 120,99,95,118,97,108,117,101,218,13,101,120,99,95,116,114, - 97,99,101,98,97,99,107,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,57,0,0,0,110,3,0,0,115, - 2,0,0,0,0,2,122,27,95,73,109,112,111,114,116,76, - 111,99,107,67,111,110,116,101,120,116,46,95,95,101,120,105, - 116,95,95,78,41,6,114,1,0,0,0,114,0,0,0,0, - 114,2,0,0,0,114,3,0,0,0,114,55,0,0,0,114, - 57,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,180,0,0,0,102,3,0, - 0,115,6,0,0,0,8,2,4,2,8,4,114,180,0,0, - 0,99,3,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,5,0,0,0,67,0,0,0,115,64,0,0,0,124, - 1,160,0,100,1,124,2,100,2,24,0,161,2,125,3,116, - 1,124,3,131,1,124,2,107,0,114,36,116,2,100,3,131, - 1,130,1,124,3,100,4,25,0,125,4,124,0,114,60,100, - 5,160,3,124,4,124,0,161,2,83,0,124,4,83,0,41, - 6,122,50,82,101,115,111,108,118,101,32,97,32,114,101,108, - 97,116,105,118,101,32,109,111,100,117,108,101,32,110,97,109, - 101,32,116,111,32,97,110,32,97,98,115,111,108,117,116,101, - 32,111,110,101,46,114,129,0,0,0,114,39,0,0,0,122, - 50,97,116,116,101,109,112,116,101,100,32,114,101,108,97,116, - 105,118,101,32,105,109,112,111,114,116,32,98,101,121,111,110, - 100,32,116,111,112,45,108,101,118,101,108,32,112,97,99,107, - 97,103,101,114,22,0,0,0,250,5,123,125,46,123,125,41, - 4,218,6,114,115,112,108,105,116,218,3,108,101,110,114,80, - 0,0,0,114,46,0,0,0,41,5,114,17,0,0,0,218, - 7,112,97,99,107,97,103,101,218,5,108,101,118,101,108,90, - 4,98,105,116,115,90,4,98,97,115,101,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,13,95,114,101,115, - 111,108,118,101,95,110,97,109,101,115,3,0,0,115,10,0, - 0,0,0,2,16,1,12,1,8,1,8,1,114,189,0,0, - 0,99,3,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,4,0,0,0,67,0,0,0,115,34,0,0,0,124, - 0,160,0,124,1,124,2,161,2,125,3,124,3,100,0,117, - 0,114,24,100,0,83,0,116,1,124,1,124,3,131,2,83, - 0,114,13,0,0,0,41,2,114,169,0,0,0,114,92,0, - 0,0,41,4,218,6,102,105,110,100,101,114,114,17,0,0, - 0,114,166,0,0,0,114,110,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,17,95,102,105,110, - 100,95,115,112,101,99,95,108,101,103,97,99,121,124,3,0, - 0,115,8,0,0,0,0,3,12,1,8,1,4,1,114,191, - 0,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, - 10,0,0,0,10,0,0,0,67,0,0,0,115,32,1,0, - 0,116,0,106,1,125,3,124,3,100,1,117,0,114,22,116, - 2,100,2,131,1,130,1,124,3,115,38,116,3,160,4,100, - 3,116,5,161,2,1,0,124,0,116,0,106,6,118,0,125, - 4,124,3,68,0,93,230,125,5,116,7,131,0,143,94,1, - 0,122,10,124,5,106,8,125,6,87,0,110,54,4,0,116, - 9,121,128,1,0,1,0,1,0,116,10,124,5,124,0,124, - 1,131,3,125,7,124,7,100,1,117,0,114,124,89,0,87, - 0,100,1,4,0,4,0,131,3,1,0,113,52,89,0,110, - 14,48,0,124,6,124,0,124,1,124,2,131,3,125,7,87, - 0,100,1,4,0,4,0,131,3,1,0,110,16,49,0,115, - 162,48,0,1,0,1,0,1,0,89,0,1,0,124,7,100, - 1,117,1,114,52,124,4,144,1,115,18,124,0,116,0,106, - 6,118,0,144,1,114,18,116,0,106,6,124,0,25,0,125, - 8,122,10,124,8,106,11,125,9,87,0,110,26,4,0,116, - 9,121,244,1,0,1,0,1,0,124,7,6,0,89,0,2, - 0,1,0,83,0,48,0,124,9,100,1,117,0,144,1,114, - 8,124,7,2,0,1,0,83,0,124,9,2,0,1,0,83, - 0,113,52,124,7,2,0,1,0,83,0,113,52,100,1,83, - 0,41,4,122,21,70,105,110,100,32,97,32,109,111,100,117, - 108,101,39,115,32,115,112,101,99,46,78,122,53,115,121,115, - 46,109,101,116,97,95,112,97,116,104,32,105,115,32,78,111, - 110,101,44,32,80,121,116,104,111,110,32,105,115,32,108,105, - 107,101,108,121,32,115,104,117,116,116,105,110,103,32,100,111, - 119,110,122,22,115,121,115,46,109,101,116,97,95,112,97,116, - 104,32,105,115,32,101,109,112,116,121,41,12,114,15,0,0, - 0,218,9,109,101,116,97,95,112,97,116,104,114,80,0,0, - 0,218,9,95,119,97,114,110,105,110,103,115,218,4,119,97, - 114,110,218,13,73,109,112,111,114,116,87,97,114,110,105,110, - 103,114,93,0,0,0,114,180,0,0,0,114,168,0,0,0, - 114,107,0,0,0,114,191,0,0,0,114,106,0,0,0,41, - 10,114,17,0,0,0,114,166,0,0,0,114,167,0,0,0, - 114,192,0,0,0,90,9,105,115,95,114,101,108,111,97,100, - 114,190,0,0,0,114,168,0,0,0,114,96,0,0,0,114, - 97,0,0,0,114,106,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,10,95,102,105,110,100,95, - 115,112,101,99,133,3,0,0,115,54,0,0,0,0,2,6, - 1,8,2,8,3,4,1,12,5,10,1,8,1,8,1,2, - 1,10,1,12,1,12,1,8,1,22,2,42,1,8,2,18, - 1,10,1,2,1,10,1,12,4,14,2,10,1,8,2,10, - 2,10,2,114,196,0,0,0,99,3,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,5,0,0,0,67,0,0, - 0,115,108,0,0,0,116,0,124,0,116,1,131,2,115,28, - 116,2,100,1,160,3,116,4,124,0,131,1,161,1,131,1, - 130,1,124,2,100,2,107,0,114,44,116,5,100,3,131,1, - 130,1,124,2,100,2,107,4,114,84,116,0,124,1,116,1, - 131,2,115,72,116,2,100,4,131,1,130,1,110,12,124,1, - 115,84,116,6,100,5,131,1,130,1,124,0,115,104,124,2, - 100,2,107,2,114,104,116,5,100,6,131,1,130,1,100,7, - 83,0,41,8,122,28,86,101,114,105,102,121,32,97,114,103, - 117,109,101,110,116,115,32,97,114,101,32,34,115,97,110,101, - 34,46,122,31,109,111,100,117,108,101,32,110,97,109,101,32, - 109,117,115,116,32,98,101,32,115,116,114,44,32,110,111,116, - 32,123,125,114,22,0,0,0,122,18,108,101,118,101,108,32, - 109,117,115,116,32,98,101,32,62,61,32,48,122,31,95,95, - 112,97,99,107,97,103,101,95,95,32,110,111,116,32,115,101, - 116,32,116,111,32,97,32,115,116,114,105,110,103,122,54,97, - 116,116,101,109,112,116,101,100,32,114,101,108,97,116,105,118, - 101,32,105,109,112,111,114,116,32,119,105,116,104,32,110,111, - 32,107,110,111,119,110,32,112,97,114,101,110,116,32,112,97, - 99,107,97,103,101,122,17,69,109,112,116,121,32,109,111,100, - 117,108,101,32,110,97,109,101,78,41,7,218,10,105,115,105, - 110,115,116,97,110,99,101,218,3,115,116,114,218,9,84,121, - 112,101,69,114,114,111,114,114,46,0,0,0,114,14,0,0, - 0,218,10,86,97,108,117,101,69,114,114,111,114,114,80,0, - 0,0,169,3,114,17,0,0,0,114,187,0,0,0,114,188, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,13,95,115,97,110,105,116,121,95,99,104,101,99, - 107,180,3,0,0,115,22,0,0,0,0,2,10,1,18,1, - 8,1,8,1,8,1,10,1,10,1,4,1,8,2,12,1, - 114,202,0,0,0,122,16,78,111,32,109,111,100,117,108,101, - 32,110,97,109,101,100,32,122,4,123,33,114,125,99,2,0, - 0,0,0,0,0,0,0,0,0,0,9,0,0,0,8,0, - 0,0,67,0,0,0,115,22,1,0,0,100,0,125,2,124, - 0,160,0,100,1,161,1,100,2,25,0,125,3,124,3,114, - 132,124,3,116,1,106,2,118,1,114,42,116,3,124,1,124, - 3,131,2,1,0,124,0,116,1,106,2,118,0,114,62,116, - 1,106,2,124,0,25,0,83,0,116,1,106,2,124,3,25, - 0,125,4,122,10,124,4,106,4,125,2,87,0,110,48,4, - 0,116,5,121,130,1,0,1,0,1,0,116,6,100,3,23, - 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124, - 0,100,4,141,2,100,0,130,2,89,0,110,2,48,0,116, - 9,124,0,124,2,131,2,125,6,124,6,100,0,117,0,114, - 170,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141, - 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,144, - 1,114,18,116,1,106,2,124,3,25,0,125,4,124,0,160, - 0,100,1,161,1,100,5,25,0,125,8,122,16,116,11,124, - 4,124,8,124,7,131,3,1,0,87,0,110,48,4,0,116, - 5,144,1,121,16,1,0,1,0,1,0,100,6,124,3,155, - 2,100,7,124,8,155,2,157,4,125,5,116,12,160,13,124, - 5,116,14,161,2,1,0,89,0,110,2,48,0,124,7,83, - 0,41,8,78,114,129,0,0,0,114,22,0,0,0,122,23, - 59,32,123,33,114,125,32,105,115,32,110,111,116,32,97,32, - 112,97,99,107,97,103,101,114,16,0,0,0,233,2,0,0, - 0,122,27,67,97,110,110,111,116,32,115,101,116,32,97,110, - 32,97,116,116,114,105,98,117,116,101,32,111,110,32,122,18, - 32,102,111,114,32,99,104,105,108,100,32,109,111,100,117,108, - 101,32,41,15,114,130,0,0,0,114,15,0,0,0,114,93, - 0,0,0,114,68,0,0,0,114,142,0,0,0,114,107,0, - 0,0,218,8,95,69,82,82,95,77,83,71,114,46,0,0, - 0,218,19,77,111,100,117,108,101,78,111,116,70,111,117,110, - 100,69,114,114,111,114,114,196,0,0,0,114,160,0,0,0, - 114,5,0,0,0,114,193,0,0,0,114,194,0,0,0,114, - 195,0,0,0,41,9,114,17,0,0,0,218,7,105,109,112, - 111,114,116,95,114,166,0,0,0,114,131,0,0,0,90,13, - 112,97,114,101,110,116,95,109,111,100,117,108,101,114,158,0, - 0,0,114,96,0,0,0,114,97,0,0,0,90,5,99,104, - 105,108,100,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,23,95,102,105,110,100,95,97,110,100,95,108,111, - 97,100,95,117,110,108,111,99,107,101,100,199,3,0,0,115, - 52,0,0,0,0,1,4,1,14,1,4,1,10,1,10,2, - 10,1,10,1,10,1,2,1,10,1,12,1,16,1,20,1, - 10,1,8,1,20,2,8,1,6,2,10,1,14,1,2,1, - 16,1,14,1,16,1,18,1,114,207,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0, - 0,0,67,0,0,0,115,128,0,0,0,116,0,124,0,131, - 1,143,62,1,0,116,1,106,2,160,3,124,0,116,4,161, - 2,125,2,124,2,116,4,117,0,114,56,116,5,124,0,124, - 1,131,2,87,0,2,0,100,1,4,0,4,0,131,3,1, - 0,83,0,87,0,100,1,4,0,4,0,131,3,1,0,110, - 16,49,0,115,76,48,0,1,0,1,0,1,0,89,0,1, - 0,124,2,100,1,117,0,114,116,100,2,160,6,124,0,161, - 1,125,3,116,7,124,3,124,0,100,3,141,2,130,1,116, - 8,124,0,131,1,1,0,124,2,83,0,41,4,122,25,70, - 105,110,100,32,97,110,100,32,108,111,97,100,32,116,104,101, - 32,109,111,100,117,108,101,46,78,122,40,105,109,112,111,114, - 116,32,111,102,32,123,125,32,104,97,108,116,101,100,59,32, - 78,111,110,101,32,105,110,32,115,121,115,46,109,111,100,117, - 108,101,115,114,16,0,0,0,41,9,114,51,0,0,0,114, - 15,0,0,0,114,93,0,0,0,114,35,0,0,0,218,14, - 95,78,69,69,68,83,95,76,79,65,68,73,78,71,114,207, - 0,0,0,114,46,0,0,0,114,205,0,0,0,114,66,0, - 0,0,41,4,114,17,0,0,0,114,206,0,0,0,114,97, - 0,0,0,114,76,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,14,95,102,105,110,100,95,97, - 110,100,95,108,111,97,100,234,3,0,0,115,22,0,0,0, - 0,2,10,1,14,1,8,1,54,2,8,1,4,1,2,255, - 4,2,12,2,8,1,114,209,0,0,0,114,22,0,0,0, - 99,3,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,4,0,0,0,67,0,0,0,115,42,0,0,0,116,0, - 124,0,124,1,124,2,131,3,1,0,124,2,100,1,107,4, - 114,32,116,1,124,0,124,1,124,2,131,3,125,0,116,2, - 124,0,116,3,131,2,83,0,41,2,97,50,1,0,0,73, - 109,112,111,114,116,32,97,110,100,32,114,101,116,117,114,110, - 32,116,104,101,32,109,111,100,117,108,101,32,98,97,115,101, - 100,32,111,110,32,105,116,115,32,110,97,109,101,44,32,116, - 104,101,32,112,97,99,107,97,103,101,32,116,104,101,32,99, - 97,108,108,32,105,115,10,32,32,32,32,98,101,105,110,103, - 32,109,97,100,101,32,102,114,111,109,44,32,97,110,100,32, - 116,104,101,32,108,101,118,101,108,32,97,100,106,117,115,116, - 109,101,110,116,46,10,10,32,32,32,32,84,104,105,115,32, - 102,117,110,99,116,105,111,110,32,114,101,112,114,101,115,101, - 110,116,115,32,116,104,101,32,103,114,101,97,116,101,115,116, - 32,99,111,109,109,111,110,32,100,101,110,111,109,105,110,97, - 116,111,114,32,111,102,32,102,117,110,99,116,105,111,110,97, - 108,105,116,121,10,32,32,32,32,98,101,116,119,101,101,110, - 32,105,109,112,111,114,116,95,109,111,100,117,108,101,32,97, - 110,100,32,95,95,105,109,112,111,114,116,95,95,46,32,84, - 104,105,115,32,105,110,99,108,117,100,101,115,32,115,101,116, - 116,105,110,103,32,95,95,112,97,99,107,97,103,101,95,95, - 32,105,102,10,32,32,32,32,116,104,101,32,108,111,97,100, - 101,114,32,100,105,100,32,110,111,116,46,10,10,32,32,32, - 32,114,22,0,0,0,41,4,114,202,0,0,0,114,189,0, - 0,0,114,209,0,0,0,218,11,95,103,99,100,95,105,109, - 112,111,114,116,114,201,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,210,0,0,0,250,3,0, - 0,115,8,0,0,0,0,9,12,1,8,1,12,1,114,210, - 0,0,0,169,1,218,9,114,101,99,117,114,115,105,118,101, - 99,3,0,0,0,0,0,0,0,1,0,0,0,8,0,0, - 0,11,0,0,0,67,0,0,0,115,232,0,0,0,124,1, - 68,0,93,222,125,4,116,0,124,4,116,1,131,2,115,66, - 124,3,114,34,124,0,106,2,100,1,23,0,125,5,110,4, - 100,2,125,5,116,3,100,3,124,5,155,0,100,4,116,4, - 124,4,131,1,106,2,155,0,157,4,131,1,130,1,113,4, - 124,4,100,5,107,2,114,108,124,3,115,226,116,5,124,0, - 100,6,131,2,114,226,116,6,124,0,124,0,106,7,124,2, - 100,7,100,8,141,4,1,0,113,4,116,5,124,0,124,4, - 131,2,115,4,100,9,160,8,124,0,106,2,124,4,161,2, - 125,6,122,14,116,9,124,2,124,6,131,2,1,0,87,0, - 113,4,4,0,116,10,121,224,1,0,125,7,1,0,122,54, - 124,7,106,11,124,6,107,2,114,202,116,12,106,13,160,14, - 124,6,116,15,161,2,100,10,117,1,114,202,87,0,89,0, - 100,10,125,7,126,7,113,4,130,0,87,0,89,0,100,10, - 125,7,126,7,113,4,100,10,125,7,126,7,48,0,48,0, - 113,4,124,0,83,0,41,11,122,238,70,105,103,117,114,101, - 32,111,117,116,32,119,104,97,116,32,95,95,105,109,112,111, - 114,116,95,95,32,115,104,111,117,108,100,32,114,101,116,117, - 114,110,46,10,10,32,32,32,32,84,104,101,32,105,109,112, - 111,114,116,95,32,112,97,114,97,109,101,116,101,114,32,105, - 115,32,97,32,99,97,108,108,97,98,108,101,32,119,104,105, - 99,104,32,116,97,107,101,115,32,116,104,101,32,110,97,109, - 101,32,111,102,32,109,111,100,117,108,101,32,116,111,10,32, - 32,32,32,105,109,112,111,114,116,46,32,73,116,32,105,115, - 32,114,101,113,117,105,114,101,100,32,116,111,32,100,101,99, - 111,117,112,108,101,32,116,104,101,32,102,117,110,99,116,105, - 111,110,32,102,114,111,109,32,97,115,115,117,109,105,110,103, - 32,105,109,112,111,114,116,108,105,98,39,115,10,32,32,32, - 32,105,109,112,111,114,116,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,105,115,32,100,101,115,105,114,101, - 100,46,10,10,32,32,32,32,122,8,46,95,95,97,108,108, - 95,95,122,13,96,96,102,114,111,109,32,108,105,115,116,39, - 39,122,8,73,116,101,109,32,105,110,32,122,18,32,109,117, - 115,116,32,98,101,32,115,116,114,44,32,110,111,116,32,250, - 1,42,218,7,95,95,97,108,108,95,95,84,114,211,0,0, - 0,114,184,0,0,0,78,41,16,114,197,0,0,0,114,198, - 0,0,0,114,1,0,0,0,114,199,0,0,0,114,14,0, - 0,0,114,4,0,0,0,218,16,95,104,97,110,100,108,101, - 95,102,114,111,109,108,105,115,116,114,214,0,0,0,114,46, - 0,0,0,114,68,0,0,0,114,205,0,0,0,114,17,0, - 0,0,114,15,0,0,0,114,93,0,0,0,114,35,0,0, - 0,114,208,0,0,0,41,8,114,97,0,0,0,218,8,102, - 114,111,109,108,105,115,116,114,206,0,0,0,114,212,0,0, - 0,218,1,120,90,5,119,104,101,114,101,90,9,102,114,111, - 109,95,110,97,109,101,90,3,101,120,99,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,215,0,0,0,9, - 4,0,0,115,48,0,0,0,0,10,8,1,10,1,4,1, - 12,2,4,1,10,1,8,255,10,2,8,1,14,1,10,1, - 2,255,8,2,10,1,14,1,2,1,14,1,14,4,10,1, - 16,255,2,2,12,1,26,1,114,215,0,0,0,99,1,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,6,0, - 0,0,67,0,0,0,115,146,0,0,0,124,0,160,0,100, - 1,161,1,125,1,124,0,160,0,100,2,161,1,125,2,124, - 1,100,3,117,1,114,82,124,2,100,3,117,1,114,78,124, - 1,124,2,106,1,107,3,114,78,116,2,106,3,100,4,124, - 1,155,2,100,5,124,2,106,1,155,2,100,6,157,5,116, - 4,100,7,100,8,141,3,1,0,124,1,83,0,124,2,100, - 3,117,1,114,96,124,2,106,1,83,0,116,2,106,3,100, - 9,116,4,100,7,100,8,141,3,1,0,124,0,100,10,25, - 0,125,1,100,11,124,0,118,1,114,142,124,1,160,5,100, - 12,161,1,100,13,25,0,125,1,124,1,83,0,41,14,122, - 167,67,97,108,99,117,108,97,116,101,32,119,104,97,116,32, - 95,95,112,97,99,107,97,103,101,95,95,32,115,104,111,117, - 108,100,32,98,101,46,10,10,32,32,32,32,95,95,112,97, - 99,107,97,103,101,95,95,32,105,115,32,110,111,116,32,103, - 117,97,114,97,110,116,101,101,100,32,116,111,32,98,101,32, - 100,101,102,105,110,101,100,32,111,114,32,99,111,117,108,100, - 32,98,101,32,115,101,116,32,116,111,32,78,111,110,101,10, - 32,32,32,32,116,111,32,114,101,112,114,101,115,101,110,116, - 32,116,104,97,116,32,105,116,115,32,112,114,111,112,101,114, - 32,118,97,108,117,101,32,105,115,32,117,110,107,110,111,119, - 110,46,10,10,32,32,32,32,114,146,0,0,0,114,106,0, - 0,0,78,122,32,95,95,112,97,99,107,97,103,101,95,95, - 32,33,61,32,95,95,115,112,101,99,95,95,46,112,97,114, - 101,110,116,32,40,122,4,32,33,61,32,250,1,41,233,3, - 0,0,0,41,1,90,10,115,116,97,99,107,108,101,118,101, - 108,122,89,99,97,110,39,116,32,114,101,115,111,108,118,101, - 32,112,97,99,107,97,103,101,32,102,114,111,109,32,95,95, - 115,112,101,99,95,95,32,111,114,32,95,95,112,97,99,107, - 97,103,101,95,95,44,32,102,97,108,108,105,110,103,32,98, - 97,99,107,32,111,110,32,95,95,110,97,109,101,95,95,32, - 97,110,100,32,95,95,112,97,116,104,95,95,114,1,0,0, - 0,114,142,0,0,0,114,129,0,0,0,114,22,0,0,0, - 41,6,114,35,0,0,0,114,131,0,0,0,114,193,0,0, - 0,114,194,0,0,0,114,195,0,0,0,114,130,0,0,0, - 41,3,218,7,103,108,111,98,97,108,115,114,187,0,0,0, - 114,96,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,17,95,99,97,108,99,95,95,95,112,97, - 99,107,97,103,101,95,95,46,4,0,0,115,42,0,0,0, - 0,7,10,1,10,1,8,1,18,1,6,1,2,255,4,1, - 4,255,6,2,4,254,6,3,4,1,8,1,6,2,6,2, - 4,254,6,3,8,1,8,1,14,1,114,221,0,0,0,114, - 10,0,0,0,99,5,0,0,0,0,0,0,0,0,0,0, - 0,9,0,0,0,5,0,0,0,67,0,0,0,115,180,0, - 0,0,124,4,100,1,107,2,114,18,116,0,124,0,131,1, - 125,5,110,36,124,1,100,2,117,1,114,30,124,1,110,2, - 105,0,125,6,116,1,124,6,131,1,125,7,116,0,124,0, - 124,7,124,4,131,3,125,5,124,3,115,150,124,4,100,1, - 107,2,114,84,116,0,124,0,160,2,100,3,161,1,100,1, - 25,0,131,1,83,0,124,0,115,92,124,5,83,0,116,3, - 124,0,131,1,116,3,124,0,160,2,100,3,161,1,100,1, - 25,0,131,1,24,0,125,8,116,4,106,5,124,5,106,6, - 100,2,116,3,124,5,106,6,131,1,124,8,24,0,133,2, - 25,0,25,0,83,0,110,26,116,7,124,5,100,4,131,2, - 114,172,116,8,124,5,124,3,116,0,131,3,83,0,124,5, - 83,0,100,2,83,0,41,5,97,215,1,0,0,73,109,112, - 111,114,116,32,97,32,109,111,100,117,108,101,46,10,10,32, - 32,32,32,84,104,101,32,39,103,108,111,98,97,108,115,39, - 32,97,114,103,117,109,101,110,116,32,105,115,32,117,115,101, - 100,32,116,111,32,105,110,102,101,114,32,119,104,101,114,101, - 32,116,104,101,32,105,109,112,111,114,116,32,105,115,32,111, - 99,99,117,114,114,105,110,103,32,102,114,111,109,10,32,32, - 32,32,116,111,32,104,97,110,100,108,101,32,114,101,108,97, - 116,105,118,101,32,105,109,112,111,114,116,115,46,32,84,104, - 101,32,39,108,111,99,97,108,115,39,32,97,114,103,117,109, - 101,110,116,32,105,115,32,105,103,110,111,114,101,100,46,32, - 84,104,101,10,32,32,32,32,39,102,114,111,109,108,105,115, - 116,39,32,97,114,103,117,109,101,110,116,32,115,112,101,99, - 105,102,105,101,115,32,119,104,97,116,32,115,104,111,117,108, - 100,32,101,120,105,115,116,32,97,115,32,97,116,116,114,105, - 98,117,116,101,115,32,111,110,32,116,104,101,32,109,111,100, - 117,108,101,10,32,32,32,32,98,101,105,110,103,32,105,109, - 112,111,114,116,101,100,32,40,101,46,103,46,32,96,96,102, - 114,111,109,32,109,111,100,117,108,101,32,105,109,112,111,114, - 116,32,60,102,114,111,109,108,105,115,116,62,96,96,41,46, - 32,32,84,104,101,32,39,108,101,118,101,108,39,10,32,32, - 32,32,97,114,103,117,109,101,110,116,32,114,101,112,114,101, - 115,101,110,116,115,32,116,104,101,32,112,97,99,107,97,103, - 101,32,108,111,99,97,116,105,111,110,32,116,111,32,105,109, - 112,111,114,116,32,102,114,111,109,32,105,110,32,97,32,114, - 101,108,97,116,105,118,101,10,32,32,32,32,105,109,112,111, - 114,116,32,40,101,46,103,46,32,96,96,102,114,111,109,32, - 46,46,112,107,103,32,105,109,112,111,114,116,32,109,111,100, - 96,96,32,119,111,117,108,100,32,104,97,118,101,32,97,32, - 39,108,101,118,101,108,39,32,111,102,32,50,41,46,10,10, - 32,32,32,32,114,22,0,0,0,78,114,129,0,0,0,114, - 142,0,0,0,41,9,114,210,0,0,0,114,221,0,0,0, - 218,9,112,97,114,116,105,116,105,111,110,114,186,0,0,0, - 114,15,0,0,0,114,93,0,0,0,114,1,0,0,0,114, - 4,0,0,0,114,215,0,0,0,41,9,114,17,0,0,0, - 114,220,0,0,0,218,6,108,111,99,97,108,115,114,216,0, - 0,0,114,188,0,0,0,114,97,0,0,0,90,8,103,108, - 111,98,97,108,115,95,114,187,0,0,0,90,7,99,117,116, - 95,111,102,102,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,10,95,95,105,109,112,111,114,116,95,95,73, - 4,0,0,115,30,0,0,0,0,11,8,1,10,2,16,1, - 8,1,12,1,4,3,8,1,18,1,4,1,4,4,26,3, - 32,1,10,1,12,2,114,224,0,0,0,99,1,0,0,0, + 0,1,0,0,0,67,0,0,0,114,185,0,0,0,41,2, + 122,54,82,101,116,117,114,110,32,78,111,110,101,32,97,115, + 32,102,114,111,122,101,110,32,109,111,100,117,108,101,115,32, + 100,111,32,110,111,116,32,104,97,118,101,32,115,111,117,114, + 99,101,32,99,111,100,101,46,78,114,5,0,0,0,114,186, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, + 0,0,114,189,0,0,0,106,3,0,0,114,188,0,0,0, + 122,25,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,103,101,116,95,115,111,117,114,99,101,99,2,0,0,0, 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,38,0,0,0,116,0,160,1,124,0,161, - 1,125,1,124,1,100,0,117,0,114,30,116,2,100,1,124, - 0,23,0,131,1,130,1,116,3,124,1,131,1,83,0,41, - 2,78,122,25,110,111,32,98,117,105,108,116,45,105,110,32, - 109,111,100,117,108,101,32,110,97,109,101,100,32,41,4,114, - 161,0,0,0,114,168,0,0,0,114,80,0,0,0,114,160, - 0,0,0,41,2,114,17,0,0,0,114,96,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,18, - 95,98,117,105,108,116,105,110,95,102,114,111,109,95,110,97, - 109,101,110,4,0,0,115,8,0,0,0,0,1,10,1,8, - 1,12,1,114,225,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,10,0,0,0,5,0,0,0,67,0,0, - 0,115,166,0,0,0,124,1,97,0,124,0,97,1,116,2, - 116,1,131,1,125,2,116,1,106,3,160,4,161,0,68,0, - 93,72,92,2,125,3,125,4,116,5,124,4,124,2,131,2, - 114,26,124,3,116,1,106,6,118,0,114,60,116,7,125,5, - 110,18,116,0,160,8,124,3,161,1,114,26,116,9,125,5, - 110,2,113,26,116,10,124,4,124,5,131,2,125,6,116,11, - 124,6,124,4,131,2,1,0,113,26,116,1,106,3,116,12, - 25,0,125,7,100,1,68,0,93,46,125,8,124,8,116,1, - 106,3,118,1,114,138,116,13,124,8,131,1,125,9,110,10, - 116,1,106,3,124,8,25,0,125,9,116,14,124,7,124,8, - 124,9,131,3,1,0,113,114,100,2,83,0,41,3,122,250, - 83,101,116,117,112,32,105,109,112,111,114,116,108,105,98,32, - 98,121,32,105,109,112,111,114,116,105,110,103,32,110,101,101, - 100,101,100,32,98,117,105,108,116,45,105,110,32,109,111,100, - 117,108,101,115,32,97,110,100,32,105,110,106,101,99,116,105, - 110,103,32,116,104,101,109,10,32,32,32,32,105,110,116,111, - 32,116,104,101,32,103,108,111,98,97,108,32,110,97,109,101, - 115,112,97,99,101,46,10,10,32,32,32,32,65,115,32,115, - 121,115,32,105,115,32,110,101,101,100,101,100,32,102,111,114, - 32,115,121,115,46,109,111,100,117,108,101,115,32,97,99,99, - 101,115,115,32,97,110,100,32,95,105,109,112,32,105,115,32, - 110,101,101,100,101,100,32,116,111,32,108,111,97,100,32,98, - 117,105,108,116,45,105,110,10,32,32,32,32,109,111,100,117, - 108,101,115,44,32,116,104,111,115,101,32,116,119,111,32,109, - 111,100,117,108,101,115,32,109,117,115,116,32,98,101,32,101, - 120,112,108,105,99,105,116,108,121,32,112,97,115,115,101,100, - 32,105,110,46,10,10,32,32,32,32,41,3,114,23,0,0, - 0,114,193,0,0,0,114,65,0,0,0,78,41,15,114,58, - 0,0,0,114,15,0,0,0,114,14,0,0,0,114,93,0, - 0,0,218,5,105,116,101,109,115,114,197,0,0,0,114,79, - 0,0,0,114,161,0,0,0,114,89,0,0,0,114,175,0, - 0,0,114,143,0,0,0,114,149,0,0,0,114,1,0,0, - 0,114,225,0,0,0,114,5,0,0,0,41,10,218,10,115, - 121,115,95,109,111,100,117,108,101,218,11,95,105,109,112,95, - 109,111,100,117,108,101,90,11,109,111,100,117,108,101,95,116, - 121,112,101,114,17,0,0,0,114,97,0,0,0,114,110,0, - 0,0,114,96,0,0,0,90,11,115,101,108,102,95,109,111, - 100,117,108,101,90,12,98,117,105,108,116,105,110,95,110,97, - 109,101,90,14,98,117,105,108,116,105,110,95,109,111,100,117, - 108,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,6,95,115,101,116,117,112,117,4,0,0,115,36,0, - 0,0,0,9,4,1,4,3,8,1,18,1,10,1,10,1, - 6,1,10,1,6,2,2,1,10,1,12,3,10,1,8,1, - 10,1,10,2,10,1,114,229,0,0,0,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,38,0,0,0,116,0,124,0,124,1,131, - 2,1,0,116,1,106,2,160,3,116,4,161,1,1,0,116, - 1,106,2,160,3,116,5,161,1,1,0,100,1,83,0,41, - 2,122,48,73,110,115,116,97,108,108,32,105,109,112,111,114, - 116,101,114,115,32,102,111,114,32,98,117,105,108,116,105,110, - 32,97,110,100,32,102,114,111,122,101,110,32,109,111,100,117, - 108,101,115,78,41,6,114,229,0,0,0,114,15,0,0,0, - 114,192,0,0,0,114,120,0,0,0,114,161,0,0,0,114, - 175,0,0,0,41,2,114,227,0,0,0,114,228,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 8,95,105,110,115,116,97,108,108,152,4,0,0,115,6,0, - 0,0,0,2,10,2,12,1,114,230,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,67,0,0,0,115,32,0,0,0,100,1,100,2,108, - 0,125,0,124,0,97,1,124,0,160,2,116,3,106,4,116, - 5,25,0,161,1,1,0,100,2,83,0,41,3,122,57,73, - 110,115,116,97,108,108,32,105,109,112,111,114,116,101,114,115, - 32,116,104,97,116,32,114,101,113,117,105,114,101,32,101,120, - 116,101,114,110,97,108,32,102,105,108,101,115,121,115,116,101, - 109,32,97,99,99,101,115,115,114,22,0,0,0,78,41,6, - 218,26,95,102,114,111,122,101,110,95,105,109,112,111,114,116, - 108,105,98,95,101,120,116,101,114,110,97,108,114,127,0,0, - 0,114,230,0,0,0,114,15,0,0,0,114,93,0,0,0, - 114,1,0,0,0,41,1,114,231,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,27,95,105,110, - 115,116,97,108,108,95,101,120,116,101,114,110,97,108,95,105, - 109,112,111,114,116,101,114,115,160,4,0,0,115,6,0,0, - 0,0,3,8,1,4,1,114,232,0,0,0,41,2,78,78, - 41,1,78,41,2,78,114,22,0,0,0,41,4,78,78,114, - 10,0,0,0,114,22,0,0,0,41,50,114,3,0,0,0, - 114,127,0,0,0,114,12,0,0,0,114,18,0,0,0,114, - 60,0,0,0,114,34,0,0,0,114,44,0,0,0,114,19, - 0,0,0,114,20,0,0,0,114,50,0,0,0,114,51,0, - 0,0,114,54,0,0,0,114,66,0,0,0,114,68,0,0, - 0,114,77,0,0,0,114,87,0,0,0,114,91,0,0,0, - 114,98,0,0,0,114,112,0,0,0,114,113,0,0,0,114, - 92,0,0,0,114,143,0,0,0,114,149,0,0,0,114,153, - 0,0,0,114,108,0,0,0,114,94,0,0,0,114,159,0, - 0,0,114,160,0,0,0,114,95,0,0,0,114,161,0,0, - 0,114,175,0,0,0,114,180,0,0,0,114,189,0,0,0, - 114,191,0,0,0,114,196,0,0,0,114,202,0,0,0,90, - 15,95,69,82,82,95,77,83,71,95,80,82,69,70,73,88, - 114,204,0,0,0,114,207,0,0,0,218,6,111,98,106,101, - 99,116,114,208,0,0,0,114,209,0,0,0,114,210,0,0, - 0,114,215,0,0,0,114,221,0,0,0,114,224,0,0,0, - 114,225,0,0,0,114,229,0,0,0,114,230,0,0,0,114, - 232,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,8,60,109,111,100,117,108, - 101,62,1,0,0,0,115,94,0,0,0,4,24,4,2,8, - 8,8,8,4,2,4,3,16,4,14,77,14,21,14,16,8, - 37,8,17,8,11,14,8,8,11,8,12,8,16,8,36,14, - 101,16,26,10,45,14,72,8,17,8,17,8,30,8,37,8, - 42,8,15,14,75,14,79,14,13,8,9,8,9,10,47,8, - 16,4,1,8,2,8,32,6,3,8,16,10,15,14,37,8, - 27,10,37,8,7,8,35,8,8, + 67,0,0,0,114,198,0,0,0,41,1,122,46,82,101,116, + 117,114,110,32,84,114,117,101,32,105,102,32,116,104,101,32, + 102,114,111,122,101,110,32,109,111,100,117,108,101,32,105,115, + 32,97,32,112,97,99,107,97,103,101,46,41,2,114,64,0, + 0,0,90,17,105,115,95,102,114,111,122,101,110,95,112,97, + 99,107,97,103,101,114,186,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,6,0,0,0,114,128,0,0,0,112,3, + 0,0,114,199,0,0,0,122,25,70,114,111,122,101,110,73, + 109,112,111,114,116,101,114,46,105,115,95,112,97,99,107,97, + 103,101,114,190,0,0,0,114,0,0,0,0,41,17,114,9, + 0,0,0,114,8,0,0,0,114,1,0,0,0,114,10,0, + 0,0,114,151,0,0,0,114,191,0,0,0,114,114,0,0, + 0,114,192,0,0,0,114,183,0,0,0,114,184,0,0,0, + 114,162,0,0,0,114,163,0,0,0,114,170,0,0,0,114, + 100,0,0,0,114,187,0,0,0,114,189,0,0,0,114,128, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,6,0,0,0,114,193,0,0,0,36,3,0,0, + 115,48,0,0,0,8,0,4,2,4,7,2,2,10,1,2, + 10,12,1,2,6,12,1,2,11,10,1,2,3,10,1,2, + 8,10,1,2,9,2,1,12,1,2,4,2,1,12,1,2, + 4,2,1,16,1,114,193,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, + 0,0,0,115,32,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, + 132,0,90,5,100,6,83,0,41,7,218,18,95,73,109,112, + 111,114,116,76,111,99,107,67,111,110,116,101,120,116,122,36, + 67,111,110,116,101,120,116,32,109,97,110,97,103,101,114,32, + 102,111,114,32,116,104,101,32,105,109,112,111,114,116,32,108, + 111,99,107,46,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,2,0,0,0,67,0,0,0,243,12,0, + 0,0,116,0,160,1,161,0,1,0,100,1,83,0,41,2, + 122,24,65,99,113,117,105,114,101,32,116,104,101,32,105,109, + 112,111,114,116,32,108,111,99,107,46,78,41,2,114,64,0, + 0,0,114,65,0,0,0,114,52,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,6,0,0,0,114,61,0,0,0, + 125,3,0,0,243,2,0,0,0,12,2,122,28,95,73,109, + 112,111,114,116,76,111,99,107,67,111,110,116,101,120,116,46, + 95,95,101,110,116,101,114,95,95,99,4,0,0,0,0,0, + 0,0,0,0,0,0,4,0,0,0,2,0,0,0,67,0, + 0,0,114,201,0,0,0,41,2,122,60,82,101,108,101,97, + 115,101,32,116,104,101,32,105,109,112,111,114,116,32,108,111, + 99,107,32,114,101,103,97,114,100,108,101,115,115,32,111,102, + 32,97,110,121,32,114,97,105,115,101,100,32,101,120,99,101, + 112,116,105,111,110,115,46,78,41,2,114,64,0,0,0,114, + 67,0,0,0,41,4,114,33,0,0,0,218,8,101,120,99, + 95,116,121,112,101,218,9,101,120,99,95,118,97,108,117,101, + 218,13,101,120,99,95,116,114,97,99,101,98,97,99,107,114, + 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,63, + 0,0,0,129,3,0,0,114,202,0,0,0,122,27,95,73, + 109,112,111,114,116,76,111,99,107,67,111,110,116,101,120,116, + 46,95,95,101,120,105,116,95,95,78,41,6,114,9,0,0, + 0,114,8,0,0,0,114,1,0,0,0,114,10,0,0,0, + 114,61,0,0,0,114,63,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,200, + 0,0,0,121,3,0,0,115,8,0,0,0,8,0,4,2, + 8,2,12,4,114,200,0,0,0,99,3,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, + 0,0,115,64,0,0,0,124,1,160,0,100,1,124,2,100, + 2,24,0,161,2,125,3,116,1,124,3,131,1,124,2,107, + 0,114,18,116,2,100,3,131,1,130,1,124,3,100,4,25, + 0,125,4,124,0,114,30,100,5,160,3,124,4,124,0,161, + 2,83,0,124,4,83,0,41,6,122,50,82,101,115,111,108, + 118,101,32,97,32,114,101,108,97,116,105,118,101,32,109,111, + 100,117,108,101,32,110,97,109,101,32,116,111,32,97,110,32, + 97,98,115,111,108,117,116,101,32,111,110,101,46,114,141,0, + 0,0,114,42,0,0,0,122,50,97,116,116,101,109,112,116, + 101,100,32,114,101,108,97,116,105,118,101,32,105,109,112,111, + 114,116,32,98,101,121,111,110,100,32,116,111,112,45,108,101, + 118,101,108,32,112,97,99,107,97,103,101,114,25,0,0,0, + 250,5,123,125,46,123,125,41,4,218,6,114,115,112,108,105, + 116,218,3,108,101,110,114,87,0,0,0,114,50,0,0,0, + 41,5,114,20,0,0,0,218,7,112,97,99,107,97,103,101, + 218,5,108,101,118,101,108,90,4,98,105,116,115,90,4,98, + 97,115,101,114,5,0,0,0,114,5,0,0,0,114,6,0, + 0,0,218,13,95,114,101,115,111,108,118,101,95,110,97,109, + 101,134,3,0,0,115,10,0,0,0,16,2,12,1,8,1, + 8,1,20,1,114,211,0,0,0,99,3,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,4,0,0,0,67,0, + 0,0,115,60,0,0,0,116,0,124,0,131,1,155,0,100, + 1,157,2,125,3,116,1,160,2,124,3,116,3,161,2,1, + 0,124,0,160,4,124,1,124,2,161,2,125,4,124,4,100, + 0,117,0,114,25,100,0,83,0,116,5,124,1,124,4,131, + 2,83,0,41,2,78,122,53,46,102,105,110,100,95,115,112, + 101,99,40,41,32,110,111,116,32,102,111,117,110,100,59,32, + 102,97,108,108,105,110,103,32,98,97,99,107,32,116,111,32, + 102,105,110,100,95,109,111,100,117,108,101,40,41,41,6,114, + 7,0,0,0,114,101,0,0,0,114,102,0,0,0,114,169, + 0,0,0,114,184,0,0,0,114,104,0,0,0,41,5,218, + 6,102,105,110,100,101,114,114,20,0,0,0,114,181,0,0, + 0,114,108,0,0,0,114,122,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,6,0,0,0,218,17,95,102,105,110, + 100,95,115,112,101,99,95,108,101,103,97,99,121,143,3,0, + 0,115,12,0,0,0,14,1,12,2,12,1,8,1,4,1, + 10,1,114,213,0,0,0,99,3,0,0,0,0,0,0,0, + 0,0,0,0,10,0,0,0,10,0,0,0,67,0,0,0, + 115,24,1,0,0,116,0,106,1,125,3,124,3,100,1,117, + 0,114,11,116,2,100,2,131,1,130,1,124,3,115,19,116, + 3,160,4,100,3,116,5,161,2,1,0,124,0,116,0,106, + 6,118,0,125,4,124,3,68,0,93,111,125,5,116,7,131, + 0,143,47,1,0,122,5,124,5,106,8,125,6,87,0,110, + 27,4,0,116,9,121,64,1,0,1,0,1,0,116,10,124, + 5,124,0,124,1,131,3,125,7,124,7,100,1,117,0,114, + 62,89,0,87,0,100,1,4,0,4,0,131,3,1,0,113, + 26,89,0,110,7,119,0,124,6,124,0,124,1,124,2,131, + 3,125,7,87,0,100,1,4,0,4,0,131,3,1,0,110, + 8,49,0,115,81,119,1,1,0,1,0,1,0,89,0,1, + 0,124,7,100,1,117,1,114,137,124,4,115,133,124,0,116, + 0,106,6,118,0,114,133,116,0,106,6,124,0,25,0,125, + 8,122,5,124,8,106,11,125,9,87,0,110,13,4,0,116, + 9,121,120,1,0,1,0,1,0,124,7,6,0,89,0,2, + 0,1,0,83,0,119,0,124,9,100,1,117,0,114,129,124, + 7,2,0,1,0,83,0,124,9,2,0,1,0,83,0,124, + 7,2,0,1,0,83,0,113,26,100,1,83,0,41,4,122, + 21,70,105,110,100,32,97,32,109,111,100,117,108,101,39,115, + 32,115,112,101,99,46,78,122,53,115,121,115,46,109,101,116, + 97,95,112,97,116,104,32,105,115,32,78,111,110,101,44,32, + 80,121,116,104,111,110,32,105,115,32,108,105,107,101,108,121, + 32,115,104,117,116,116,105,110,103,32,100,111,119,110,122,22, + 115,121,115,46,109,101,116,97,95,112,97,116,104,32,105,115, + 32,101,109,112,116,121,41,12,114,18,0,0,0,218,9,109, + 101,116,97,95,112,97,116,104,114,87,0,0,0,114,101,0, + 0,0,114,102,0,0,0,114,169,0,0,0,114,105,0,0, + 0,114,200,0,0,0,114,183,0,0,0,114,2,0,0,0, + 114,213,0,0,0,114,113,0,0,0,41,10,114,20,0,0, + 0,114,181,0,0,0,114,182,0,0,0,114,214,0,0,0, + 90,9,105,115,95,114,101,108,111,97,100,114,212,0,0,0, + 114,183,0,0,0,114,109,0,0,0,114,110,0,0,0,114, + 113,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,218,10,95,102,105,110,100,95,115,112,101,99,153, + 3,0,0,115,68,0,0,0,6,2,8,1,8,2,4,3, + 12,1,10,5,8,1,8,1,2,1,10,1,12,1,12,1, + 8,1,2,1,14,250,4,5,2,254,12,5,2,128,28,248, + 8,9,14,2,10,1,2,1,10,1,12,1,12,4,2,252, + 8,6,8,1,8,2,8,2,2,239,4,19,114,215,0,0, + 0,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,5,0,0,0,67,0,0,0,115,110,0,0,0,116, + 0,124,0,116,1,131,2,115,14,116,2,100,1,160,3,116, + 4,124,0,131,1,161,1,131,1,130,1,124,2,100,2,107, + 0,114,22,116,5,100,3,131,1,130,1,124,2,100,2,107, + 4,114,41,116,0,124,1,116,1,131,2,115,35,116,2,100, + 4,131,1,130,1,124,1,115,41,116,6,100,5,131,1,130, + 1,124,0,115,51,124,2,100,2,107,2,114,53,116,5,100, + 6,131,1,130,1,100,7,83,0,100,7,83,0,41,8,122, + 28,86,101,114,105,102,121,32,97,114,103,117,109,101,110,116, + 115,32,97,114,101,32,34,115,97,110,101,34,46,122,31,109, + 111,100,117,108,101,32,110,97,109,101,32,109,117,115,116,32, + 98,101,32,115,116,114,44,32,110,111,116,32,123,125,114,25, + 0,0,0,122,18,108,101,118,101,108,32,109,117,115,116,32, + 98,101,32,62,61,32,48,122,31,95,95,112,97,99,107,97, + 103,101,95,95,32,110,111,116,32,115,101,116,32,116,111,32, + 97,32,115,116,114,105,110,103,122,54,97,116,116,101,109,112, + 116,101,100,32,114,101,108,97,116,105,118,101,32,105,109,112, + 111,114,116,32,119,105,116,104,32,110,111,32,107,110,111,119, + 110,32,112,97,114,101,110,116,32,112,97,99,107,97,103,101, + 122,17,69,109,112,116,121,32,109,111,100,117,108,101,32,110, + 97,109,101,78,41,7,218,10,105,115,105,110,115,116,97,110, + 99,101,218,3,115,116,114,218,9,84,121,112,101,69,114,114, + 111,114,114,50,0,0,0,114,3,0,0,0,218,10,86,97, + 108,117,101,69,114,114,111,114,114,87,0,0,0,169,3,114, + 20,0,0,0,114,209,0,0,0,114,210,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,218,13,95, + 115,97,110,105,116,121,95,99,104,101,99,107,200,3,0,0, + 115,24,0,0,0,10,2,18,1,8,1,8,1,8,1,10, + 1,8,1,4,1,8,1,12,2,8,1,8,255,114,221,0, + 0,0,122,16,78,111,32,109,111,100,117,108,101,32,110,97, + 109,101,100,32,122,4,123,33,114,125,99,2,0,0,0,0, + 0,0,0,0,0,0,0,9,0,0,0,8,0,0,0,67, + 0,0,0,115,16,1,0,0,100,0,125,2,124,0,160,0, + 100,1,161,1,100,2,25,0,125,3,124,3,114,64,124,3, + 116,1,106,2,118,1,114,21,116,3,124,1,124,3,131,2, + 1,0,124,0,116,1,106,2,118,0,114,31,116,1,106,2, + 124,0,25,0,83,0,116,1,106,2,124,3,25,0,125,4, + 122,5,124,4,106,4,125,2,87,0,110,22,4,0,116,5, + 121,63,1,0,1,0,1,0,116,6,100,3,23,0,160,7, + 124,0,124,3,161,2,125,5,116,8,124,5,124,0,100,4, + 141,2,100,0,130,2,119,0,116,9,124,0,124,2,131,2, + 125,6,124,6,100,0,117,0,114,82,116,8,116,6,160,7, + 124,0,161,1,124,0,100,4,141,2,130,1,116,10,124,6, + 131,1,125,7,124,3,114,134,116,1,106,2,124,3,25,0, + 125,4,124,0,160,0,100,1,161,1,100,5,25,0,125,8, + 122,9,116,11,124,4,124,8,124,7,131,3,1,0,87,0, + 124,7,83,0,4,0,116,5,121,133,1,0,1,0,1,0, + 100,6,124,3,155,2,100,7,124,8,155,2,157,4,125,5, + 116,12,160,13,124,5,116,14,161,2,1,0,89,0,124,7, + 83,0,119,0,124,7,83,0,41,8,78,114,141,0,0,0, + 114,25,0,0,0,122,23,59,32,123,33,114,125,32,105,115, + 32,110,111,116,32,97,32,112,97,99,107,97,103,101,114,19, + 0,0,0,233,2,0,0,0,122,27,67,97,110,110,111,116, + 32,115,101,116,32,97,110,32,97,116,116,114,105,98,117,116, + 101,32,111,110,32,122,18,32,102,111,114,32,99,104,105,108, + 100,32,109,111,100,117,108,101,32,41,15,114,142,0,0,0, + 114,18,0,0,0,114,105,0,0,0,114,74,0,0,0,114, + 154,0,0,0,114,2,0,0,0,218,8,95,69,82,82,95, + 77,83,71,114,50,0,0,0,218,19,77,111,100,117,108,101, + 78,111,116,70,111,117,110,100,69,114,114,111,114,114,215,0, + 0,0,114,173,0,0,0,114,12,0,0,0,114,101,0,0, + 0,114,102,0,0,0,114,169,0,0,0,41,9,114,20,0, + 0,0,218,7,105,109,112,111,114,116,95,114,181,0,0,0, + 114,143,0,0,0,90,13,112,97,114,101,110,116,95,109,111, + 100,117,108,101,114,108,0,0,0,114,109,0,0,0,114,110, + 0,0,0,90,5,99,104,105,108,100,114,5,0,0,0,114, + 5,0,0,0,114,6,0,0,0,218,23,95,102,105,110,100, + 95,97,110,100,95,108,111,97,100,95,117,110,108,111,99,107, + 101,100,219,3,0,0,115,60,0,0,0,4,1,14,1,4, + 1,10,1,10,1,10,2,10,1,10,1,2,1,10,1,12, + 1,16,1,14,1,2,254,10,3,8,1,18,1,8,2,4, + 1,10,2,14,1,2,1,14,1,4,4,12,253,16,1,14, + 1,4,1,2,253,4,3,114,226,0,0,0,99,2,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,8,0,0, + 0,67,0,0,0,115,128,0,0,0,116,0,124,0,131,1, + 143,31,1,0,116,1,106,2,160,3,124,0,116,4,161,2, + 125,2,124,2,116,4,117,0,114,28,116,5,124,0,124,1, + 131,2,87,0,2,0,100,1,4,0,4,0,131,3,1,0, + 83,0,87,0,100,1,4,0,4,0,131,3,1,0,110,8, + 49,0,115,38,119,1,1,0,1,0,1,0,89,0,1,0, + 124,2,100,1,117,0,114,58,100,2,160,6,124,0,161,1, + 125,3,116,7,124,3,124,0,100,3,141,2,130,1,116,8, + 124,0,131,1,1,0,124,2,83,0,41,4,122,25,70,105, + 110,100,32,97,110,100,32,108,111,97,100,32,116,104,101,32, + 109,111,100,117,108,101,46,78,122,40,105,109,112,111,114,116, + 32,111,102,32,123,125,32,104,97,108,116,101,100,59,32,78, + 111,110,101,32,105,110,32,115,121,115,46,109,111,100,117,108, + 101,115,114,19,0,0,0,41,9,114,57,0,0,0,114,18, + 0,0,0,114,105,0,0,0,114,38,0,0,0,218,14,95, + 78,69,69,68,83,95,76,79,65,68,73,78,71,114,226,0, + 0,0,114,50,0,0,0,114,224,0,0,0,114,72,0,0, + 0,41,4,114,20,0,0,0,114,225,0,0,0,114,110,0, + 0,0,114,82,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,6,0,0,0,218,14,95,102,105,110,100,95,97,110, + 100,95,108,111,97,100,254,3,0,0,115,28,0,0,0,10, + 2,14,1,8,1,8,1,16,253,2,2,28,254,8,5,2, + 1,6,1,2,255,12,2,8,2,4,1,114,228,0,0,0, + 114,25,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,42, + 0,0,0,116,0,124,0,124,1,124,2,131,3,1,0,124, + 2,100,1,107,4,114,16,116,1,124,0,124,1,124,2,131, + 3,125,0,116,2,124,0,116,3,131,2,83,0,41,2,97, + 50,1,0,0,73,109,112,111,114,116,32,97,110,100,32,114, + 101,116,117,114,110,32,116,104,101,32,109,111,100,117,108,101, + 32,98,97,115,101,100,32,111,110,32,105,116,115,32,110,97, + 109,101,44,32,116,104,101,32,112,97,99,107,97,103,101,32, + 116,104,101,32,99,97,108,108,32,105,115,10,32,32,32,32, + 98,101,105,110,103,32,109,97,100,101,32,102,114,111,109,44, + 32,97,110,100,32,116,104,101,32,108,101,118,101,108,32,97, + 100,106,117,115,116,109,101,110,116,46,10,10,32,32,32,32, + 84,104,105,115,32,102,117,110,99,116,105,111,110,32,114,101, + 112,114,101,115,101,110,116,115,32,116,104,101,32,103,114,101, + 97,116,101,115,116,32,99,111,109,109,111,110,32,100,101,110, + 111,109,105,110,97,116,111,114,32,111,102,32,102,117,110,99, + 116,105,111,110,97,108,105,116,121,10,32,32,32,32,98,101, + 116,119,101,101,110,32,105,109,112,111,114,116,95,109,111,100, + 117,108,101,32,97,110,100,32,95,95,105,109,112,111,114,116, + 95,95,46,32,84,104,105,115,32,105,110,99,108,117,100,101, + 115,32,115,101,116,116,105,110,103,32,95,95,112,97,99,107, + 97,103,101,95,95,32,105,102,10,32,32,32,32,116,104,101, + 32,108,111,97,100,101,114,32,100,105,100,32,110,111,116,46, + 10,10,32,32,32,32,114,25,0,0,0,41,4,114,221,0, + 0,0,114,211,0,0,0,114,228,0,0,0,218,11,95,103, + 99,100,95,105,109,112,111,114,116,114,220,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,6,0,0,0,114,229,0, + 0,0,14,4,0,0,115,8,0,0,0,12,9,8,1,12, + 1,10,1,114,229,0,0,0,169,1,218,9,114,101,99,117, + 114,115,105,118,101,99,3,0,0,0,0,0,0,0,1,0, + 0,0,8,0,0,0,11,0,0,0,67,0,0,0,115,218, + 0,0,0,124,1,68,0,93,104,125,4,116,0,124,4,116, + 1,131,2,115,32,124,3,114,17,124,0,106,2,100,1,23, + 0,125,5,110,2,100,2,125,5,116,3,100,3,124,5,155, + 0,100,4,116,4,124,4,131,1,106,2,155,0,157,4,131, + 1,130,1,124,4,100,5,107,2,114,53,124,3,115,52,116, + 5,124,0,100,6,131,2,114,52,116,6,124,0,124,0,106, + 7,124,2,100,7,100,8,141,4,1,0,113,2,116,5,124, + 0,124,4,131,2,115,106,100,9,160,8,124,0,106,2,124, + 4,161,2,125,6,122,7,116,9,124,2,124,6,131,2,1, + 0,87,0,113,2,4,0,116,10,121,105,1,0,125,7,1, + 0,122,21,124,7,106,11,124,6,107,2,114,100,116,12,106, + 13,160,14,124,6,116,15,161,2,100,10,117,1,114,100,87, + 0,89,0,100,10,125,7,126,7,113,2,130,0,100,10,125, + 7,126,7,119,1,119,0,113,2,124,0,83,0,41,11,122, + 238,70,105,103,117,114,101,32,111,117,116,32,119,104,97,116, + 32,95,95,105,109,112,111,114,116,95,95,32,115,104,111,117, + 108,100,32,114,101,116,117,114,110,46,10,10,32,32,32,32, + 84,104,101,32,105,109,112,111,114,116,95,32,112,97,114,97, + 109,101,116,101,114,32,105,115,32,97,32,99,97,108,108,97, + 98,108,101,32,119,104,105,99,104,32,116,97,107,101,115,32, + 116,104,101,32,110,97,109,101,32,111,102,32,109,111,100,117, + 108,101,32,116,111,10,32,32,32,32,105,109,112,111,114,116, + 46,32,73,116,32,105,115,32,114,101,113,117,105,114,101,100, + 32,116,111,32,100,101,99,111,117,112,108,101,32,116,104,101, + 32,102,117,110,99,116,105,111,110,32,102,114,111,109,32,97, + 115,115,117,109,105,110,103,32,105,109,112,111,114,116,108,105, + 98,39,115,10,32,32,32,32,105,109,112,111,114,116,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,105,115, + 32,100,101,115,105,114,101,100,46,10,10,32,32,32,32,122, + 8,46,95,95,97,108,108,95,95,122,13,96,96,102,114,111, + 109,32,108,105,115,116,39,39,122,8,73,116,101,109,32,105, + 110,32,122,18,32,109,117,115,116,32,98,101,32,115,116,114, + 44,32,110,111,116,32,250,1,42,218,7,95,95,97,108,108, + 95,95,84,114,230,0,0,0,114,206,0,0,0,78,41,16, + 114,216,0,0,0,114,217,0,0,0,114,9,0,0,0,114, + 218,0,0,0,114,3,0,0,0,114,11,0,0,0,218,16, + 95,104,97,110,100,108,101,95,102,114,111,109,108,105,115,116, + 114,233,0,0,0,114,50,0,0,0,114,74,0,0,0,114, + 224,0,0,0,114,20,0,0,0,114,18,0,0,0,114,105, + 0,0,0,114,38,0,0,0,114,227,0,0,0,41,8,114, + 110,0,0,0,218,8,102,114,111,109,108,105,115,116,114,225, + 0,0,0,114,231,0,0,0,218,1,120,90,5,119,104,101, + 114,101,90,9,102,114,111,109,95,110,97,109,101,90,3,101, + 120,99,114,5,0,0,0,114,5,0,0,0,114,6,0,0, + 0,114,234,0,0,0,29,4,0,0,115,56,0,0,0,8, + 10,10,1,4,1,12,1,4,2,10,1,8,1,8,255,8, + 2,14,1,10,1,2,1,6,255,2,128,10,2,14,1,2, + 1,14,1,14,1,10,4,16,1,2,255,12,2,2,1,8, + 128,2,249,2,252,4,12,114,234,0,0,0,99,1,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,6,0,0, + 0,67,0,0,0,115,146,0,0,0,124,0,160,0,100,1, + 161,1,125,1,124,0,160,0,100,2,161,1,125,2,124,1, + 100,3,117,1,114,41,124,2,100,3,117,1,114,39,124,1, + 124,2,106,1,107,3,114,39,116,2,106,3,100,4,124,1, + 155,2,100,5,124,2,106,1,155,2,100,6,157,5,116,4, + 100,7,100,8,141,3,1,0,124,1,83,0,124,2,100,3, + 117,1,114,48,124,2,106,1,83,0,116,2,106,3,100,9, + 116,4,100,7,100,8,141,3,1,0,124,0,100,10,25,0, + 125,1,100,11,124,0,118,1,114,71,124,1,160,5,100,12, + 161,1,100,13,25,0,125,1,124,1,83,0,41,14,122,167, + 67,97,108,99,117,108,97,116,101,32,119,104,97,116,32,95, + 95,112,97,99,107,97,103,101,95,95,32,115,104,111,117,108, + 100,32,98,101,46,10,10,32,32,32,32,95,95,112,97,99, + 107,97,103,101,95,95,32,105,115,32,110,111,116,32,103,117, + 97,114,97,110,116,101,101,100,32,116,111,32,98,101,32,100, + 101,102,105,110,101,100,32,111,114,32,99,111,117,108,100,32, + 98,101,32,115,101,116,32,116,111,32,78,111,110,101,10,32, + 32,32,32,116,111,32,114,101,112,114,101,115,101,110,116,32, + 116,104,97,116,32,105,116,115,32,112,114,111,112,101,114,32, + 118,97,108,117,101,32,105,115,32,117,110,107,110,111,119,110, + 46,10,10,32,32,32,32,114,158,0,0,0,114,113,0,0, + 0,78,122,32,95,95,112,97,99,107,97,103,101,95,95,32, + 33,61,32,95,95,115,112,101,99,95,95,46,112,97,114,101, + 110,116,32,40,122,4,32,33,61,32,250,1,41,233,3,0, + 0,0,41,1,90,10,115,116,97,99,107,108,101,118,101,108, + 122,89,99,97,110,39,116,32,114,101,115,111,108,118,101,32, + 112,97,99,107,97,103,101,32,102,114,111,109,32,95,95,115, + 112,101,99,95,95,32,111,114,32,95,95,112,97,99,107,97, + 103,101,95,95,44,32,102,97,108,108,105,110,103,32,98,97, + 99,107,32,111,110,32,95,95,110,97,109,101,95,95,32,97, + 110,100,32,95,95,112,97,116,104,95,95,114,9,0,0,0, + 114,154,0,0,0,114,141,0,0,0,114,25,0,0,0,41, + 6,114,38,0,0,0,114,143,0,0,0,114,101,0,0,0, + 114,102,0,0,0,114,169,0,0,0,114,142,0,0,0,41, + 3,218,7,103,108,111,98,97,108,115,114,209,0,0,0,114, + 109,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,99, + 107,97,103,101,95,95,66,4,0,0,115,42,0,0,0,10, + 7,10,1,8,1,18,1,6,1,2,1,4,255,4,1,6, + 255,4,2,6,254,4,3,8,1,6,1,6,2,4,2,6, + 254,8,3,8,1,14,1,4,1,114,240,0,0,0,114,5, + 0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0, + 9,0,0,0,5,0,0,0,67,0,0,0,115,174,0,0, + 0,124,4,100,1,107,2,114,9,116,0,124,0,131,1,125, + 5,110,18,124,1,100,2,117,1,114,15,124,1,110,1,105, + 0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,124, + 7,124,4,131,3,125,5,124,3,115,74,124,4,100,1,107, + 2,114,42,116,0,124,0,160,2,100,3,161,1,100,1,25, + 0,131,1,83,0,124,0,115,46,124,5,83,0,116,3,124, + 0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,25, + 0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,100, + 2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,25, + 0,25,0,83,0,116,7,124,5,100,4,131,2,114,85,116, + 8,124,5,124,3,116,0,131,3,83,0,124,5,83,0,41, + 5,97,215,1,0,0,73,109,112,111,114,116,32,97,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,84,104,101,32, + 39,103,108,111,98,97,108,115,39,32,97,114,103,117,109,101, + 110,116,32,105,115,32,117,115,101,100,32,116,111,32,105,110, + 102,101,114,32,119,104,101,114,101,32,116,104,101,32,105,109, + 112,111,114,116,32,105,115,32,111,99,99,117,114,114,105,110, + 103,32,102,114,111,109,10,32,32,32,32,116,111,32,104,97, + 110,100,108,101,32,114,101,108,97,116,105,118,101,32,105,109, + 112,111,114,116,115,46,32,84,104,101,32,39,108,111,99,97, + 108,115,39,32,97,114,103,117,109,101,110,116,32,105,115,32, + 105,103,110,111,114,101,100,46,32,84,104,101,10,32,32,32, + 32,39,102,114,111,109,108,105,115,116,39,32,97,114,103,117, + 109,101,110,116,32,115,112,101,99,105,102,105,101,115,32,119, + 104,97,116,32,115,104,111,117,108,100,32,101,120,105,115,116, + 32,97,115,32,97,116,116,114,105,98,117,116,101,115,32,111, + 110,32,116,104,101,32,109,111,100,117,108,101,10,32,32,32, + 32,98,101,105,110,103,32,105,109,112,111,114,116,101,100,32, + 40,101,46,103,46,32,96,96,102,114,111,109,32,109,111,100, + 117,108,101,32,105,109,112,111,114,116,32,60,102,114,111,109, + 108,105,115,116,62,96,96,41,46,32,32,84,104,101,32,39, + 108,101,118,101,108,39,10,32,32,32,32,97,114,103,117,109, + 101,110,116,32,114,101,112,114,101,115,101,110,116,115,32,116, + 104,101,32,112,97,99,107,97,103,101,32,108,111,99,97,116, + 105,111,110,32,116,111,32,105,109,112,111,114,116,32,102,114, + 111,109,32,105,110,32,97,32,114,101,108,97,116,105,118,101, + 10,32,32,32,32,105,109,112,111,114,116,32,40,101,46,103, + 46,32,96,96,102,114,111,109,32,46,46,112,107,103,32,105, + 109,112,111,114,116,32,109,111,100,96,96,32,119,111,117,108, + 100,32,104,97,118,101,32,97,32,39,108,101,118,101,108,39, + 32,111,102,32,50,41,46,10,10,32,32,32,32,114,25,0, + 0,0,78,114,141,0,0,0,114,154,0,0,0,41,9,114, + 229,0,0,0,114,240,0,0,0,218,9,112,97,114,116,105, + 116,105,111,110,114,208,0,0,0,114,18,0,0,0,114,105, + 0,0,0,114,9,0,0,0,114,11,0,0,0,114,234,0, + 0,0,41,9,114,20,0,0,0,114,239,0,0,0,218,6, + 108,111,99,97,108,115,114,235,0,0,0,114,210,0,0,0, + 114,110,0,0,0,90,8,103,108,111,98,97,108,115,95,114, + 209,0,0,0,90,7,99,117,116,95,111,102,102,114,5,0, + 0,0,114,5,0,0,0,114,6,0,0,0,218,10,95,95, + 105,109,112,111,114,116,95,95,93,4,0,0,115,30,0,0, + 0,8,11,10,1,16,2,8,1,12,1,4,1,8,3,18, + 1,4,1,4,1,26,4,30,3,10,1,12,1,4,2,114, + 243,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,3,0,0,0,67,0,0,0,115,38,0, + 0,0,116,0,160,1,124,0,161,1,125,1,124,1,100,0, + 117,0,114,15,116,2,100,1,124,0,23,0,131,1,130,1, + 116,3,124,1,131,1,83,0,41,2,78,122,25,110,111,32, + 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,32, + 110,97,109,101,100,32,41,4,114,175,0,0,0,114,183,0, + 0,0,114,87,0,0,0,114,173,0,0,0,41,2,114,20, + 0,0,0,114,109,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,6,0,0,0,218,18,95,98,117,105,108,116,105, + 110,95,102,114,111,109,95,110,97,109,101,130,4,0,0,115, + 8,0,0,0,10,1,8,1,12,1,8,1,114,244,0,0, + 0,99,2,0,0,0,0,0,0,0,0,0,0,0,10,0, + 0,0,5,0,0,0,67,0,0,0,115,166,0,0,0,124, + 1,97,0,124,0,97,1,116,2,116,1,131,1,125,2,116, + 1,106,3,160,4,161,0,68,0,93,36,92,2,125,3,125, + 4,116,5,124,4,124,2,131,2,114,49,124,3,116,1,106, + 6,118,0,114,30,116,7,125,5,110,9,116,0,160,8,124, + 3,161,1,114,38,116,9,125,5,110,1,113,13,116,10,124, + 4,124,5,131,2,125,6,116,11,124,6,124,4,131,2,1, + 0,113,13,116,1,106,3,116,12,25,0,125,7,100,1,68, + 0,93,23,125,8,124,8,116,1,106,3,118,1,114,69,116, + 13,124,8,131,1,125,9,110,5,116,1,106,3,124,8,25, + 0,125,9,116,14,124,7,124,8,124,9,131,3,1,0,113, + 57,100,2,83,0,41,3,122,250,83,101,116,117,112,32,105, + 109,112,111,114,116,108,105,98,32,98,121,32,105,109,112,111, + 114,116,105,110,103,32,110,101,101,100,101,100,32,98,117,105, + 108,116,45,105,110,32,109,111,100,117,108,101,115,32,97,110, + 100,32,105,110,106,101,99,116,105,110,103,32,116,104,101,109, + 10,32,32,32,32,105,110,116,111,32,116,104,101,32,103,108, + 111,98,97,108,32,110,97,109,101,115,112,97,99,101,46,10, + 10,32,32,32,32,65,115,32,115,121,115,32,105,115,32,110, + 101,101,100,101,100,32,102,111,114,32,115,121,115,46,109,111, + 100,117,108,101,115,32,97,99,99,101,115,115,32,97,110,100, + 32,95,105,109,112,32,105,115,32,110,101,101,100,101,100,32, + 116,111,32,108,111,97,100,32,98,117,105,108,116,45,105,110, + 10,32,32,32,32,109,111,100,117,108,101,115,44,32,116,104, + 111,115,101,32,116,119,111,32,109,111,100,117,108,101,115,32, + 109,117,115,116,32,98,101,32,101,120,112,108,105,99,105,116, + 108,121,32,112,97,115,115,101,100,32,105,110,46,10,10,32, + 32,32,32,41,3,114,26,0,0,0,114,101,0,0,0,114, + 71,0,0,0,78,41,15,114,64,0,0,0,114,18,0,0, + 0,114,3,0,0,0,114,105,0,0,0,218,5,105,116,101, + 109,115,114,216,0,0,0,114,86,0,0,0,114,175,0,0, + 0,114,98,0,0,0,114,193,0,0,0,114,155,0,0,0, + 114,161,0,0,0,114,9,0,0,0,114,244,0,0,0,114, + 12,0,0,0,41,10,218,10,115,121,115,95,109,111,100,117, + 108,101,218,11,95,105,109,112,95,109,111,100,117,108,101,90, + 11,109,111,100,117,108,101,95,116,121,112,101,114,20,0,0, + 0,114,110,0,0,0,114,122,0,0,0,114,109,0,0,0, + 90,11,115,101,108,102,95,109,111,100,117,108,101,90,12,98, + 117,105,108,116,105,110,95,110,97,109,101,90,14,98,117,105, + 108,116,105,110,95,109,111,100,117,108,101,114,5,0,0,0, + 114,5,0,0,0,114,6,0,0,0,218,6,95,115,101,116, + 117,112,137,4,0,0,115,40,0,0,0,4,9,4,1,8, + 3,18,1,10,1,10,1,6,1,10,1,6,1,2,2,10, + 1,10,1,2,128,10,3,8,1,10,1,10,1,10,2,14, + 1,4,251,114,248,0,0,0,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, + 0,115,38,0,0,0,116,0,124,0,124,1,131,2,1,0, + 116,1,106,2,160,3,116,4,161,1,1,0,116,1,106,2, + 160,3,116,5,161,1,1,0,100,1,83,0,41,2,122,48, + 73,110,115,116,97,108,108,32,105,109,112,111,114,116,101,114, + 115,32,102,111,114,32,98,117,105,108,116,105,110,32,97,110, + 100,32,102,114,111,122,101,110,32,109,111,100,117,108,101,115, + 78,41,6,114,248,0,0,0,114,18,0,0,0,114,214,0, + 0,0,114,132,0,0,0,114,175,0,0,0,114,193,0,0, + 0,41,2,114,246,0,0,0,114,247,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,6,0,0,0,218,8,95,105, + 110,115,116,97,108,108,172,4,0,0,115,6,0,0,0,10, + 2,12,2,16,1,114,249,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,67, + 0,0,0,115,32,0,0,0,100,1,100,2,108,0,125,0, + 124,0,97,1,124,0,160,2,116,3,106,4,116,5,25,0, + 161,1,1,0,100,2,83,0,41,3,122,57,73,110,115,116, + 97,108,108,32,105,109,112,111,114,116,101,114,115,32,116,104, + 97,116,32,114,101,113,117,105,114,101,32,101,120,116,101,114, + 110,97,108,32,102,105,108,101,115,121,115,116,101,109,32,97, + 99,99,101,115,115,114,25,0,0,0,78,41,6,218,26,95, + 102,114,111,122,101,110,95,105,109,112,111,114,116,108,105,98, + 95,101,120,116,101,114,110,97,108,114,139,0,0,0,114,249, + 0,0,0,114,18,0,0,0,114,105,0,0,0,114,9,0, + 0,0,41,1,114,250,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,6,0,0,0,218,27,95,105,110,115,116,97, + 108,108,95,101,120,116,101,114,110,97,108,95,105,109,112,111, + 114,116,101,114,115,180,4,0,0,115,6,0,0,0,8,3, + 4,1,20,1,114,251,0,0,0,114,190,0,0,0,114,0, + 0,0,0,114,24,0,0,0,41,4,78,78,114,5,0,0, + 0,114,25,0,0,0,41,54,114,10,0,0,0,114,7,0, + 0,0,114,26,0,0,0,114,101,0,0,0,114,71,0,0, + 0,114,139,0,0,0,114,17,0,0,0,114,21,0,0,0, + 114,66,0,0,0,114,37,0,0,0,114,47,0,0,0,114, + 22,0,0,0,114,23,0,0,0,114,55,0,0,0,114,57, + 0,0,0,114,60,0,0,0,114,72,0,0,0,114,74,0, + 0,0,114,83,0,0,0,114,95,0,0,0,114,100,0,0, + 0,114,111,0,0,0,114,124,0,0,0,114,125,0,0,0, + 114,104,0,0,0,114,155,0,0,0,114,161,0,0,0,114, + 165,0,0,0,114,119,0,0,0,114,106,0,0,0,114,172, + 0,0,0,114,173,0,0,0,114,107,0,0,0,114,175,0, + 0,0,114,193,0,0,0,114,200,0,0,0,114,211,0,0, + 0,114,213,0,0,0,114,215,0,0,0,114,221,0,0,0, + 90,15,95,69,82,82,95,77,83,71,95,80,82,69,70,73, + 88,114,223,0,0,0,114,226,0,0,0,218,6,111,98,106, + 101,99,116,114,227,0,0,0,114,228,0,0,0,114,229,0, + 0,0,114,234,0,0,0,114,240,0,0,0,114,243,0,0, + 0,114,244,0,0,0,114,248,0,0,0,114,249,0,0,0, + 114,251,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,6,0,0,0,218,8,60,109,111,100,117, + 108,101,62,1,0,0,0,115,104,0,0,0,4,0,8,22, + 4,9,4,1,4,1,4,3,8,3,8,8,4,8,4,2, + 16,3,14,4,14,77,14,21,8,16,8,37,8,17,14,11, + 8,8,8,11,8,12,8,19,14,26,16,101,10,26,14,45, + 8,72,8,17,8,17,8,30,8,36,8,45,14,15,14,80, + 14,85,8,13,8,9,10,10,8,47,4,16,8,1,8,2, + 6,32,8,3,10,16,14,15,8,37,10,27,8,37,8,7, + 8,35,12,8, }; diff --git a/contrib/tools/python3/src/Python/importlib_external.h b/contrib/tools/python3/src/Python/importlib_external.h index 23af2cd20b9..dcf5505fa74 100644 --- a/contrib/tools/python3/src/Python/importlib_external.h +++ b/contrib/tools/python3/src/Python/importlib_external.h @@ -1,628 +1,626 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_bootstrap_external[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,5,0,0,0,64,0,0,0,115,224,2,0,0,100,0, - 90,0,100,1,100,2,108,1,97,1,100,1,100,2,108,2, - 90,2,100,1,100,2,108,3,97,3,100,1,100,2,108,4, - 90,4,100,1,100,2,108,5,90,5,116,3,106,6,100,3, - 107,2,90,7,101,7,114,76,100,1,100,2,108,8,90,9, - 100,1,100,2,108,10,90,10,110,8,100,1,100,2,108,11, - 90,9,101,7,114,98,100,4,100,5,103,2,90,12,110,6, - 100,5,103,1,90,12,101,13,100,6,100,7,132,0,101,12, - 68,0,131,1,131,1,115,126,74,0,130,1,101,12,100,1, - 25,0,90,14,101,15,101,12,131,1,90,16,100,8,160,17, - 101,12,161,1,90,12,100,9,100,10,132,0,101,12,68,0, - 131,1,90,18,100,11,90,19,100,12,90,20,101,20,101,19, - 23,0,90,21,100,13,100,14,132,0,90,22,100,15,100,16, - 132,0,90,23,100,17,100,18,132,0,90,24,100,19,100,20, - 132,0,90,25,101,7,114,228,100,21,100,22,132,0,90,26, - 110,8,100,23,100,22,132,0,90,26,100,24,100,25,132,0, - 90,27,100,26,100,27,132,0,90,28,100,28,100,29,132,0, - 90,29,100,30,100,31,132,0,90,30,100,32,100,33,132,0, - 90,31,101,7,144,1,114,36,100,34,100,35,132,0,90,32, - 110,8,100,36,100,35,132,0,90,32,100,111,100,38,100,39, - 132,1,90,33,101,34,101,33,106,35,131,1,90,36,100,40, - 160,37,100,41,100,42,161,2,100,43,23,0,90,38,101,39, - 160,40,101,38,100,42,161,2,90,41,100,44,90,42,100,45, - 90,43,100,46,103,1,90,44,100,47,103,1,90,45,101,45, - 4,0,90,46,90,47,100,112,100,2,100,48,156,1,100,49, - 100,50,132,3,90,48,100,51,100,52,132,0,90,49,100,53, - 100,54,132,0,90,50,100,55,100,56,132,0,90,51,100,57, - 100,58,132,0,90,52,100,59,100,60,132,0,90,53,100,61, - 100,62,132,0,90,54,100,63,100,64,132,0,90,55,100,65, - 100,66,132,0,90,56,100,67,100,68,132,0,90,57,100,113, - 100,69,100,70,132,1,90,58,100,114,100,71,100,72,132,1, - 90,59,100,115,100,74,100,75,132,1,90,60,100,76,100,77, - 132,0,90,61,101,62,131,0,90,63,100,116,100,2,101,63, - 100,78,156,2,100,79,100,80,132,3,90,64,71,0,100,81, - 100,82,132,0,100,82,131,2,90,65,71,0,100,83,100,84, - 132,0,100,84,131,2,90,66,71,0,100,85,100,86,132,0, - 100,86,101,66,131,3,90,67,71,0,100,87,100,88,132,0, - 100,88,131,2,90,68,71,0,100,89,100,90,132,0,100,90, - 101,68,101,67,131,4,90,69,71,0,100,91,100,92,132,0, - 100,92,101,68,101,66,131,4,90,70,103,0,90,71,71,0, - 100,93,100,94,132,0,100,94,101,68,101,66,131,4,90,72, - 71,0,100,95,100,96,132,0,100,96,131,2,90,73,71,0, - 100,97,100,98,132,0,100,98,131,2,90,74,71,0,100,99, - 100,100,132,0,100,100,131,2,90,75,71,0,100,101,100,102, - 132,0,100,102,131,2,90,76,100,117,100,103,100,104,132,1, - 90,77,100,105,100,106,132,0,90,78,100,107,100,108,132,0, - 90,79,100,109,100,110,132,0,90,80,100,2,83,0,41,118, - 97,94,1,0,0,67,111,114,101,32,105,109,112,108,101,109, - 101,110,116,97,116,105,111,110,32,111,102,32,112,97,116,104, - 45,98,97,115,101,100,32,105,109,112,111,114,116,46,10,10, - 84,104,105,115,32,109,111,100,117,108,101,32,105,115,32,78, - 79,84,32,109,101,97,110,116,32,116,111,32,98,101,32,100, - 105,114,101,99,116,108,121,32,105,109,112,111,114,116,101,100, - 33,32,73,116,32,104,97,115,32,98,101,101,110,32,100,101, - 115,105,103,110,101,100,32,115,117,99,104,10,116,104,97,116, - 32,105,116,32,99,97,110,32,98,101,32,98,111,111,116,115, - 116,114,97,112,112,101,100,32,105,110,116,111,32,80,121,116, - 104,111,110,32,97,115,32,116,104,101,32,105,109,112,108,101, - 109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,112, - 111,114,116,46,32,65,115,10,115,117,99,104,32,105,116,32, - 114,101,113,117,105,114,101,115,32,116,104,101,32,105,110,106, - 101,99,116,105,111,110,32,111,102,32,115,112,101,99,105,102, - 105,99,32,109,111,100,117,108,101,115,32,97,110,100,32,97, - 116,116,114,105,98,117,116,101,115,32,105,110,32,111,114,100, - 101,114,32,116,111,10,119,111,114,107,46,32,79,110,101,32, - 115,104,111,117,108,100,32,117,115,101,32,105,109,112,111,114, - 116,108,105,98,32,97,115,32,116,104,101,32,112,117,98,108, - 105,99,45,102,97,99,105,110,103,32,118,101,114,115,105,111, - 110,32,111,102,32,116,104,105,115,32,109,111,100,117,108,101, - 46,10,10,233,0,0,0,0,78,90,5,119,105,110,51,50, - 250,1,92,250,1,47,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,99,0,0,0,115, - 26,0,0,0,124,0,93,18,125,1,116,0,124,1,131,1, - 100,0,107,2,86,0,1,0,113,2,100,1,83,0,169,2, - 233,1,0,0,0,78,169,1,218,3,108,101,110,169,2,218, - 2,46,48,218,3,115,101,112,169,0,114,10,0,0,0,250, - 38,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, - 105,98,46,95,98,111,111,116,115,116,114,97,112,95,101,120, - 116,101,114,110,97,108,62,218,9,60,103,101,110,101,120,112, - 114,62,43,0,0,0,243,0,0,0,0,114,12,0,0,0, + 0,5,0,0,0,64,0,0,0,115,250,2,0,0,100,0, + 90,0,100,1,97,1,100,2,100,1,108,2,90,2,100,2, + 100,1,108,3,90,3,100,2,100,1,108,4,90,4,100,2, + 100,1,108,5,90,5,100,2,100,1,108,6,90,6,101,4, + 106,7,100,3,107,2,90,8,101,8,114,40,100,2,100,1, + 108,9,90,10,100,2,100,1,108,11,90,11,110,4,100,2, + 100,1,108,12,90,10,101,8,114,51,100,4,100,5,103,2, + 90,13,110,3,100,5,103,1,90,13,101,14,100,6,100,7, + 132,0,101,13,68,0,131,1,131,1,115,65,74,0,130,1, + 101,13,100,2,25,0,90,15,101,16,101,13,131,1,90,17, + 100,8,160,18,101,13,161,1,90,13,100,9,100,10,132,0, + 101,13,68,0,131,1,90,19,100,11,90,20,100,12,90,21, + 101,21,101,20,23,0,90,22,100,13,100,14,132,0,90,23, + 101,23,131,0,90,24,100,15,100,16,132,0,90,25,100,17, + 100,18,132,0,90,26,100,19,100,20,132,0,90,27,101,8, + 114,119,100,21,100,22,132,0,90,28,110,4,100,23,100,22, + 132,0,90,28,100,24,100,25,132,0,90,29,100,26,100,27, + 132,0,90,30,100,28,100,29,132,0,90,31,100,30,100,31, + 132,0,90,32,100,32,100,33,132,0,90,33,101,8,114,150, + 100,34,100,35,132,0,90,34,110,4,100,36,100,35,132,0, + 90,34,100,112,100,38,100,39,132,1,90,35,101,36,101,35, + 106,37,131,1,90,38,100,40,160,39,100,41,100,42,161,2, + 100,43,23,0,90,40,101,41,160,42,101,40,100,42,161,2, + 90,43,100,44,90,44,100,45,90,45,100,46,103,1,90,46, + 101,8,114,192,101,46,160,47,100,47,161,1,1,0,101,2, + 160,48,161,0,90,49,100,48,103,1,90,50,101,50,4,0, + 90,51,90,52,100,113,100,1,100,49,156,1,100,50,100,51, + 132,3,90,53,100,52,100,53,132,0,90,54,100,54,100,55, + 132,0,90,55,100,56,100,57,132,0,90,56,100,58,100,59, + 132,0,90,57,100,60,100,61,132,0,90,58,100,62,100,63, + 132,0,90,59,100,64,100,65,132,0,90,60,100,66,100,67, + 132,0,90,61,100,68,100,69,132,0,90,62,100,114,100,70, + 100,71,132,1,90,63,100,115,100,72,100,73,132,1,90,64, + 100,116,100,75,100,76,132,1,90,65,100,77,100,78,132,0, + 90,66,101,67,131,0,90,68,100,113,100,1,101,68,100,79, + 156,2,100,80,100,81,132,3,90,69,71,0,100,82,100,83, + 132,0,100,83,131,2,90,70,71,0,100,84,100,85,132,0, + 100,85,131,2,90,71,71,0,100,86,100,87,132,0,100,87, + 101,71,131,3,90,72,71,0,100,88,100,89,132,0,100,89, + 131,2,90,73,71,0,100,90,100,91,132,0,100,91,101,73, + 101,72,131,4,90,74,71,0,100,92,100,93,132,0,100,93, + 101,73,101,71,131,4,90,75,71,0,100,94,100,95,132,0, + 100,95,101,73,101,71,131,4,90,76,71,0,100,96,100,97, + 132,0,100,97,131,2,90,77,71,0,100,98,100,99,132,0, + 100,99,131,2,90,78,71,0,100,100,100,101,132,0,100,101, + 131,2,90,79,71,0,100,102,100,103,132,0,100,103,131,2, + 90,80,100,113,100,104,100,105,132,1,90,81,100,106,100,107, + 132,0,90,82,100,108,100,109,132,0,90,83,100,110,100,111, + 132,0,90,84,100,1,83,0,41,117,97,94,1,0,0,67, + 111,114,101,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,111,102,32,112,97,116,104,45,98,97,115,101,100, + 32,105,109,112,111,114,116,46,10,10,84,104,105,115,32,109, + 111,100,117,108,101,32,105,115,32,78,79,84,32,109,101,97, + 110,116,32,116,111,32,98,101,32,100,105,114,101,99,116,108, + 121,32,105,109,112,111,114,116,101,100,33,32,73,116,32,104, + 97,115,32,98,101,101,110,32,100,101,115,105,103,110,101,100, + 32,115,117,99,104,10,116,104,97,116,32,105,116,32,99,97, + 110,32,98,101,32,98,111,111,116,115,116,114,97,112,112,101, + 100,32,105,110,116,111,32,80,121,116,104,111,110,32,97,115, + 32,116,104,101,32,105,109,112,108,101,109,101,110,116,97,116, + 105,111,110,32,111,102,32,105,109,112,111,114,116,46,32,65, + 115,10,115,117,99,104,32,105,116,32,114,101,113,117,105,114, + 101,115,32,116,104,101,32,105,110,106,101,99,116,105,111,110, + 32,111,102,32,115,112,101,99,105,102,105,99,32,109,111,100, + 117,108,101,115,32,97,110,100,32,97,116,116,114,105,98,117, + 116,101,115,32,105,110,32,111,114,100,101,114,32,116,111,10, + 119,111,114,107,46,32,79,110,101,32,115,104,111,117,108,100, + 32,117,115,101,32,105,109,112,111,114,116,108,105,98,32,97, + 115,32,116,104,101,32,112,117,98,108,105,99,45,102,97,99, + 105,110,103,32,118,101,114,115,105,111,110,32,111,102,32,116, + 104,105,115,32,109,111,100,117,108,101,46,10,10,78,233,0, + 0,0,0,90,5,119,105,110,51,50,250,1,92,250,1,47, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,3,0,0,0,99,0,0,0,115,28,0,0,0,129,0, + 124,0,93,9,125,1,116,0,124,1,131,1,100,0,107,2, + 86,0,1,0,113,2,100,1,83,0,41,2,233,1,0,0, + 0,78,41,1,218,3,108,101,110,41,2,218,2,46,48,218, + 3,115,101,112,169,0,114,7,0,0,0,250,38,60,102,114, + 111,122,101,110,32,105,109,112,111,114,116,108,105,98,46,95, + 98,111,111,116,115,116,114,97,112,95,101,120,116,101,114,110, + 97,108,62,218,9,60,103,101,110,101,120,112,114,62,46,0, + 0,0,115,4,0,0,0,2,128,26,0,114,9,0,0,0, 218,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2, 0,0,0,4,0,0,0,67,0,0,0,115,22,0,0,0, - 104,0,124,0,93,14,125,1,100,0,124,1,155,0,157,2, - 146,2,113,4,83,0,169,1,250,1,58,114,10,0,0,0, - 169,2,114,8,0,0,0,218,1,115,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,9,60,115,101,116,99, - 111,109,112,62,47,0,0,0,114,13,0,0,0,114,19,0, - 0,0,41,1,218,3,119,105,110,41,2,90,6,99,121,103, - 119,105,110,90,6,100,97,114,119,105,110,99,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, - 3,0,0,0,115,60,0,0,0,116,0,106,1,160,2,116, - 3,161,1,114,48,116,0,106,1,160,2,116,4,161,1,114, - 30,100,1,137,0,110,4,100,2,137,0,135,0,102,1,100, - 3,100,4,132,8,125,0,110,8,100,5,100,4,132,0,125, - 0,124,0,83,0,41,6,78,90,12,80,89,84,72,79,78, - 67,65,83,69,79,75,115,12,0,0,0,80,89,84,72,79, - 78,67,65,83,69,79,75,99,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,19,0,0,0, - 115,20,0,0,0,116,0,106,1,106,2,12,0,111,18,136, - 0,116,3,106,4,118,0,83,0,41,1,122,94,84,114,117, - 101,32,105,102,32,102,105,108,101,110,97,109,101,115,32,109, - 117,115,116,32,98,101,32,99,104,101,99,107,101,100,32,99, - 97,115,101,45,105,110,115,101,110,115,105,116,105,118,101,108, - 121,32,97,110,100,32,105,103,110,111,114,101,32,101,110,118, - 105,114,111,110,109,101,110,116,32,102,108,97,103,115,32,97, - 114,101,32,110,111,116,32,115,101,116,46,41,5,218,3,115, - 121,115,218,5,102,108,97,103,115,218,18,105,103,110,111,114, - 101,95,101,110,118,105,114,111,110,109,101,110,116,218,3,95, - 111,115,90,7,101,110,118,105,114,111,110,114,10,0,0,0, - 169,1,218,3,107,101,121,114,10,0,0,0,114,11,0,0, - 0,218,11,95,114,101,108,97,120,95,99,97,115,101,64,0, - 0,0,115,2,0,0,0,0,2,122,37,95,109,97,107,101, - 95,114,101,108,97,120,95,99,97,115,101,46,60,108,111,99, - 97,108,115,62,46,95,114,101,108,97,120,95,99,97,115,101, - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,83,0,0,0,115,4,0,0,0,100,1, - 83,0,41,2,122,53,84,114,117,101,32,105,102,32,102,105, - 108,101,110,97,109,101,115,32,109,117,115,116,32,98,101,32, - 99,104,101,99,107,101,100,32,99,97,115,101,45,105,110,115, - 101,110,115,105,116,105,118,101,108,121,46,70,114,10,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,27,0,0,0,68,0,0,0,115,2, - 0,0,0,0,2,41,5,114,21,0,0,0,218,8,112,108, - 97,116,102,111,114,109,218,10,115,116,97,114,116,115,119,105, - 116,104,218,27,95,67,65,83,69,95,73,78,83,69,78,83, - 73,84,73,86,69,95,80,76,65,84,70,79,82,77,83,218, - 35,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, - 86,69,95,80,76,65,84,70,79,82,77,83,95,83,84,82, - 95,75,69,89,41,1,114,27,0,0,0,114,10,0,0,0, - 114,25,0,0,0,114,11,0,0,0,218,16,95,109,97,107, - 101,95,114,101,108,97,120,95,99,97,115,101,57,0,0,0, - 115,14,0,0,0,0,1,12,1,12,1,6,2,4,2,14, - 4,8,3,114,32,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, - 0,115,20,0,0,0,116,0,124,0,131,1,100,1,64,0, - 160,1,100,2,100,3,161,2,83,0,41,4,122,42,67,111, - 110,118,101,114,116,32,97,32,51,50,45,98,105,116,32,105, - 110,116,101,103,101,114,32,116,111,32,108,105,116,116,108,101, - 45,101,110,100,105,97,110,46,236,3,0,0,0,255,127,255, - 127,3,0,233,4,0,0,0,218,6,108,105,116,116,108,101, - 41,2,218,3,105,110,116,218,8,116,111,95,98,121,116,101, - 115,41,1,218,1,120,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,12,95,112,97,99,107,95,117,105,110, - 116,51,50,74,0,0,0,115,2,0,0,0,0,2,114,39, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0, - 0,116,0,124,0,131,1,100,1,107,2,115,16,74,0,130, - 1,116,1,160,2,124,0,100,2,161,2,83,0,41,3,122, - 47,67,111,110,118,101,114,116,32,52,32,98,121,116,101,115, + 104,0,124,0,93,7,125,1,100,0,124,1,155,0,157,2, + 146,2,113,2,83,0,41,1,250,1,58,114,7,0,0,0, + 41,2,114,5,0,0,0,218,1,115,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,218,9,60,115,101,116,99, + 111,109,112,62,50,0,0,0,115,2,0,0,0,22,0,114, + 13,0,0,0,41,1,218,3,119,105,110,41,2,90,6,99, + 121,103,119,105,110,90,6,100,97,114,119,105,110,99,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0, + 0,0,3,0,0,0,115,62,0,0,0,116,0,106,1,160, + 2,116,3,161,1,114,25,116,0,106,1,160,2,116,4,161, + 1,114,15,100,1,137,0,110,2,100,2,137,0,135,0,102, + 1,100,3,100,4,132,8,125,0,124,0,83,0,100,5,100, + 4,132,0,125,0,124,0,83,0,41,6,78,90,12,80,89, + 84,72,79,78,67,65,83,69,79,75,115,12,0,0,0,80, + 89,84,72,79,78,67,65,83,69,79,75,99,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 19,0,0,0,115,20,0,0,0,116,0,106,1,106,2,12, + 0,111,9,136,0,116,3,106,4,118,0,83,0,41,1,122, + 94,84,114,117,101,32,105,102,32,102,105,108,101,110,97,109, + 101,115,32,109,117,115,116,32,98,101,32,99,104,101,99,107, + 101,100,32,99,97,115,101,45,105,110,115,101,110,115,105,116, + 105,118,101,108,121,32,97,110,100,32,105,103,110,111,114,101, + 32,101,110,118,105,114,111,110,109,101,110,116,32,102,108,97, + 103,115,32,97,114,101,32,110,111,116,32,115,101,116,46,41, + 5,218,3,115,121,115,218,5,102,108,97,103,115,218,18,105, + 103,110,111,114,101,95,101,110,118,105,114,111,110,109,101,110, + 116,218,3,95,111,115,90,7,101,110,118,105,114,111,110,114, + 7,0,0,0,169,1,218,3,107,101,121,114,7,0,0,0, + 114,8,0,0,0,218,11,95,114,101,108,97,120,95,99,97, + 115,101,67,0,0,0,243,2,0,0,0,20,2,122,37,95, + 109,97,107,101,95,114,101,108,97,120,95,99,97,115,101,46, + 60,108,111,99,97,108,115,62,46,95,114,101,108,97,120,95, + 99,97,115,101,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,83,0,0,0,243,4,0, + 0,0,100,1,83,0,41,2,122,53,84,114,117,101,32,105, + 102,32,102,105,108,101,110,97,109,101,115,32,109,117,115,116, + 32,98,101,32,99,104,101,99,107,101,100,32,99,97,115,101, + 45,105,110,115,101,110,115,105,116,105,118,101,108,121,46,70, + 114,7,0,0,0,114,7,0,0,0,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,114,21,0,0,0,71,0, + 0,0,243,2,0,0,0,4,2,41,5,114,15,0,0,0, + 218,8,112,108,97,116,102,111,114,109,218,10,115,116,97,114, + 116,115,119,105,116,104,218,27,95,67,65,83,69,95,73,78, + 83,69,78,83,73,84,73,86,69,95,80,76,65,84,70,79, + 82,77,83,218,35,95,67,65,83,69,95,73,78,83,69,78, + 83,73,84,73,86,69,95,80,76,65,84,70,79,82,77,83, + 95,83,84,82,95,75,69,89,41,1,114,21,0,0,0,114, + 7,0,0,0,114,19,0,0,0,114,8,0,0,0,218,16, + 95,109,97,107,101,95,114,101,108,97,120,95,99,97,115,101, + 60,0,0,0,115,16,0,0,0,12,1,12,1,6,1,4, + 2,12,2,4,7,8,253,4,3,114,29,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4, + 0,0,0,67,0,0,0,115,20,0,0,0,116,0,124,0, + 131,1,100,1,64,0,160,1,100,2,100,3,161,2,83,0, + 41,4,122,42,67,111,110,118,101,114,116,32,97,32,51,50, + 45,98,105,116,32,105,110,116,101,103,101,114,32,116,111,32, + 108,105,116,116,108,101,45,101,110,100,105,97,110,46,236,3, + 0,0,0,255,127,255,127,3,0,233,4,0,0,0,218,6, + 108,105,116,116,108,101,41,2,218,3,105,110,116,218,8,116, + 111,95,98,121,116,101,115,41,1,218,1,120,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,218,12,95,112,97, + 99,107,95,117,105,110,116,51,50,79,0,0,0,114,22,0, + 0,0,114,36,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,4,0,0,0,67,0,0,0, + 243,28,0,0,0,116,0,124,0,131,1,100,1,107,2,115, + 8,74,0,130,1,116,1,160,2,124,0,100,2,161,2,83, + 0,41,3,122,47,67,111,110,118,101,114,116,32,52,32,98, + 121,116,101,115,32,105,110,32,108,105,116,116,108,101,45,101, + 110,100,105,97,110,32,116,111,32,97,110,32,105,110,116,101, + 103,101,114,46,114,31,0,0,0,114,32,0,0,0,169,3, + 114,4,0,0,0,114,33,0,0,0,218,10,102,114,111,109, + 95,98,121,116,101,115,169,1,218,4,100,97,116,97,114,7, + 0,0,0,114,7,0,0,0,114,8,0,0,0,218,14,95, + 117,110,112,97,99,107,95,117,105,110,116,51,50,84,0,0, + 0,243,4,0,0,0,16,2,12,1,114,42,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 4,0,0,0,67,0,0,0,114,37,0,0,0,41,3,122, + 47,67,111,110,118,101,114,116,32,50,32,98,121,116,101,115, 32,105,110,32,108,105,116,116,108,101,45,101,110,100,105,97, 110,32,116,111,32,97,110,32,105,110,116,101,103,101,114,46, - 114,34,0,0,0,114,35,0,0,0,169,3,114,6,0,0, - 0,114,36,0,0,0,218,10,102,114,111,109,95,98,121,116, - 101,115,169,1,218,4,100,97,116,97,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,14,95,117,110,112,97, - 99,107,95,117,105,110,116,51,50,79,0,0,0,115,4,0, - 0,0,0,2,16,1,114,44,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, - 67,0,0,0,115,28,0,0,0,116,0,124,0,131,1,100, - 1,107,2,115,16,74,0,130,1,116,1,160,2,124,0,100, - 2,161,2,83,0,41,3,122,47,67,111,110,118,101,114,116, - 32,50,32,98,121,116,101,115,32,105,110,32,108,105,116,116, - 108,101,45,101,110,100,105,97,110,32,116,111,32,97,110,32, - 105,110,116,101,103,101,114,46,233,2,0,0,0,114,35,0, - 0,0,114,40,0,0,0,114,42,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,14,95,117,110, - 112,97,99,107,95,117,105,110,116,49,54,84,0,0,0,115, - 4,0,0,0,0,2,16,1,114,46,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0, - 0,0,71,0,0,0,115,228,0,0,0,124,0,115,8,100, - 1,83,0,116,0,124,0,131,1,100,2,107,2,114,28,124, - 0,100,3,25,0,83,0,100,1,125,1,103,0,125,2,116, - 1,116,2,106,3,124,0,131,2,68,0,93,122,92,2,125, - 3,125,4,124,3,160,4,116,5,161,1,115,76,124,3,160, - 6,116,5,161,1,114,102,124,3,160,7,116,8,161,1,112, - 88,124,1,125,1,116,9,124,4,23,0,103,1,125,2,113, - 48,124,3,160,6,100,4,161,1,114,152,124,1,160,10,161, - 0,124,3,160,10,161,0,107,3,114,140,124,3,125,1,124, - 4,103,1,125,2,113,170,124,2,160,11,124,4,161,1,1, - 0,113,48,124,3,112,158,124,1,125,1,124,2,160,11,124, - 4,161,1,1,0,113,48,100,5,100,6,132,0,124,2,68, - 0,131,1,125,2,116,0,124,2,131,1,100,2,107,2,114, - 214,124,2,100,3,25,0,115,214,124,1,116,9,23,0,83, - 0,124,1,116,9,160,12,124,2,161,1,23,0,83,0,41, - 7,250,31,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,106,111,105,110,40, - 41,46,114,14,0,0,0,114,4,0,0,0,114,0,0,0, - 0,114,16,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,5,0,0,0,83,0,0,0,115, - 26,0,0,0,103,0,124,0,93,18,125,1,124,1,114,4, - 124,1,160,0,116,1,161,1,145,2,113,4,83,0,114,10, - 0,0,0,169,2,218,6,114,115,116,114,105,112,218,15,112, - 97,116,104,95,115,101,112,97,114,97,116,111,114,115,169,2, - 114,8,0,0,0,218,1,112,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,10,60,108,105,115,116,99,111, - 109,112,62,114,0,0,0,114,13,0,0,0,250,30,95,112, - 97,116,104,95,106,111,105,110,46,60,108,111,99,97,108,115, - 62,46,60,108,105,115,116,99,111,109,112,62,41,13,114,6, - 0,0,0,218,3,109,97,112,114,24,0,0,0,218,15,95, - 112,97,116,104,95,115,112,108,105,116,114,111,111,116,114,29, - 0,0,0,218,14,112,97,116,104,95,115,101,112,95,116,117, - 112,108,101,218,8,101,110,100,115,119,105,116,104,114,49,0, - 0,0,114,50,0,0,0,218,8,112,97,116,104,95,115,101, - 112,218,8,99,97,115,101,102,111,108,100,218,6,97,112,112, - 101,110,100,218,4,106,111,105,110,41,5,218,10,112,97,116, - 104,95,112,97,114,116,115,218,4,114,111,111,116,218,4,112, - 97,116,104,90,8,110,101,119,95,114,111,111,116,218,4,116, - 97,105,108,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,10,95,112,97,116,104,95,106,111,105,110,91,0, - 0,0,115,42,0,0,0,0,2,4,1,4,1,12,1,8, - 1,4,1,4,1,20,1,20,1,14,1,12,1,10,1,16, - 3,4,1,8,2,12,2,8,1,12,1,14,1,20,2,8, - 1,114,67,0,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,4,0,0,0,71,0,0,0,115, - 20,0,0,0,116,0,160,1,100,1,100,2,132,0,124,0, - 68,0,131,1,161,1,83,0,41,3,114,47,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 5,0,0,0,83,0,0,0,115,26,0,0,0,103,0,124, - 0,93,18,125,1,124,1,114,4,124,1,160,0,116,1,161, - 1,145,2,113,4,83,0,114,10,0,0,0,114,48,0,0, - 0,41,2,114,8,0,0,0,218,4,112,97,114,116,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,53,0, - 0,0,123,0,0,0,115,4,0,0,0,6,1,6,255,114, - 54,0,0,0,41,2,114,59,0,0,0,114,62,0,0,0, - 41,1,114,63,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,67,0,0,0,121,0,0,0,115, - 6,0,0,0,0,2,10,1,2,255,99,1,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,3, - 0,0,0,115,66,0,0,0,116,0,135,0,102,1,100,1, - 100,2,132,8,116,1,68,0,131,1,131,1,125,1,124,1, - 100,3,107,0,114,38,100,4,136,0,102,2,83,0,136,0, - 100,5,124,1,133,2,25,0,136,0,124,1,100,6,23,0, - 100,5,133,2,25,0,102,2,83,0,41,7,122,32,82,101, - 112,108,97,99,101,109,101,110,116,32,102,111,114,32,111,115, - 46,112,97,116,104,46,115,112,108,105,116,40,41,46,99,1, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, - 0,0,0,51,0,0,0,115,24,0,0,0,124,0,93,16, + 233,2,0,0,0,114,32,0,0,0,114,38,0,0,0,114, + 40,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,14,95,117,110,112,97,99,107,95,117,105,110, + 116,49,54,89,0,0,0,114,43,0,0,0,114,45,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,4,0,0,0,71,0,0,0,115,228,0,0,0,124, + 0,115,4,100,1,83,0,116,0,124,0,131,1,100,2,107, + 2,114,14,124,0,100,3,25,0,83,0,100,1,125,1,103, + 0,125,2,116,1,116,2,106,3,124,0,131,2,68,0,93, + 61,92,2,125,3,125,4,124,3,160,4,116,5,161,1,115, + 38,124,3,160,6,116,5,161,1,114,51,124,3,160,7,116, + 8,161,1,112,44,124,1,125,1,116,9,124,4,23,0,103, + 1,125,2,113,24,124,3,160,6,100,4,161,1,114,76,124, + 1,160,10,161,0,124,3,160,10,161,0,107,3,114,70,124, + 3,125,1,124,4,103,1,125,2,113,24,124,2,160,11,124, + 4,161,1,1,0,113,24,124,3,112,79,124,1,125,1,124, + 2,160,11,124,4,161,1,1,0,113,24,100,5,100,6,132, + 0,124,2,68,0,131,1,125,2,116,0,124,2,131,1,100, + 2,107,2,114,107,124,2,100,3,25,0,115,107,124,1,116, + 9,23,0,83,0,124,1,116,9,160,12,124,2,161,1,23, + 0,83,0,41,7,250,31,82,101,112,108,97,99,101,109,101, + 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,106, + 111,105,110,40,41,46,114,10,0,0,0,114,3,0,0,0, + 114,0,0,0,0,114,11,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,5,0,0,0,83, + 0,0,0,243,26,0,0,0,103,0,124,0,93,9,125,1, + 124,1,114,2,124,1,160,0,116,1,161,1,145,2,113,2, + 83,0,114,7,0,0,0,169,2,218,6,114,115,116,114,105, + 112,218,15,112,97,116,104,95,115,101,112,97,114,97,116,111, + 114,115,169,2,114,5,0,0,0,218,1,112,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,218,10,60,108,105, + 115,116,99,111,109,112,62,119,0,0,0,115,2,0,0,0, + 26,0,250,30,95,112,97,116,104,95,106,111,105,110,46,60, + 108,111,99,97,108,115,62,46,60,108,105,115,116,99,111,109, + 112,62,41,13,114,4,0,0,0,218,3,109,97,112,114,18, + 0,0,0,218,15,95,112,97,116,104,95,115,112,108,105,116, + 114,111,111,116,114,26,0,0,0,218,14,112,97,116,104,95, + 115,101,112,95,116,117,112,108,101,218,8,101,110,100,115,119, + 105,116,104,114,49,0,0,0,114,50,0,0,0,218,8,112, + 97,116,104,95,115,101,112,218,8,99,97,115,101,102,111,108, + 100,218,6,97,112,112,101,110,100,218,4,106,111,105,110,41, + 5,218,10,112,97,116,104,95,112,97,114,116,115,218,4,114, + 111,111,116,218,4,112,97,116,104,90,8,110,101,119,95,114, + 111,111,116,218,4,116,97,105,108,114,7,0,0,0,114,7, + 0,0,0,114,8,0,0,0,218,10,95,112,97,116,104,95, + 106,111,105,110,96,0,0,0,115,42,0,0,0,4,2,4, + 1,12,1,8,1,4,1,4,1,20,1,20,1,14,1,12, + 1,10,1,16,1,4,3,8,1,12,2,8,2,12,1,14, + 1,20,1,8,2,14,1,114,67,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,71,0,0,0,115,20,0,0,0,116,0,160,1,100,1, + 100,2,132,0,124,0,68,0,131,1,161,1,83,0,41,3, + 114,46,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,5,0,0,0,83,0,0,0,114,47, + 0,0,0,114,7,0,0,0,114,48,0,0,0,41,2,114, + 5,0,0,0,218,4,112,97,114,116,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,114,53,0,0,0,128,0, + 0,0,115,6,0,0,0,6,0,4,1,16,255,114,54,0, + 0,0,41,2,114,59,0,0,0,114,62,0,0,0,41,1, + 114,63,0,0,0,114,7,0,0,0,114,7,0,0,0,114, + 8,0,0,0,114,67,0,0,0,126,0,0,0,115,6,0, + 0,0,10,2,2,1,8,255,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,4,0,0,0,3,0,0, + 0,115,66,0,0,0,116,0,135,0,102,1,100,1,100,2, + 132,8,116,1,68,0,131,1,131,1,125,1,124,1,100,3, + 107,0,114,19,100,4,136,0,102,2,83,0,136,0,100,5, + 124,1,133,2,25,0,136,0,124,1,100,6,23,0,100,5, + 133,2,25,0,102,2,83,0,41,7,122,32,82,101,112,108, + 97,99,101,109,101,110,116,32,102,111,114,32,111,115,46,112, + 97,116,104,46,115,112,108,105,116,40,41,46,99,1,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, + 0,51,0,0,0,115,26,0,0,0,129,0,124,0,93,8, 125,1,136,0,160,0,124,1,161,1,86,0,1,0,113,2, 100,0,83,0,169,1,78,41,1,218,5,114,102,105,110,100, - 114,51,0,0,0,169,1,114,65,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,12,0,0,0,129,0,0,0,114, - 13,0,0,0,122,30,95,112,97,116,104,95,115,112,108,105, - 116,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, - 120,112,114,62,114,0,0,0,0,114,14,0,0,0,78,114, - 4,0,0,0,41,2,218,3,109,97,120,114,50,0,0,0, - 41,2,114,65,0,0,0,218,1,105,114,10,0,0,0,114, - 71,0,0,0,114,11,0,0,0,218,11,95,112,97,116,104, - 95,115,112,108,105,116,127,0,0,0,115,8,0,0,0,0, - 2,22,1,8,1,8,1,114,74,0,0,0,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, - 0,67,0,0,0,115,10,0,0,0,116,0,160,1,124,0, - 161,1,83,0,41,1,122,126,83,116,97,116,32,116,104,101, - 32,112,97,116,104,46,10,10,32,32,32,32,77,97,100,101, - 32,97,32,115,101,112,97,114,97,116,101,32,102,117,110,99, - 116,105,111,110,32,116,111,32,109,97,107,101,32,105,116,32, - 101,97,115,105,101,114,32,116,111,32,111,118,101,114,114,105, - 100,101,32,105,110,32,101,120,112,101,114,105,109,101,110,116, - 115,10,32,32,32,32,40,101,46,103,46,32,99,97,99,104, - 101,32,115,116,97,116,32,114,101,115,117,108,116,115,41,46, - 10,10,32,32,32,32,41,2,114,24,0,0,0,90,4,115, - 116,97,116,114,71,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,10,95,112,97,116,104,95,115, - 116,97,116,135,0,0,0,115,2,0,0,0,0,7,114,75, - 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,8,0,0,0,67,0,0,0,115,48,0,0, - 0,122,12,116,0,124,0,131,1,125,2,87,0,110,20,4, - 0,116,1,121,32,1,0,1,0,1,0,89,0,100,1,83, - 0,48,0,124,2,106,2,100,2,64,0,124,1,107,2,83, - 0,41,3,122,49,84,101,115,116,32,119,104,101,116,104,101, - 114,32,116,104,101,32,112,97,116,104,32,105,115,32,116,104, - 101,32,115,112,101,99,105,102,105,101,100,32,109,111,100,101, - 32,116,121,112,101,46,70,105,0,240,0,0,41,3,114,75, - 0,0,0,218,7,79,83,69,114,114,111,114,218,7,115,116, - 95,109,111,100,101,41,3,114,65,0,0,0,218,4,109,111, - 100,101,90,9,115,116,97,116,95,105,110,102,111,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,18,95,112, - 97,116,104,95,105,115,95,109,111,100,101,95,116,121,112,101, - 145,0,0,0,115,10,0,0,0,0,2,2,1,12,1,12, - 1,8,1,114,79,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,10,0,0,0,116,0,124,0,100,1,131,2,83,0, - 41,2,122,31,82,101,112,108,97,99,101,109,101,110,116,32, - 102,111,114,32,111,115,46,112,97,116,104,46,105,115,102,105, - 108,101,46,105,0,128,0,0,41,1,114,79,0,0,0,114, - 71,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,12,95,112,97,116,104,95,105,115,102,105,108, - 101,154,0,0,0,115,2,0,0,0,0,2,114,80,0,0, - 0,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,3,0,0,0,67,0,0,0,115,22,0,0,0,124, - 0,115,12,116,0,160,1,161,0,125,0,116,2,124,0,100, - 1,131,2,83,0,41,2,122,30,82,101,112,108,97,99,101, - 109,101,110,116,32,102,111,114,32,111,115,46,112,97,116,104, - 46,105,115,100,105,114,46,105,0,64,0,0,41,3,114,24, - 0,0,0,218,6,103,101,116,99,119,100,114,79,0,0,0, - 114,71,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,11,95,112,97,116,104,95,105,115,100,105, - 114,159,0,0,0,115,6,0,0,0,0,2,4,1,8,1, - 114,82,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,62, - 0,0,0,124,0,115,8,100,1,83,0,116,0,160,1,124, - 0,161,1,100,2,25,0,160,2,100,3,100,4,161,2,125, - 1,116,3,124,1,131,1,100,5,107,4,111,60,124,1,160, - 4,100,6,161,1,112,60,124,1,160,5,100,4,161,1,83, - 0,41,7,250,30,82,101,112,108,97,99,101,109,101,110,116, - 32,102,111,114,32,111,115,46,112,97,116,104,46,105,115,97, - 98,115,46,70,114,0,0,0,0,114,2,0,0,0,114,1, - 0,0,0,114,4,0,0,0,122,2,92,92,41,6,114,24, - 0,0,0,114,56,0,0,0,218,7,114,101,112,108,97,99, - 101,114,6,0,0,0,114,29,0,0,0,114,58,0,0,0, - 41,2,114,65,0,0,0,114,64,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,11,95,112,97, - 116,104,95,105,115,97,98,115,167,0,0,0,115,8,0,0, - 0,0,2,4,1,4,1,22,1,114,85,0,0,0,99,1, + 114,51,0,0,0,169,1,114,65,0,0,0,114,7,0,0, + 0,114,8,0,0,0,114,9,0,0,0,134,0,0,0,115, + 4,0,0,0,2,128,24,0,122,30,95,112,97,116,104,95, + 115,112,108,105,116,46,60,108,111,99,97,108,115,62,46,60, + 103,101,110,101,120,112,114,62,114,0,0,0,0,114,10,0, + 0,0,78,114,3,0,0,0,41,2,218,3,109,97,120,114, + 50,0,0,0,41,2,114,65,0,0,0,218,1,105,114,7, + 0,0,0,114,71,0,0,0,114,8,0,0,0,218,11,95, + 112,97,116,104,95,115,112,108,105,116,132,0,0,0,115,8, + 0,0,0,22,2,8,1,8,1,28,1,114,74,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,115,10,0,0,0,116,0, + 160,1,124,0,161,1,83,0,41,1,122,126,83,116,97,116, + 32,116,104,101,32,112,97,116,104,46,10,10,32,32,32,32, + 77,97,100,101,32,97,32,115,101,112,97,114,97,116,101,32, + 102,117,110,99,116,105,111,110,32,116,111,32,109,97,107,101, + 32,105,116,32,101,97,115,105,101,114,32,116,111,32,111,118, + 101,114,114,105,100,101,32,105,110,32,101,120,112,101,114,105, + 109,101,110,116,115,10,32,32,32,32,40,101,46,103,46,32, + 99,97,99,104,101,32,115,116,97,116,32,114,101,115,117,108, + 116,115,41,46,10,10,32,32,32,32,41,2,114,18,0,0, + 0,90,4,115,116,97,116,114,71,0,0,0,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,218,10,95,112,97, + 116,104,95,115,116,97,116,140,0,0,0,115,2,0,0,0, + 10,7,114,75,0,0,0,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,8,0,0,0,67,0,0,0, + 115,48,0,0,0,122,6,116,0,124,0,131,1,125,2,87, + 0,110,10,4,0,116,1,121,16,1,0,1,0,1,0,89, + 0,100,1,83,0,119,0,124,2,106,2,100,2,64,0,124, + 1,107,2,83,0,41,3,122,49,84,101,115,116,32,119,104, + 101,116,104,101,114,32,116,104,101,32,112,97,116,104,32,105, + 115,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, + 109,111,100,101,32,116,121,112,101,46,70,105,0,240,0,0, + 41,3,114,75,0,0,0,218,7,79,83,69,114,114,111,114, + 218,7,115,116,95,109,111,100,101,41,3,114,65,0,0,0, + 218,4,109,111,100,101,90,9,115,116,97,116,95,105,110,102, + 111,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, + 218,18,95,112,97,116,104,95,105,115,95,109,111,100,101,95, + 116,121,112,101,150,0,0,0,115,12,0,0,0,2,2,12, + 1,12,1,6,1,2,255,14,2,114,79,0,0,0,99,1, 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3, - 0,0,0,67,0,0,0,115,10,0,0,0,124,0,160,0, - 116,1,161,1,83,0,41,1,114,83,0,0,0,41,2,114, - 29,0,0,0,114,50,0,0,0,114,71,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,85,0, - 0,0,175,0,0,0,115,2,0,0,0,0,2,233,182,1, - 0,0,99,3,0,0,0,0,0,0,0,0,0,0,0,6, - 0,0,0,11,0,0,0,67,0,0,0,115,178,0,0,0, - 100,1,160,0,124,0,116,1,124,0,131,1,161,2,125,3, - 116,2,160,3,124,3,116,2,106,4,116,2,106,5,66,0, - 116,2,106,6,66,0,124,2,100,2,64,0,161,3,125,4, - 122,70,116,7,160,8,124,4,100,3,161,2,143,26,125,5, - 124,5,160,9,124,1,161,1,1,0,87,0,100,4,4,0, - 4,0,131,3,1,0,110,16,49,0,115,94,48,0,1,0, - 1,0,1,0,89,0,1,0,116,2,160,10,124,3,124,0, - 161,2,1,0,87,0,110,54,4,0,116,11,121,172,1,0, - 1,0,1,0,122,14,116,2,160,12,124,3,161,1,1,0, - 87,0,110,18,4,0,116,11,121,164,1,0,1,0,1,0, - 89,0,110,2,48,0,130,0,89,0,110,2,48,0,100,4, - 83,0,41,5,122,162,66,101,115,116,45,101,102,102,111,114, - 116,32,102,117,110,99,116,105,111,110,32,116,111,32,119,114, - 105,116,101,32,100,97,116,97,32,116,111,32,97,32,112,97, - 116,104,32,97,116,111,109,105,99,97,108,108,121,46,10,32, - 32,32,32,66,101,32,112,114,101,112,97,114,101,100,32,116, - 111,32,104,97,110,100,108,101,32,97,32,70,105,108,101,69, - 120,105,115,116,115,69,114,114,111,114,32,105,102,32,99,111, - 110,99,117,114,114,101,110,116,32,119,114,105,116,105,110,103, - 32,111,102,32,116,104,101,10,32,32,32,32,116,101,109,112, - 111,114,97,114,121,32,102,105,108,101,32,105,115,32,97,116, - 116,101,109,112,116,101,100,46,250,5,123,125,46,123,125,114, - 86,0,0,0,90,2,119,98,78,41,13,218,6,102,111,114, - 109,97,116,218,2,105,100,114,24,0,0,0,90,4,111,112, - 101,110,90,6,79,95,69,88,67,76,90,7,79,95,67,82, - 69,65,84,90,8,79,95,87,82,79,78,76,89,218,3,95, - 105,111,218,6,70,105,108,101,73,79,218,5,119,114,105,116, - 101,114,84,0,0,0,114,76,0,0,0,90,6,117,110,108, - 105,110,107,41,6,114,65,0,0,0,114,43,0,0,0,114, - 78,0,0,0,90,8,112,97,116,104,95,116,109,112,90,2, - 102,100,218,4,102,105,108,101,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,13,95,119,114,105,116,101,95, - 97,116,111,109,105,99,180,0,0,0,115,28,0,0,0,0, - 5,16,1,6,1,22,255,4,2,2,3,14,1,40,1,16, - 1,12,1,2,1,14,1,12,1,6,1,114,94,0,0,0, - 105,97,13,0,0,114,45,0,0,0,114,35,0,0,0,115, - 2,0,0,0,13,10,90,11,95,95,112,121,99,97,99,104, - 101,95,95,122,4,111,112,116,45,122,3,46,112,121,122,4, - 46,112,121,99,41,1,218,12,111,112,116,105,109,105,122,97, - 116,105,111,110,99,2,0,0,0,0,0,0,0,1,0,0, - 0,12,0,0,0,5,0,0,0,67,0,0,0,115,88,1, - 0,0,124,1,100,1,117,1,114,52,116,0,160,1,100,2, - 116,2,161,2,1,0,124,2,100,1,117,1,114,40,100,3, - 125,3,116,3,124,3,131,1,130,1,124,1,114,48,100,4, - 110,2,100,5,125,2,116,4,160,5,124,0,161,1,125,0, - 116,6,124,0,131,1,92,2,125,4,125,5,124,5,160,7, - 100,6,161,1,92,3,125,6,125,7,125,8,116,8,106,9, - 106,10,125,9,124,9,100,1,117,0,114,114,116,11,100,7, - 131,1,130,1,100,4,160,12,124,6,114,126,124,6,110,2, - 124,8,124,7,124,9,103,3,161,1,125,10,124,2,100,1, - 117,0,114,172,116,8,106,13,106,14,100,8,107,2,114,164, - 100,4,125,2,110,8,116,8,106,13,106,14,125,2,116,15, - 124,2,131,1,125,2,124,2,100,4,107,3,114,224,124,2, - 160,16,161,0,115,210,116,17,100,9,160,18,124,2,161,1, - 131,1,130,1,100,10,160,18,124,10,116,19,124,2,161,3, - 125,10,124,10,116,20,100,8,25,0,23,0,125,11,116,8, - 106,21,100,1,117,1,144,1,114,76,116,22,124,4,131,1, - 144,1,115,16,116,23,116,4,160,24,161,0,124,4,131,2, - 125,4,124,4,100,5,25,0,100,11,107,2,144,1,114,56, - 124,4,100,8,25,0,116,25,118,1,144,1,114,56,124,4, - 100,12,100,1,133,2,25,0,125,4,116,23,116,8,106,21, - 124,4,160,26,116,25,161,1,124,11,131,3,83,0,116,23, - 124,4,116,27,124,11,131,3,83,0,41,13,97,254,2,0, - 0,71,105,118,101,110,32,116,104,101,32,112,97,116,104,32, - 116,111,32,97,32,46,112,121,32,102,105,108,101,44,32,114, - 101,116,117,114,110,32,116,104,101,32,112,97,116,104,32,116, - 111,32,105,116,115,32,46,112,121,99,32,102,105,108,101,46, - 10,10,32,32,32,32,84,104,101,32,46,112,121,32,102,105, - 108,101,32,100,111,101,115,32,110,111,116,32,110,101,101,100, - 32,116,111,32,101,120,105,115,116,59,32,116,104,105,115,32, - 115,105,109,112,108,121,32,114,101,116,117,114,110,115,32,116, - 104,101,32,112,97,116,104,32,116,111,32,116,104,101,10,32, - 32,32,32,46,112,121,99,32,102,105,108,101,32,99,97,108, - 99,117,108,97,116,101,100,32,97,115,32,105,102,32,116,104, - 101,32,46,112,121,32,102,105,108,101,32,119,101,114,101,32, - 105,109,112,111,114,116,101,100,46,10,10,32,32,32,32,84, - 104,101,32,39,111,112,116,105,109,105,122,97,116,105,111,110, - 39,32,112,97,114,97,109,101,116,101,114,32,99,111,110,116, - 114,111,108,115,32,116,104,101,32,112,114,101,115,117,109,101, - 100,32,111,112,116,105,109,105,122,97,116,105,111,110,32,108, - 101,118,101,108,32,111,102,10,32,32,32,32,116,104,101,32, - 98,121,116,101,99,111,100,101,32,102,105,108,101,46,32,73, - 102,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39, - 32,105,115,32,110,111,116,32,78,111,110,101,44,32,116,104, - 101,32,115,116,114,105,110,103,32,114,101,112,114,101,115,101, - 110,116,97,116,105,111,110,10,32,32,32,32,111,102,32,116, - 104,101,32,97,114,103,117,109,101,110,116,32,105,115,32,116, - 97,107,101,110,32,97,110,100,32,118,101,114,105,102,105,101, - 100,32,116,111,32,98,101,32,97,108,112,104,97,110,117,109, - 101,114,105,99,32,40,101,108,115,101,32,86,97,108,117,101, - 69,114,114,111,114,10,32,32,32,32,105,115,32,114,97,105, - 115,101,100,41,46,10,10,32,32,32,32,84,104,101,32,100, - 101,98,117,103,95,111,118,101,114,114,105,100,101,32,112,97, - 114,97,109,101,116,101,114,32,105,115,32,100,101,112,114,101, - 99,97,116,101,100,46,32,73,102,32,100,101,98,117,103,95, - 111,118,101,114,114,105,100,101,32,105,115,32,110,111,116,32, - 78,111,110,101,44,10,32,32,32,32,97,32,84,114,117,101, - 32,118,97,108,117,101,32,105,115,32,116,104,101,32,115,97, - 109,101,32,97,115,32,115,101,116,116,105,110,103,32,39,111, - 112,116,105,109,105,122,97,116,105,111,110,39,32,116,111,32, - 116,104,101,32,101,109,112,116,121,32,115,116,114,105,110,103, - 10,32,32,32,32,119,104,105,108,101,32,97,32,70,97,108, - 115,101,32,118,97,108,117,101,32,105,115,32,101,113,117,105, - 118,97,108,101,110,116,32,116,111,32,115,101,116,116,105,110, - 103,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39, - 32,116,111,32,39,49,39,46,10,10,32,32,32,32,73,102, - 32,115,121,115,46,105,109,112,108,101,109,101,110,116,97,116, - 105,111,110,46,99,97,99,104,101,95,116,97,103,32,105,115, - 32,78,111,110,101,32,116,104,101,110,32,78,111,116,73,109, - 112,108,101,109,101,110,116,101,100,69,114,114,111,114,32,105, - 115,32,114,97,105,115,101,100,46,10,10,32,32,32,32,78, - 122,70,116,104,101,32,100,101,98,117,103,95,111,118,101,114, - 114,105,100,101,32,112,97,114,97,109,101,116,101,114,32,105, - 115,32,100,101,112,114,101,99,97,116,101,100,59,32,117,115, - 101,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39, - 32,105,110,115,116,101,97,100,122,50,100,101,98,117,103,95, - 111,118,101,114,114,105,100,101,32,111,114,32,111,112,116,105, - 109,105,122,97,116,105,111,110,32,109,117,115,116,32,98,101, - 32,115,101,116,32,116,111,32,78,111,110,101,114,14,0,0, - 0,114,4,0,0,0,218,1,46,250,36,115,121,115,46,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,46,99,97, - 99,104,101,95,116,97,103,32,105,115,32,78,111,110,101,114, - 0,0,0,0,122,24,123,33,114,125,32,105,115,32,110,111, - 116,32,97,108,112,104,97,110,117,109,101,114,105,99,122,7, - 123,125,46,123,125,123,125,114,16,0,0,0,114,45,0,0, - 0,41,28,218,9,95,119,97,114,110,105,110,103,115,218,4, - 119,97,114,110,218,18,68,101,112,114,101,99,97,116,105,111, - 110,87,97,114,110,105,110,103,218,9,84,121,112,101,69,114, - 114,111,114,114,24,0,0,0,218,6,102,115,112,97,116,104, - 114,74,0,0,0,218,10,114,112,97,114,116,105,116,105,111, - 110,114,21,0,0,0,218,14,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,218,9,99,97,99,104,101,95,116,97, - 103,218,19,78,111,116,73,109,112,108,101,109,101,110,116,101, - 100,69,114,114,111,114,114,62,0,0,0,114,22,0,0,0, - 218,8,111,112,116,105,109,105,122,101,218,3,115,116,114,218, - 7,105,115,97,108,110,117,109,218,10,86,97,108,117,101,69, - 114,114,111,114,114,88,0,0,0,218,4,95,79,80,84,218, - 17,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88, - 69,83,218,14,112,121,99,97,99,104,101,95,112,114,101,102, - 105,120,114,85,0,0,0,114,67,0,0,0,114,81,0,0, - 0,114,50,0,0,0,218,6,108,115,116,114,105,112,218,8, - 95,80,89,67,65,67,72,69,41,12,114,65,0,0,0,90, - 14,100,101,98,117,103,95,111,118,101,114,114,105,100,101,114, - 95,0,0,0,218,7,109,101,115,115,97,103,101,218,4,104, - 101,97,100,114,66,0,0,0,90,4,98,97,115,101,114,9, - 0,0,0,218,4,114,101,115,116,90,3,116,97,103,90,15, - 97,108,109,111,115,116,95,102,105,108,101,110,97,109,101,218, - 8,102,105,108,101,110,97,109,101,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,17,99,97,99,104,101,95, - 102,114,111,109,95,115,111,117,114,99,101,105,1,0,0,115, - 72,0,0,0,0,18,8,1,6,1,2,255,4,2,8,1, + 0,0,0,67,0,0,0,115,10,0,0,0,116,0,124,0, + 100,1,131,2,83,0,41,2,122,31,82,101,112,108,97,99, + 101,109,101,110,116,32,102,111,114,32,111,115,46,112,97,116, + 104,46,105,115,102,105,108,101,46,105,0,128,0,0,41,1, + 114,79,0,0,0,114,71,0,0,0,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,218,12,95,112,97,116,104, + 95,105,115,102,105,108,101,159,0,0,0,243,2,0,0,0, + 10,2,114,80,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, + 115,22,0,0,0,124,0,115,6,116,0,160,1,161,0,125, + 0,116,2,124,0,100,1,131,2,83,0,41,2,122,30,82, + 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, + 115,46,112,97,116,104,46,105,115,100,105,114,46,105,0,64, + 0,0,41,3,114,18,0,0,0,218,6,103,101,116,99,119, + 100,114,79,0,0,0,114,71,0,0,0,114,7,0,0,0, + 114,7,0,0,0,114,8,0,0,0,218,11,95,112,97,116, + 104,95,105,115,100,105,114,164,0,0,0,115,6,0,0,0, + 4,2,8,1,10,1,114,83,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, + 67,0,0,0,115,62,0,0,0,124,0,115,4,100,1,83, + 0,116,0,160,1,124,0,161,1,100,2,25,0,160,2,100, + 3,100,4,161,2,125,1,116,3,124,1,131,1,100,5,107, + 4,111,30,124,1,160,4,100,6,161,1,112,30,124,1,160, + 5,100,4,161,1,83,0,41,7,250,30,82,101,112,108,97, + 99,101,109,101,110,116,32,102,111,114,32,111,115,46,112,97, + 116,104,46,105,115,97,98,115,46,70,114,0,0,0,0,114, + 2,0,0,0,114,1,0,0,0,114,3,0,0,0,122,2, + 92,92,41,6,114,18,0,0,0,114,56,0,0,0,218,7, + 114,101,112,108,97,99,101,114,4,0,0,0,114,26,0,0, + 0,114,58,0,0,0,41,2,114,65,0,0,0,114,64,0, + 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, + 0,218,11,95,112,97,116,104,95,105,115,97,98,115,172,0, + 0,0,115,8,0,0,0,4,2,4,1,22,1,32,1,114, + 86,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,67,0,0,0,115,10,0, + 0,0,124,0,160,0,116,1,161,1,83,0,41,1,114,84, + 0,0,0,41,2,114,26,0,0,0,114,50,0,0,0,114, + 71,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,114,86,0,0,0,180,0,0,0,114,81,0,0, + 0,233,182,1,0,0,99,3,0,0,0,0,0,0,0,0, + 0,0,0,6,0,0,0,11,0,0,0,67,0,0,0,115, + 170,0,0,0,100,1,160,0,124,0,116,1,124,0,131,1, + 161,2,125,3,116,2,160,3,124,3,116,2,106,4,116,2, + 106,5,66,0,116,2,106,6,66,0,124,2,100,2,64,0, + 161,3,125,4,122,36,116,7,160,8,124,4,100,3,161,2, + 143,13,125,5,124,5,160,9,124,1,161,1,1,0,87,0, + 100,4,4,0,4,0,131,3,1,0,110,8,49,0,115,47, + 119,1,1,0,1,0,1,0,89,0,1,0,116,2,160,10, + 124,3,124,0,161,2,1,0,87,0,100,4,83,0,4,0, + 116,11,121,84,1,0,1,0,1,0,122,7,116,2,160,12, + 124,3,161,1,1,0,87,0,130,0,4,0,116,11,121,83, + 1,0,1,0,1,0,89,0,130,0,119,0,119,0,41,5, + 122,162,66,101,115,116,45,101,102,102,111,114,116,32,102,117, + 110,99,116,105,111,110,32,116,111,32,119,114,105,116,101,32, + 100,97,116,97,32,116,111,32,97,32,112,97,116,104,32,97, + 116,111,109,105,99,97,108,108,121,46,10,32,32,32,32,66, + 101,32,112,114,101,112,97,114,101,100,32,116,111,32,104,97, + 110,100,108,101,32,97,32,70,105,108,101,69,120,105,115,116, + 115,69,114,114,111,114,32,105,102,32,99,111,110,99,117,114, + 114,101,110,116,32,119,114,105,116,105,110,103,32,111,102,32, + 116,104,101,10,32,32,32,32,116,101,109,112,111,114,97,114, + 121,32,102,105,108,101,32,105,115,32,97,116,116,101,109,112, + 116,101,100,46,250,5,123,125,46,123,125,114,87,0,0,0, + 90,2,119,98,78,41,13,218,6,102,111,114,109,97,116,218, + 2,105,100,114,18,0,0,0,90,4,111,112,101,110,90,6, + 79,95,69,88,67,76,90,7,79,95,67,82,69,65,84,90, + 8,79,95,87,82,79,78,76,89,218,3,95,105,111,218,6, + 70,105,108,101,73,79,218,5,119,114,105,116,101,114,85,0, + 0,0,114,76,0,0,0,90,6,117,110,108,105,110,107,41, + 6,114,65,0,0,0,114,41,0,0,0,114,78,0,0,0, + 90,8,112,97,116,104,95,116,109,112,90,2,102,100,218,4, + 102,105,108,101,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,13,95,119,114,105,116,101,95,97,116,111,109, + 105,99,185,0,0,0,115,36,0,0,0,16,5,6,1,22, + 1,4,255,2,2,14,3,12,1,28,255,18,2,12,1,2, + 1,12,1,2,3,12,254,2,1,2,1,2,254,2,253,114, + 95,0,0,0,105,111,13,0,0,114,44,0,0,0,114,32, + 0,0,0,115,2,0,0,0,13,10,90,11,95,95,112,121, + 99,97,99,104,101,95,95,122,4,111,112,116,45,122,3,46, + 112,121,122,4,46,112,121,119,122,4,46,112,121,99,41,1, + 218,12,111,112,116,105,109,105,122,97,116,105,111,110,99,2, + 0,0,0,0,0,0,0,1,0,0,0,12,0,0,0,5, + 0,0,0,67,0,0,0,115,80,1,0,0,124,1,100,1, + 117,1,114,26,116,0,160,1,100,2,116,2,161,2,1,0, + 124,2,100,1,117,1,114,20,100,3,125,3,116,3,124,3, + 131,1,130,1,124,1,114,24,100,4,110,1,100,5,125,2, + 116,4,160,5,124,0,161,1,125,0,116,6,124,0,131,1, + 92,2,125,4,125,5,124,5,160,7,100,6,161,1,92,3, + 125,6,125,7,125,8,116,8,106,9,106,10,125,9,124,9, + 100,1,117,0,114,57,116,11,100,7,131,1,130,1,100,4, + 160,12,124,6,114,63,124,6,110,1,124,8,124,7,124,9, + 103,3,161,1,125,10,124,2,100,1,117,0,114,86,116,8, + 106,13,106,14,100,8,107,2,114,82,100,4,125,2,110,4, + 116,8,106,13,106,14,125,2,116,15,124,2,131,1,125,2, + 124,2,100,4,107,3,114,112,124,2,160,16,161,0,115,105, + 116,17,100,9,160,18,124,2,161,1,131,1,130,1,100,10, + 160,18,124,10,116,19,124,2,161,3,125,10,124,10,116,20, + 100,8,25,0,23,0,125,11,116,8,106,21,100,1,117,1, + 114,162,116,22,124,4,131,1,115,134,116,23,116,4,160,24, + 161,0,124,4,131,2,125,4,124,4,100,5,25,0,100,11, + 107,2,114,152,124,4,100,8,25,0,116,25,118,1,114,152, + 124,4,100,12,100,1,133,2,25,0,125,4,116,23,116,8, + 106,21,124,4,160,26,116,25,161,1,124,11,131,3,83,0, + 116,23,124,4,116,27,124,11,131,3,83,0,41,13,97,254, + 2,0,0,71,105,118,101,110,32,116,104,101,32,112,97,116, + 104,32,116,111,32,97,32,46,112,121,32,102,105,108,101,44, + 32,114,101,116,117,114,110,32,116,104,101,32,112,97,116,104, + 32,116,111,32,105,116,115,32,46,112,121,99,32,102,105,108, + 101,46,10,10,32,32,32,32,84,104,101,32,46,112,121,32, + 102,105,108,101,32,100,111,101,115,32,110,111,116,32,110,101, + 101,100,32,116,111,32,101,120,105,115,116,59,32,116,104,105, + 115,32,115,105,109,112,108,121,32,114,101,116,117,114,110,115, + 32,116,104,101,32,112,97,116,104,32,116,111,32,116,104,101, + 10,32,32,32,32,46,112,121,99,32,102,105,108,101,32,99, + 97,108,99,117,108,97,116,101,100,32,97,115,32,105,102,32, + 116,104,101,32,46,112,121,32,102,105,108,101,32,119,101,114, + 101,32,105,109,112,111,114,116,101,100,46,10,10,32,32,32, + 32,84,104,101,32,39,111,112,116,105,109,105,122,97,116,105, + 111,110,39,32,112,97,114,97,109,101,116,101,114,32,99,111, + 110,116,114,111,108,115,32,116,104,101,32,112,114,101,115,117, + 109,101,100,32,111,112,116,105,109,105,122,97,116,105,111,110, + 32,108,101,118,101,108,32,111,102,10,32,32,32,32,116,104, + 101,32,98,121,116,101,99,111,100,101,32,102,105,108,101,46, + 32,73,102,32,39,111,112,116,105,109,105,122,97,116,105,111, + 110,39,32,105,115,32,110,111,116,32,78,111,110,101,44,32, + 116,104,101,32,115,116,114,105,110,103,32,114,101,112,114,101, + 115,101,110,116,97,116,105,111,110,10,32,32,32,32,111,102, + 32,116,104,101,32,97,114,103,117,109,101,110,116,32,105,115, + 32,116,97,107,101,110,32,97,110,100,32,118,101,114,105,102, + 105,101,100,32,116,111,32,98,101,32,97,108,112,104,97,110, + 117,109,101,114,105,99,32,40,101,108,115,101,32,86,97,108, + 117,101,69,114,114,111,114,10,32,32,32,32,105,115,32,114, + 97,105,115,101,100,41,46,10,10,32,32,32,32,84,104,101, + 32,100,101,98,117,103,95,111,118,101,114,114,105,100,101,32, + 112,97,114,97,109,101,116,101,114,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,46,32,73,102,32,100,101,98,117, + 103,95,111,118,101,114,114,105,100,101,32,105,115,32,110,111, + 116,32,78,111,110,101,44,10,32,32,32,32,97,32,84,114, + 117,101,32,118,97,108,117,101,32,105,115,32,116,104,101,32, + 115,97,109,101,32,97,115,32,115,101,116,116,105,110,103,32, + 39,111,112,116,105,109,105,122,97,116,105,111,110,39,32,116, + 111,32,116,104,101,32,101,109,112,116,121,32,115,116,114,105, + 110,103,10,32,32,32,32,119,104,105,108,101,32,97,32,70, + 97,108,115,101,32,118,97,108,117,101,32,105,115,32,101,113, + 117,105,118,97,108,101,110,116,32,116,111,32,115,101,116,116, + 105,110,103,32,39,111,112,116,105,109,105,122,97,116,105,111, + 110,39,32,116,111,32,39,49,39,46,10,10,32,32,32,32, + 73,102,32,115,121,115,46,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,32, + 105,115,32,78,111,110,101,32,116,104,101,110,32,78,111,116, + 73,109,112,108,101,109,101,110,116,101,100,69,114,114,111,114, + 32,105,115,32,114,97,105,115,101,100,46,10,10,32,32,32, + 32,78,122,70,116,104,101,32,100,101,98,117,103,95,111,118, + 101,114,114,105,100,101,32,112,97,114,97,109,101,116,101,114, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,59,32, + 117,115,101,32,39,111,112,116,105,109,105,122,97,116,105,111, + 110,39,32,105,110,115,116,101,97,100,122,50,100,101,98,117, + 103,95,111,118,101,114,114,105,100,101,32,111,114,32,111,112, + 116,105,109,105,122,97,116,105,111,110,32,109,117,115,116,32, + 98,101,32,115,101,116,32,116,111,32,78,111,110,101,114,10, + 0,0,0,114,3,0,0,0,218,1,46,250,36,115,121,115, + 46,105,109,112,108,101,109,101,110,116,97,116,105,111,110,46, + 99,97,99,104,101,95,116,97,103,32,105,115,32,78,111,110, + 101,114,0,0,0,0,122,24,123,33,114,125,32,105,115,32, + 110,111,116,32,97,108,112,104,97,110,117,109,101,114,105,99, + 122,7,123,125,46,123,125,123,125,114,11,0,0,0,114,44, + 0,0,0,41,28,218,9,95,119,97,114,110,105,110,103,115, + 218,4,119,97,114,110,218,18,68,101,112,114,101,99,97,116, + 105,111,110,87,97,114,110,105,110,103,218,9,84,121,112,101, + 69,114,114,111,114,114,18,0,0,0,218,6,102,115,112,97, + 116,104,114,74,0,0,0,218,10,114,112,97,114,116,105,116, + 105,111,110,114,15,0,0,0,218,14,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,218,9,99,97,99,104,101,95, + 116,97,103,218,19,78,111,116,73,109,112,108,101,109,101,110, + 116,101,100,69,114,114,111,114,114,62,0,0,0,114,16,0, + 0,0,218,8,111,112,116,105,109,105,122,101,218,3,115,116, + 114,218,7,105,115,97,108,110,117,109,218,10,86,97,108,117, + 101,69,114,114,111,114,114,89,0,0,0,218,4,95,79,80, + 84,218,17,66,89,84,69,67,79,68,69,95,83,85,70,70, + 73,88,69,83,218,14,112,121,99,97,99,104,101,95,112,114, + 101,102,105,120,114,86,0,0,0,114,67,0,0,0,114,82, + 0,0,0,114,50,0,0,0,218,6,108,115,116,114,105,112, + 218,8,95,80,89,67,65,67,72,69,41,12,114,65,0,0, + 0,90,14,100,101,98,117,103,95,111,118,101,114,114,105,100, + 101,114,96,0,0,0,218,7,109,101,115,115,97,103,101,218, + 4,104,101,97,100,114,66,0,0,0,90,4,98,97,115,101, + 114,6,0,0,0,218,4,114,101,115,116,90,3,116,97,103, + 90,15,97,108,109,111,115,116,95,102,105,108,101,110,97,109, + 101,218,8,102,105,108,101,110,97,109,101,114,7,0,0,0, + 114,7,0,0,0,114,8,0,0,0,218,17,99,97,99,104, + 101,95,102,114,111,109,95,115,111,117,114,99,101,124,1,0, + 0,115,72,0,0,0,8,18,6,1,2,1,4,255,8,2, 4,1,8,1,12,1,10,1,12,1,16,1,8,1,8,1, - 8,1,24,1,8,1,12,1,6,2,8,1,8,1,8,1, - 8,1,14,1,14,1,12,1,12,9,10,1,14,5,28,1, - 12,4,2,1,4,1,8,1,2,253,4,5,114,120,0,0, - 0,99,1,0,0,0,0,0,0,0,0,0,0,0,10,0, - 0,0,5,0,0,0,67,0,0,0,115,46,1,0,0,116, - 0,106,1,106,2,100,1,117,0,114,20,116,3,100,2,131, - 1,130,1,116,4,160,5,124,0,161,1,125,0,116,6,124, - 0,131,1,92,2,125,1,125,2,100,3,125,3,116,0,106, - 7,100,1,117,1,114,102,116,0,106,7,160,8,116,9,161, - 1,125,4,124,1,160,10,124,4,116,11,23,0,161,1,114, - 102,124,1,116,12,124,4,131,1,100,1,133,2,25,0,125, - 1,100,4,125,3,124,3,115,144,116,6,124,1,131,1,92, - 2,125,1,125,5,124,5,116,13,107,3,114,144,116,14,116, - 13,155,0,100,5,124,0,155,2,157,3,131,1,130,1,124, - 2,160,15,100,6,161,1,125,6,124,6,100,7,118,1,114, - 178,116,14,100,8,124,2,155,2,157,2,131,1,130,1,110, - 92,124,6,100,9,107,2,144,1,114,14,124,2,160,16,100, - 6,100,10,161,2,100,11,25,0,125,7,124,7,160,10,116, - 17,161,1,115,228,116,14,100,12,116,17,155,2,157,2,131, - 1,130,1,124,7,116,12,116,17,131,1,100,1,133,2,25, - 0,125,8,124,8,160,18,161,0,144,1,115,14,116,14,100, - 13,124,7,155,2,100,14,157,3,131,1,130,1,124,2,160, - 19,100,6,161,1,100,15,25,0,125,9,116,20,124,1,124, - 9,116,21,100,15,25,0,23,0,131,2,83,0,41,16,97, - 110,1,0,0,71,105,118,101,110,32,116,104,101,32,112,97, - 116,104,32,116,111,32,97,32,46,112,121,99,46,32,102,105, - 108,101,44,32,114,101,116,117,114,110,32,116,104,101,32,112, - 97,116,104,32,116,111,32,105,116,115,32,46,112,121,32,102, - 105,108,101,46,10,10,32,32,32,32,84,104,101,32,46,112, - 121,99,32,102,105,108,101,32,100,111,101,115,32,110,111,116, - 32,110,101,101,100,32,116,111,32,101,120,105,115,116,59,32, - 116,104,105,115,32,115,105,109,112,108,121,32,114,101,116,117, - 114,110,115,32,116,104,101,32,112,97,116,104,32,116,111,10, - 32,32,32,32,116,104,101,32,46,112,121,32,102,105,108,101, - 32,99,97,108,99,117,108,97,116,101,100,32,116,111,32,99, - 111,114,114,101,115,112,111,110,100,32,116,111,32,116,104,101, - 32,46,112,121,99,32,102,105,108,101,46,32,32,73,102,32, - 112,97,116,104,32,100,111,101,115,10,32,32,32,32,110,111, - 116,32,99,111,110,102,111,114,109,32,116,111,32,80,69,80, - 32,51,49,52,55,47,52,56,56,32,102,111,114,109,97,116, - 44,32,86,97,108,117,101,69,114,114,111,114,32,119,105,108, - 108,32,98,101,32,114,97,105,115,101,100,46,32,73,102,10, - 32,32,32,32,115,121,115,46,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,46,99,97,99,104,101,95,116,97,103, - 32,105,115,32,78,111,110,101,32,116,104,101,110,32,78,111, - 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111, - 114,32,105,115,32,114,97,105,115,101,100,46,10,10,32,32, - 32,32,78,114,97,0,0,0,70,84,122,31,32,110,111,116, - 32,98,111,116,116,111,109,45,108,101,118,101,108,32,100,105, - 114,101,99,116,111,114,121,32,105,110,32,114,96,0,0,0, - 62,2,0,0,0,114,45,0,0,0,233,3,0,0,0,122, - 29,101,120,112,101,99,116,101,100,32,111,110,108,121,32,50, - 32,111,114,32,51,32,100,111,116,115,32,105,110,32,114,121, - 0,0,0,114,45,0,0,0,233,254,255,255,255,122,53,111, - 112,116,105,109,105,122,97,116,105,111,110,32,112,111,114,116, - 105,111,110,32,111,102,32,102,105,108,101,110,97,109,101,32, - 100,111,101,115,32,110,111,116,32,115,116,97,114,116,32,119, - 105,116,104,32,122,19,111,112,116,105,109,105,122,97,116,105, - 111,110,32,108,101,118,101,108,32,122,29,32,105,115,32,110, - 111,116,32,97,110,32,97,108,112,104,97,110,117,109,101,114, - 105,99,32,118,97,108,117,101,114,0,0,0,0,41,22,114, - 21,0,0,0,114,104,0,0,0,114,105,0,0,0,114,106, - 0,0,0,114,24,0,0,0,114,102,0,0,0,114,74,0, - 0,0,114,113,0,0,0,114,49,0,0,0,114,50,0,0, - 0,114,29,0,0,0,114,59,0,0,0,114,6,0,0,0, - 114,115,0,0,0,114,110,0,0,0,218,5,99,111,117,110, - 116,218,6,114,115,112,108,105,116,114,111,0,0,0,114,109, - 0,0,0,218,9,112,97,114,116,105,116,105,111,110,114,67, - 0,0,0,218,15,83,79,85,82,67,69,95,83,85,70,70, - 73,88,69,83,41,10,114,65,0,0,0,114,117,0,0,0, - 90,16,112,121,99,97,99,104,101,95,102,105,108,101,110,97, - 109,101,90,23,102,111,117,110,100,95,105,110,95,112,121,99, - 97,99,104,101,95,112,114,101,102,105,120,90,13,115,116,114, - 105,112,112,101,100,95,112,97,116,104,90,7,112,121,99,97, - 99,104,101,90,9,100,111,116,95,99,111,117,110,116,114,95, - 0,0,0,90,9,111,112,116,95,108,101,118,101,108,90,13, - 98,97,115,101,95,102,105,108,101,110,97,109,101,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,17,115,111, - 117,114,99,101,95,102,114,111,109,95,99,97,99,104,101,176, - 1,0,0,115,60,0,0,0,0,9,12,1,8,1,10,1, - 12,1,4,1,10,1,12,1,14,1,16,1,4,1,4,1, - 12,1,8,1,8,1,2,255,8,2,10,1,8,1,16,1, - 10,1,16,1,10,1,4,1,2,255,8,2,16,1,10,1, - 16,2,14,1,114,127,0,0,0,99,1,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,9,0,0,0,67,0, - 0,0,115,124,0,0,0,116,0,124,0,131,1,100,1,107, - 2,114,16,100,2,83,0,124,0,160,1,100,3,161,1,92, - 3,125,1,125,2,125,3,124,1,114,56,124,3,160,2,161, - 0,100,4,100,5,133,2,25,0,100,6,107,3,114,60,124, - 0,83,0,122,12,116,3,124,0,131,1,125,4,87,0,110, - 34,4,0,116,4,116,5,102,2,121,106,1,0,1,0,1, - 0,124,0,100,2,100,5,133,2,25,0,125,4,89,0,110, - 2,48,0,116,6,124,4,131,1,114,120,124,4,83,0,124, - 0,83,0,41,7,122,188,67,111,110,118,101,114,116,32,97, - 32,98,121,116,101,99,111,100,101,32,102,105,108,101,32,112, - 97,116,104,32,116,111,32,97,32,115,111,117,114,99,101,32, - 112,97,116,104,32,40,105,102,32,112,111,115,115,105,98,108, - 101,41,46,10,10,32,32,32,32,84,104,105,115,32,102,117, - 110,99,116,105,111,110,32,101,120,105,115,116,115,32,112,117, - 114,101,108,121,32,102,111,114,32,98,97,99,107,119,97,114, - 100,115,45,99,111,109,112,97,116,105,98,105,108,105,116,121, - 32,102,111,114,10,32,32,32,32,80,121,73,109,112,111,114, - 116,95,69,120,101,99,67,111,100,101,77,111,100,117,108,101, - 87,105,116,104,70,105,108,101,110,97,109,101,115,40,41,32, - 105,110,32,116,104,101,32,67,32,65,80,73,46,10,10,32, - 32,32,32,114,0,0,0,0,78,114,96,0,0,0,233,253, - 255,255,255,233,255,255,255,255,90,2,112,121,41,7,114,6, - 0,0,0,114,103,0,0,0,218,5,108,111,119,101,114,114, - 127,0,0,0,114,106,0,0,0,114,110,0,0,0,114,80, - 0,0,0,41,5,218,13,98,121,116,101,99,111,100,101,95, - 112,97,116,104,114,118,0,0,0,218,1,95,90,9,101,120, - 116,101,110,115,105,111,110,218,11,115,111,117,114,99,101,95, - 112,97,116,104,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,15,95,103,101,116,95,115,111,117,114,99,101, - 102,105,108,101,216,1,0,0,115,20,0,0,0,0,7,12, - 1,4,1,16,1,24,1,4,1,2,1,12,1,16,1,18, - 1,114,134,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,8,0,0,0,67,0,0,0,115, - 72,0,0,0,124,0,160,0,116,1,116,2,131,1,161,1, - 114,46,122,10,116,3,124,0,131,1,87,0,83,0,4,0, - 116,4,121,42,1,0,1,0,1,0,89,0,113,68,48,0, - 110,22,124,0,160,0,116,1,116,5,131,1,161,1,114,64, - 124,0,83,0,100,0,83,0,100,0,83,0,114,69,0,0, - 0,41,6,114,58,0,0,0,218,5,116,117,112,108,101,114, - 126,0,0,0,114,120,0,0,0,114,106,0,0,0,114,112, - 0,0,0,41,1,114,119,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,11,95,103,101,116,95, - 99,97,99,104,101,100,235,1,0,0,115,16,0,0,0,0, - 1,14,1,2,1,10,1,12,1,8,1,14,1,4,2,114, - 136,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,8,0,0,0,67,0,0,0,115,50,0, - 0,0,122,14,116,0,124,0,131,1,106,1,125,1,87,0, - 110,22,4,0,116,2,121,36,1,0,1,0,1,0,100,1, - 125,1,89,0,110,2,48,0,124,1,100,2,79,0,125,1, - 124,1,83,0,41,3,122,51,67,97,108,99,117,108,97,116, - 101,32,116,104,101,32,109,111,100,101,32,112,101,114,109,105, - 115,115,105,111,110,115,32,102,111,114,32,97,32,98,121,116, - 101,99,111,100,101,32,102,105,108,101,46,114,86,0,0,0, - 233,128,0,0,0,41,3,114,75,0,0,0,114,77,0,0, - 0,114,76,0,0,0,41,2,114,65,0,0,0,114,78,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,10,95,99,97,108,99,95,109,111,100,101,247,1,0, - 0,115,12,0,0,0,0,2,2,1,14,1,12,1,10,3, - 8,1,114,138,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,8,0,0,0,3,0,0,0, - 115,66,0,0,0,100,6,135,0,102,1,100,2,100,3,132, - 9,125,1,122,10,116,0,106,1,125,2,87,0,110,26,4, - 0,116,2,121,50,1,0,1,0,1,0,100,4,100,5,132, - 0,125,2,89,0,110,2,48,0,124,2,124,1,136,0,131, + 8,1,24,1,8,1,12,1,6,1,8,2,8,1,8,1, + 8,1,14,1,14,1,12,1,10,1,8,9,14,1,24,5, + 12,1,2,4,4,1,8,1,2,1,4,253,12,5,114,121, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 10,0,0,0,5,0,0,0,67,0,0,0,115,40,1,0, + 0,116,0,106,1,106,2,100,1,117,0,114,10,116,3,100, + 2,131,1,130,1,116,4,160,5,124,0,161,1,125,0,116, + 6,124,0,131,1,92,2,125,1,125,2,100,3,125,3,116, + 0,106,7,100,1,117,1,114,51,116,0,106,7,160,8,116, + 9,161,1,125,4,124,1,160,10,124,4,116,11,23,0,161, + 1,114,51,124,1,116,12,124,4,131,1,100,1,133,2,25, + 0,125,1,100,4,125,3,124,3,115,72,116,6,124,1,131, + 1,92,2,125,1,125,5,124,5,116,13,107,3,114,72,116, + 14,116,13,155,0,100,5,124,0,155,2,157,3,131,1,130, + 1,124,2,160,15,100,6,161,1,125,6,124,6,100,7,118, + 1,114,88,116,14,100,8,124,2,155,2,157,2,131,1,130, + 1,124,6,100,9,107,2,114,132,124,2,160,16,100,6,100, + 10,161,2,100,11,25,0,125,7,124,7,160,10,116,17,161, + 1,115,112,116,14,100,12,116,17,155,2,157,2,131,1,130, + 1,124,7,116,12,116,17,131,1,100,1,133,2,25,0,125, + 8,124,8,160,18,161,0,115,132,116,14,100,13,124,7,155, + 2,100,14,157,3,131,1,130,1,124,2,160,19,100,6,161, + 1,100,15,25,0,125,9,116,20,124,1,124,9,116,21,100, + 15,25,0,23,0,131,2,83,0,41,16,97,110,1,0,0, + 71,105,118,101,110,32,116,104,101,32,112,97,116,104,32,116, + 111,32,97,32,46,112,121,99,46,32,102,105,108,101,44,32, + 114,101,116,117,114,110,32,116,104,101,32,112,97,116,104,32, + 116,111,32,105,116,115,32,46,112,121,32,102,105,108,101,46, + 10,10,32,32,32,32,84,104,101,32,46,112,121,99,32,102, + 105,108,101,32,100,111,101,115,32,110,111,116,32,110,101,101, + 100,32,116,111,32,101,120,105,115,116,59,32,116,104,105,115, + 32,115,105,109,112,108,121,32,114,101,116,117,114,110,115,32, + 116,104,101,32,112,97,116,104,32,116,111,10,32,32,32,32, + 116,104,101,32,46,112,121,32,102,105,108,101,32,99,97,108, + 99,117,108,97,116,101,100,32,116,111,32,99,111,114,114,101, + 115,112,111,110,100,32,116,111,32,116,104,101,32,46,112,121, + 99,32,102,105,108,101,46,32,32,73,102,32,112,97,116,104, + 32,100,111,101,115,10,32,32,32,32,110,111,116,32,99,111, + 110,102,111,114,109,32,116,111,32,80,69,80,32,51,49,52, + 55,47,52,56,56,32,102,111,114,109,97,116,44,32,86,97, + 108,117,101,69,114,114,111,114,32,119,105,108,108,32,98,101, + 32,114,97,105,115,101,100,46,32,73,102,10,32,32,32,32, + 115,121,115,46,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,46,99,97,99,104,101,95,116,97,103,32,105,115,32, + 78,111,110,101,32,116,104,101,110,32,78,111,116,73,109,112, + 108,101,109,101,110,116,101,100,69,114,114,111,114,32,105,115, + 32,114,97,105,115,101,100,46,10,10,32,32,32,32,78,114, + 98,0,0,0,70,84,122,31,32,110,111,116,32,98,111,116, + 116,111,109,45,108,101,118,101,108,32,100,105,114,101,99,116, + 111,114,121,32,105,110,32,114,97,0,0,0,62,2,0,0, + 0,114,44,0,0,0,233,3,0,0,0,122,29,101,120,112, + 101,99,116,101,100,32,111,110,108,121,32,50,32,111,114,32, + 51,32,100,111,116,115,32,105,110,32,114,122,0,0,0,114, + 44,0,0,0,233,254,255,255,255,122,53,111,112,116,105,109, + 105,122,97,116,105,111,110,32,112,111,114,116,105,111,110,32, + 111,102,32,102,105,108,101,110,97,109,101,32,100,111,101,115, + 32,110,111,116,32,115,116,97,114,116,32,119,105,116,104,32, + 122,19,111,112,116,105,109,105,122,97,116,105,111,110,32,108, + 101,118,101,108,32,122,29,32,105,115,32,110,111,116,32,97, + 110,32,97,108,112,104,97,110,117,109,101,114,105,99,32,118, + 97,108,117,101,114,0,0,0,0,41,22,114,15,0,0,0, + 114,105,0,0,0,114,106,0,0,0,114,107,0,0,0,114, + 18,0,0,0,114,103,0,0,0,114,74,0,0,0,114,114, + 0,0,0,114,49,0,0,0,114,50,0,0,0,114,26,0, + 0,0,114,59,0,0,0,114,4,0,0,0,114,116,0,0, + 0,114,111,0,0,0,218,5,99,111,117,110,116,218,6,114, + 115,112,108,105,116,114,112,0,0,0,114,110,0,0,0,218, + 9,112,97,114,116,105,116,105,111,110,114,67,0,0,0,218, + 15,83,79,85,82,67,69,95,83,85,70,70,73,88,69,83, + 41,10,114,65,0,0,0,114,118,0,0,0,90,16,112,121, + 99,97,99,104,101,95,102,105,108,101,110,97,109,101,90,23, + 102,111,117,110,100,95,105,110,95,112,121,99,97,99,104,101, + 95,112,114,101,102,105,120,90,13,115,116,114,105,112,112,101, + 100,95,112,97,116,104,90,7,112,121,99,97,99,104,101,90, + 9,100,111,116,95,99,111,117,110,116,114,96,0,0,0,90, + 9,111,112,116,95,108,101,118,101,108,90,13,98,97,115,101, + 95,102,105,108,101,110,97,109,101,114,7,0,0,0,114,7, + 0,0,0,114,8,0,0,0,218,17,115,111,117,114,99,101, + 95,102,114,111,109,95,99,97,99,104,101,195,1,0,0,115, + 60,0,0,0,12,9,8,1,10,1,12,1,4,1,10,1, + 12,1,14,1,16,1,4,1,4,1,12,1,8,1,8,1, + 2,1,8,255,10,2,8,1,14,1,8,1,16,1,10,1, + 4,1,2,1,8,255,16,2,8,1,16,1,14,2,18,1, + 114,128,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,5,0,0,0,9,0,0,0,67,0,0,0,115,124, + 0,0,0,116,0,124,0,131,1,100,1,107,2,114,8,100, + 2,83,0,124,0,160,1,100,3,161,1,92,3,125,1,125, + 2,125,3,124,1,114,28,124,3,160,2,161,0,100,4,100, + 5,133,2,25,0,100,6,107,3,114,30,124,0,83,0,122, + 6,116,3,124,0,131,1,125,4,87,0,110,17,4,0,116, + 4,116,5,102,2,121,53,1,0,1,0,1,0,124,0,100, + 2,100,5,133,2,25,0,125,4,89,0,110,1,119,0,116, + 6,124,4,131,1,114,60,124,4,83,0,124,0,83,0,41, + 7,122,188,67,111,110,118,101,114,116,32,97,32,98,121,116, + 101,99,111,100,101,32,102,105,108,101,32,112,97,116,104,32, + 116,111,32,97,32,115,111,117,114,99,101,32,112,97,116,104, + 32,40,105,102,32,112,111,115,115,105,98,108,101,41,46,10, + 10,32,32,32,32,84,104,105,115,32,102,117,110,99,116,105, + 111,110,32,101,120,105,115,116,115,32,112,117,114,101,108,121, + 32,102,111,114,32,98,97,99,107,119,97,114,100,115,45,99, + 111,109,112,97,116,105,98,105,108,105,116,121,32,102,111,114, + 10,32,32,32,32,80,121,73,109,112,111,114,116,95,69,120, + 101,99,67,111,100,101,77,111,100,117,108,101,87,105,116,104, + 70,105,108,101,110,97,109,101,115,40,41,32,105,110,32,116, + 104,101,32,67,32,65,80,73,46,10,10,32,32,32,32,114, + 0,0,0,0,78,114,97,0,0,0,233,253,255,255,255,233, + 255,255,255,255,90,2,112,121,41,7,114,4,0,0,0,114, + 104,0,0,0,218,5,108,111,119,101,114,114,128,0,0,0, + 114,107,0,0,0,114,111,0,0,0,114,80,0,0,0,41, + 5,218,13,98,121,116,101,99,111,100,101,95,112,97,116,104, + 114,119,0,0,0,218,1,95,90,9,101,120,116,101,110,115, + 105,111,110,218,11,115,111,117,114,99,101,95,112,97,116,104, + 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, + 15,95,103,101,116,95,115,111,117,114,99,101,102,105,108,101, + 235,1,0,0,115,22,0,0,0,12,7,4,1,16,1,24, + 1,4,1,2,1,12,1,16,1,16,1,2,255,16,2,114, + 135,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,8,0,0,0,67,0,0,0,115,68,0, + 0,0,124,0,160,0,116,1,116,2,131,1,161,1,114,23, + 122,5,116,3,124,0,131,1,87,0,83,0,4,0,116,4, + 121,22,1,0,1,0,1,0,89,0,100,0,83,0,119,0, + 124,0,160,0,116,1,116,5,131,1,161,1,114,32,124,0, + 83,0,100,0,83,0,114,69,0,0,0,41,6,114,58,0, + 0,0,218,5,116,117,112,108,101,114,127,0,0,0,114,121, + 0,0,0,114,107,0,0,0,114,113,0,0,0,41,1,114, + 120,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,11,95,103,101,116,95,99,97,99,104,101,100, + 254,1,0,0,115,18,0,0,0,14,1,2,1,10,1,12, + 1,6,1,2,255,14,2,4,1,4,2,114,137,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,8,0,0,0,67,0,0,0,115,50,0,0,0,122,7, + 116,0,124,0,131,1,106,1,125,1,87,0,110,11,4,0, + 116,2,121,18,1,0,1,0,1,0,100,1,125,1,89,0, + 110,1,119,0,124,1,100,2,79,0,125,1,124,1,83,0, + 41,3,122,51,67,97,108,99,117,108,97,116,101,32,116,104, + 101,32,109,111,100,101,32,112,101,114,109,105,115,115,105,111, + 110,115,32,102,111,114,32,97,32,98,121,116,101,99,111,100, + 101,32,102,105,108,101,46,114,87,0,0,0,233,128,0,0, + 0,41,3,114,75,0,0,0,114,77,0,0,0,114,76,0, + 0,0,41,2,114,65,0,0,0,114,78,0,0,0,114,7, + 0,0,0,114,7,0,0,0,114,8,0,0,0,218,10,95, + 99,97,108,99,95,109,111,100,101,10,2,0,0,115,14,0, + 0,0,2,2,14,1,12,1,8,1,2,255,8,4,4,1, + 114,139,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,4,0,0,0,3,0,0,0,115,52, + 0,0,0,100,6,135,0,102,1,100,2,100,3,132,9,125, + 1,116,0,100,1,117,1,114,15,116,0,106,1,125,2,110, + 4,100,4,100,5,132,0,125,2,124,2,124,1,136,0,131, 2,1,0,124,1,83,0,41,7,122,252,68,101,99,111,114, 97,116,111,114,32,116,111,32,118,101,114,105,102,121,32,116, 104,97,116,32,116,104,101,32,109,111,100,117,108,101,32,98, @@ -641,28 +639,28 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, 46,10,10,32,32,32,32,78,99,2,0,0,0,0,0,0, 0,0,0,0,0,4,0,0,0,4,0,0,0,31,0,0, - 0,115,72,0,0,0,124,1,100,0,117,0,114,16,124,0, - 106,0,125,1,110,32,124,0,106,0,124,1,107,3,114,48, + 0,115,72,0,0,0,124,1,100,0,117,0,114,8,124,0, + 106,0,125,1,110,16,124,0,106,0,124,1,107,3,114,24, 116,1,100,1,124,0,106,0,124,1,102,2,22,0,124,1, 100,2,141,2,130,1,136,0,124,0,124,1,103,2,124,2, 162,1,82,0,105,0,124,3,164,1,142,1,83,0,41,3, 78,122,30,108,111,97,100,101,114,32,102,111,114,32,37,115, 32,99,97,110,110,111,116,32,104,97,110,100,108,101,32,37, - 115,169,1,218,4,110,97,109,101,41,2,114,140,0,0,0, + 115,169,1,218,4,110,97,109,101,41,2,114,141,0,0,0, 218,11,73,109,112,111,114,116,69,114,114,111,114,41,4,218, - 4,115,101,108,102,114,140,0,0,0,218,4,97,114,103,115, + 4,115,101,108,102,114,141,0,0,0,218,4,97,114,103,115, 218,6,107,119,97,114,103,115,169,1,218,6,109,101,116,104, - 111,100,114,10,0,0,0,114,11,0,0,0,218,19,95,99, + 111,100,114,7,0,0,0,114,8,0,0,0,218,19,95,99, 104,101,99,107,95,110,97,109,101,95,119,114,97,112,112,101, - 114,11,2,0,0,115,18,0,0,0,0,1,8,1,8,1, - 10,1,4,1,8,255,2,1,2,255,6,2,122,40,95,99, + 114,30,2,0,0,115,18,0,0,0,8,1,8,1,10,1, + 4,1,8,1,2,255,2,1,6,255,24,2,122,40,95,99, 104,101,99,107,95,110,97,109,101,46,60,108,111,99,97,108, 115,62,46,95,99,104,101,99,107,95,110,97,109,101,95,119, 114,97,112,112,101,114,99,2,0,0,0,0,0,0,0,0, 0,0,0,3,0,0,0,7,0,0,0,83,0,0,0,115, - 56,0,0,0,100,1,68,0,93,32,125,2,116,0,124,1, - 124,2,131,2,114,4,116,1,124,0,124,2,116,2,124,1, - 124,2,131,2,131,3,1,0,113,4,124,0,106,3,160,4, + 56,0,0,0,100,1,68,0,93,16,125,2,116,0,124,1, + 124,2,131,2,114,18,116,1,124,0,124,2,116,2,124,1, + 124,2,131,2,131,3,1,0,113,2,124,0,106,3,160,4, 124,1,106,3,161,1,1,0,100,0,83,0,41,2,78,41, 4,218,10,95,95,109,111,100,117,108,101,95,95,218,8,95, 95,110,97,109,101,95,95,218,12,95,95,113,117,97,108,110, @@ -670,75 +668,149 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 218,7,104,97,115,97,116,116,114,218,7,115,101,116,97,116, 116,114,218,7,103,101,116,97,116,116,114,218,8,95,95,100, 105,99,116,95,95,218,6,117,112,100,97,116,101,41,3,90, - 3,110,101,119,90,3,111,108,100,114,84,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,5,95, - 119,114,97,112,22,2,0,0,115,8,0,0,0,0,1,8, - 1,10,1,20,1,122,26,95,99,104,101,99,107,95,110,97, - 109,101,46,60,108,111,99,97,108,115,62,46,95,119,114,97, - 112,41,1,78,41,3,218,10,95,98,111,111,116,115,116,114, - 97,112,114,157,0,0,0,218,9,78,97,109,101,69,114,114, - 111,114,41,3,114,146,0,0,0,114,147,0,0,0,114,157, - 0,0,0,114,10,0,0,0,114,145,0,0,0,114,11,0, - 0,0,218,11,95,99,104,101,99,107,95,110,97,109,101,3, - 2,0,0,115,14,0,0,0,0,8,14,7,2,1,10,1, - 12,2,14,5,10,1,114,160,0,0,0,99,2,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0, - 67,0,0,0,115,60,0,0,0,124,0,160,0,124,1,161, - 1,92,2,125,2,125,3,124,2,100,1,117,0,114,56,116, - 1,124,3,131,1,114,56,100,2,125,4,116,2,160,3,124, - 4,160,4,124,3,100,3,25,0,161,1,116,5,161,2,1, - 0,124,2,83,0,41,4,122,155,84,114,121,32,116,111,32, - 102,105,110,100,32,97,32,108,111,97,100,101,114,32,102,111, - 114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, - 109,111,100,117,108,101,32,98,121,32,100,101,108,101,103,97, - 116,105,110,103,32,116,111,10,32,32,32,32,115,101,108,102, - 46,102,105,110,100,95,108,111,97,100,101,114,40,41,46,10, - 10,32,32,32,32,84,104,105,115,32,109,101,116,104,111,100, - 32,105,115,32,100,101,112,114,101,99,97,116,101,100,32,105, - 110,32,102,97,118,111,114,32,111,102,32,102,105,110,100,101, - 114,46,102,105,110,100,95,115,112,101,99,40,41,46,10,10, - 32,32,32,32,78,122,44,78,111,116,32,105,109,112,111,114, - 116,105,110,103,32,100,105,114,101,99,116,111,114,121,32,123, - 125,58,32,109,105,115,115,105,110,103,32,95,95,105,110,105, - 116,95,95,114,0,0,0,0,41,6,218,11,102,105,110,100, - 95,108,111,97,100,101,114,114,6,0,0,0,114,98,0,0, - 0,114,99,0,0,0,114,88,0,0,0,218,13,73,109,112, - 111,114,116,87,97,114,110,105,110,103,41,5,114,142,0,0, - 0,218,8,102,117,108,108,110,97,109,101,218,6,108,111,97, - 100,101,114,218,8,112,111,114,116,105,111,110,115,218,3,109, - 115,103,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,17,95,102,105,110,100,95,109,111,100,117,108,101,95, - 115,104,105,109,31,2,0,0,115,10,0,0,0,0,10,14, - 1,16,1,4,1,22,1,114,167,0,0,0,99,3,0,0, - 0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0, - 0,67,0,0,0,115,166,0,0,0,124,0,100,1,100,2, - 133,2,25,0,125,3,124,3,116,0,107,3,114,64,100,3, - 124,1,155,2,100,4,124,3,155,2,157,4,125,4,116,1, - 160,2,100,5,124,4,161,2,1,0,116,3,124,4,102,1, - 105,0,124,2,164,1,142,1,130,1,116,4,124,0,131,1, - 100,6,107,0,114,106,100,7,124,1,155,2,157,2,125,4, - 116,1,160,2,100,5,124,4,161,2,1,0,116,5,124,4, - 131,1,130,1,116,6,124,0,100,2,100,8,133,2,25,0, - 131,1,125,5,124,5,100,9,64,0,114,162,100,10,124,5, - 155,2,100,11,124,1,155,2,157,4,125,4,116,3,124,4, - 102,1,105,0,124,2,164,1,142,1,130,1,124,5,83,0, - 41,12,97,84,2,0,0,80,101,114,102,111,114,109,32,98, - 97,115,105,99,32,118,97,108,105,100,105,116,121,32,99,104, - 101,99,107,105,110,103,32,111,102,32,97,32,112,121,99,32, - 104,101,97,100,101,114,32,97,110,100,32,114,101,116,117,114, - 110,32,116,104,101,32,102,108,97,103,115,32,102,105,101,108, - 100,44,10,32,32,32,32,119,104,105,99,104,32,100,101,116, - 101,114,109,105,110,101,115,32,104,111,119,32,116,104,101,32, - 112,121,99,32,115,104,111,117,108,100,32,98,101,32,102,117, - 114,116,104,101,114,32,118,97,108,105,100,97,116,101,100,32, - 97,103,97,105,110,115,116,32,116,104,101,32,115,111,117,114, - 99,101,46,10,10,32,32,32,32,42,100,97,116,97,42,32, - 105,115,32,116,104,101,32,99,111,110,116,101,110,116,115,32, - 111,102,32,116,104,101,32,112,121,99,32,102,105,108,101,46, - 32,40,79,110,108,121,32,116,104,101,32,102,105,114,115,116, - 32,49,54,32,98,121,116,101,115,32,97,114,101,10,32,32, - 32,32,114,101,113,117,105,114,101,100,44,32,116,104,111,117, - 103,104,46,41,10,10,32,32,32,32,42,110,97,109,101,42, + 3,110,101,119,90,3,111,108,100,114,85,0,0,0,114,7, + 0,0,0,114,7,0,0,0,114,8,0,0,0,218,5,95, + 119,114,97,112,43,2,0,0,115,10,0,0,0,8,1,10, + 1,18,1,2,128,18,1,122,26,95,99,104,101,99,107,95, + 110,97,109,101,46,60,108,111,99,97,108,115,62,46,95,119, + 114,97,112,114,69,0,0,0,41,2,218,10,95,98,111,111, + 116,115,116,114,97,112,114,158,0,0,0,41,3,114,147,0, + 0,0,114,148,0,0,0,114,158,0,0,0,114,7,0,0, + 0,114,146,0,0,0,114,8,0,0,0,218,11,95,99,104, + 101,99,107,95,110,97,109,101,22,2,0,0,115,12,0,0, + 0,14,8,8,10,8,1,8,2,10,6,4,1,114,160,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,5, + 0,0,0,6,0,0,0,67,0,0,0,115,72,0,0,0, + 116,0,160,1,100,1,116,2,161,2,1,0,124,0,160,3, + 124,1,161,1,92,2,125,2,125,3,124,2,100,2,117,0, + 114,34,116,4,124,3,131,1,114,34,100,3,125,4,116,0, + 160,1,124,4,160,5,124,3,100,4,25,0,161,1,116,6, + 161,2,1,0,124,2,83,0,41,5,122,155,84,114,121,32, + 116,111,32,102,105,110,100,32,97,32,108,111,97,100,101,114, + 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, + 101,100,32,109,111,100,117,108,101,32,98,121,32,100,101,108, + 101,103,97,116,105,110,103,32,116,111,10,32,32,32,32,115, + 101,108,102,46,102,105,110,100,95,108,111,97,100,101,114,40, + 41,46,10,10,32,32,32,32,84,104,105,115,32,109,101,116, + 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, + 100,32,105,110,32,102,97,118,111,114,32,111,102,32,102,105, + 110,100,101,114,46,102,105,110,100,95,115,112,101,99,40,41, + 46,10,10,32,32,32,32,122,90,102,105,110,100,95,109,111, + 100,117,108,101,40,41,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,32,97,110,100,32,115,108,97,116,101,100,32, + 102,111,114,32,114,101,109,111,118,97,108,32,105,110,32,80, + 121,116,104,111,110,32,51,46,49,50,59,32,117,115,101,32, + 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, + 101,97,100,78,122,44,78,111,116,32,105,109,112,111,114,116, + 105,110,103,32,100,105,114,101,99,116,111,114,121,32,123,125, + 58,32,109,105,115,115,105,110,103,32,95,95,105,110,105,116, + 95,95,114,0,0,0,0,41,7,114,99,0,0,0,114,100, + 0,0,0,114,101,0,0,0,218,11,102,105,110,100,95,108, + 111,97,100,101,114,114,4,0,0,0,114,89,0,0,0,218, + 13,73,109,112,111,114,116,87,97,114,110,105,110,103,41,5, + 114,143,0,0,0,218,8,102,117,108,108,110,97,109,101,218, + 6,108,111,97,100,101,114,218,8,112,111,114,116,105,111,110, + 115,218,3,109,115,103,114,7,0,0,0,114,7,0,0,0, + 114,8,0,0,0,218,17,95,102,105,110,100,95,109,111,100, + 117,108,101,95,115,104,105,109,53,2,0,0,115,16,0,0, + 0,6,7,2,2,4,254,14,6,16,1,4,1,22,1,4, + 1,114,167,0,0,0,99,3,0,0,0,0,0,0,0,0, + 0,0,0,6,0,0,0,4,0,0,0,67,0,0,0,115, + 166,0,0,0,124,0,100,1,100,2,133,2,25,0,125,3, + 124,3,116,0,107,3,114,32,100,3,124,1,155,2,100,4, + 124,3,155,2,157,4,125,4,116,1,160,2,100,5,124,4, + 161,2,1,0,116,3,124,4,102,1,105,0,124,2,164,1, + 142,1,130,1,116,4,124,0,131,1,100,6,107,0,114,53, + 100,7,124,1,155,2,157,2,125,4,116,1,160,2,100,5, + 124,4,161,2,1,0,116,5,124,4,131,1,130,1,116,6, + 124,0,100,2,100,8,133,2,25,0,131,1,125,5,124,5, + 100,9,64,0,114,81,100,10,124,5,155,2,100,11,124,1, + 155,2,157,4,125,4,116,3,124,4,102,1,105,0,124,2, + 164,1,142,1,130,1,124,5,83,0,41,12,97,84,2,0, + 0,80,101,114,102,111,114,109,32,98,97,115,105,99,32,118, + 97,108,105,100,105,116,121,32,99,104,101,99,107,105,110,103, + 32,111,102,32,97,32,112,121,99,32,104,101,97,100,101,114, + 32,97,110,100,32,114,101,116,117,114,110,32,116,104,101,32, + 102,108,97,103,115,32,102,105,101,108,100,44,10,32,32,32, + 32,119,104,105,99,104,32,100,101,116,101,114,109,105,110,101, + 115,32,104,111,119,32,116,104,101,32,112,121,99,32,115,104, + 111,117,108,100,32,98,101,32,102,117,114,116,104,101,114,32, + 118,97,108,105,100,97,116,101,100,32,97,103,97,105,110,115, + 116,32,116,104,101,32,115,111,117,114,99,101,46,10,10,32, + 32,32,32,42,100,97,116,97,42,32,105,115,32,116,104,101, + 32,99,111,110,116,101,110,116,115,32,111,102,32,116,104,101, + 32,112,121,99,32,102,105,108,101,46,32,40,79,110,108,121, + 32,116,104,101,32,102,105,114,115,116,32,49,54,32,98,121, + 116,101,115,32,97,114,101,10,32,32,32,32,114,101,113,117, + 105,114,101,100,44,32,116,104,111,117,103,104,46,41,10,10, + 32,32,32,32,42,110,97,109,101,42,32,105,115,32,116,104, + 101,32,110,97,109,101,32,111,102,32,116,104,101,32,109,111, + 100,117,108,101,32,98,101,105,110,103,32,105,109,112,111,114, + 116,101,100,46,32,73,116,32,105,115,32,117,115,101,100,32, + 102,111,114,32,108,111,103,103,105,110,103,46,10,10,32,32, + 32,32,42,101,120,99,95,100,101,116,97,105,108,115,42,32, + 105,115,32,97,32,100,105,99,116,105,111,110,97,114,121,32, + 112,97,115,115,101,100,32,116,111,32,73,109,112,111,114,116, + 69,114,114,111,114,32,105,102,32,105,116,32,114,97,105,115, + 101,100,32,102,111,114,10,32,32,32,32,105,109,112,114,111, + 118,101,100,32,100,101,98,117,103,103,105,110,103,46,10,10, + 32,32,32,32,73,109,112,111,114,116,69,114,114,111,114,32, + 105,115,32,114,97,105,115,101,100,32,119,104,101,110,32,116, + 104,101,32,109,97,103,105,99,32,110,117,109,98,101,114,32, + 105,115,32,105,110,99,111,114,114,101,99,116,32,111,114,32, + 119,104,101,110,32,116,104,101,32,102,108,97,103,115,10,32, + 32,32,32,102,105,101,108,100,32,105,115,32,105,110,118,97, + 108,105,100,46,32,69,79,70,69,114,114,111,114,32,105,115, + 32,114,97,105,115,101,100,32,119,104,101,110,32,116,104,101, + 32,100,97,116,97,32,105,115,32,102,111,117,110,100,32,116, + 111,32,98,101,32,116,114,117,110,99,97,116,101,100,46,10, + 10,32,32,32,32,78,114,31,0,0,0,122,20,98,97,100, + 32,109,97,103,105,99,32,110,117,109,98,101,114,32,105,110, + 32,122,2,58,32,250,2,123,125,233,16,0,0,0,122,40, + 114,101,97,99,104,101,100,32,69,79,70,32,119,104,105,108, + 101,32,114,101,97,100,105,110,103,32,112,121,99,32,104,101, + 97,100,101,114,32,111,102,32,233,8,0,0,0,233,252,255, + 255,255,122,14,105,110,118,97,108,105,100,32,102,108,97,103, + 115,32,122,4,32,105,110,32,41,7,218,12,77,65,71,73, + 67,95,78,85,77,66,69,82,114,159,0,0,0,218,16,95, + 118,101,114,98,111,115,101,95,109,101,115,115,97,103,101,114, + 142,0,0,0,114,4,0,0,0,218,8,69,79,70,69,114, + 114,111,114,114,42,0,0,0,41,6,114,41,0,0,0,114, + 141,0,0,0,218,11,101,120,99,95,100,101,116,97,105,108, + 115,90,5,109,97,103,105,99,114,117,0,0,0,114,16,0, + 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, + 0,218,13,95,99,108,97,115,115,105,102,121,95,112,121,99, + 73,2,0,0,115,28,0,0,0,12,16,8,1,16,1,12, + 1,16,1,12,1,10,1,12,1,8,1,16,1,8,2,16, + 1,16,1,4,1,114,176,0,0,0,99,5,0,0,0,0, + 0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,67, + 0,0,0,115,124,0,0,0,116,0,124,0,100,1,100,2, + 133,2,25,0,131,1,124,1,100,3,64,0,107,3,114,31, + 100,4,124,3,155,2,157,2,125,5,116,1,160,2,100,5, + 124,5,161,2,1,0,116,3,124,5,102,1,105,0,124,4, + 164,1,142,1,130,1,124,2,100,6,117,1,114,58,116,0, + 124,0,100,2,100,7,133,2,25,0,131,1,124,2,100,3, + 64,0,107,3,114,60,116,3,100,4,124,3,155,2,157,2, + 102,1,105,0,124,4,164,1,142,1,130,1,100,6,83,0, + 100,6,83,0,41,8,97,7,2,0,0,86,97,108,105,100, + 97,116,101,32,97,32,112,121,99,32,97,103,97,105,110,115, + 116,32,116,104,101,32,115,111,117,114,99,101,32,108,97,115, + 116,45,109,111,100,105,102,105,101,100,32,116,105,109,101,46, + 10,10,32,32,32,32,42,100,97,116,97,42,32,105,115,32, + 116,104,101,32,99,111,110,116,101,110,116,115,32,111,102,32, + 116,104,101,32,112,121,99,32,102,105,108,101,46,32,40,79, + 110,108,121,32,116,104,101,32,102,105,114,115,116,32,49,54, + 32,98,121,116,101,115,32,97,114,101,10,32,32,32,32,114, + 101,113,117,105,114,101,100,46,41,10,10,32,32,32,32,42, + 115,111,117,114,99,101,95,109,116,105,109,101,42,32,105,115, + 32,116,104,101,32,108,97,115,116,32,109,111,100,105,102,105, + 101,100,32,116,105,109,101,115,116,97,109,112,32,111,102,32, + 116,104,101,32,115,111,117,114,99,101,32,102,105,108,101,46, + 10,10,32,32,32,32,42,115,111,117,114,99,101,95,115,105, + 122,101,42,32,105,115,32,78,111,110,101,32,111,114,32,116, + 104,101,32,115,105,122,101,32,111,102,32,116,104,101,32,115, + 111,117,114,99,101,32,102,105,108,101,32,105,110,32,98,121, + 116,101,115,46,10,10,32,32,32,32,42,110,97,109,101,42, 32,105,115,32,116,104,101,32,110,97,109,101,32,111,102,32, 116,104,101,32,109,111,100,117,108,101,32,98,101,105,110,103, 32,105,109,112,111,114,116,101,100,46,32,73,116,32,105,115, @@ -749,93 +821,26 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 73,109,112,111,114,116,69,114,114,111,114,32,105,102,32,105, 116,32,114,97,105,115,101,100,32,102,111,114,10,32,32,32, 32,105,109,112,114,111,118,101,100,32,100,101,98,117,103,103, - 105,110,103,46,10,10,32,32,32,32,73,109,112,111,114,116, - 69,114,114,111,114,32,105,115,32,114,97,105,115,101,100,32, - 119,104,101,110,32,116,104,101,32,109,97,103,105,99,32,110, - 117,109,98,101,114,32,105,115,32,105,110,99,111,114,114,101, - 99,116,32,111,114,32,119,104,101,110,32,116,104,101,32,102, - 108,97,103,115,10,32,32,32,32,102,105,101,108,100,32,105, - 115,32,105,110,118,97,108,105,100,46,32,69,79,70,69,114, - 114,111,114,32,105,115,32,114,97,105,115,101,100,32,119,104, - 101,110,32,116,104,101,32,100,97,116,97,32,105,115,32,102, - 111,117,110,100,32,116,111,32,98,101,32,116,114,117,110,99, - 97,116,101,100,46,10,10,32,32,32,32,78,114,34,0,0, - 0,122,20,98,97,100,32,109,97,103,105,99,32,110,117,109, - 98,101,114,32,105,110,32,122,2,58,32,250,2,123,125,233, - 16,0,0,0,122,40,114,101,97,99,104,101,100,32,69,79, - 70,32,119,104,105,108,101,32,114,101,97,100,105,110,103,32, - 112,121,99,32,104,101,97,100,101,114,32,111,102,32,233,8, - 0,0,0,233,252,255,255,255,122,14,105,110,118,97,108,105, - 100,32,102,108,97,103,115,32,122,4,32,105,110,32,41,7, - 218,12,77,65,71,73,67,95,78,85,77,66,69,82,114,158, - 0,0,0,218,16,95,118,101,114,98,111,115,101,95,109,101, - 115,115,97,103,101,114,141,0,0,0,114,6,0,0,0,218, - 8,69,79,70,69,114,114,111,114,114,44,0,0,0,41,6, - 114,43,0,0,0,114,140,0,0,0,218,11,101,120,99,95, - 100,101,116,97,105,108,115,90,5,109,97,103,105,99,114,116, - 0,0,0,114,22,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,13,95,99,108,97,115,115,105, - 102,121,95,112,121,99,48,2,0,0,115,28,0,0,0,0, - 16,12,1,8,1,16,1,12,1,16,1,12,1,10,1,12, - 1,8,1,16,2,8,1,16,1,16,1,114,176,0,0,0, - 99,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0, - 0,4,0,0,0,67,0,0,0,115,120,0,0,0,116,0, - 124,0,100,1,100,2,133,2,25,0,131,1,124,1,100,3, - 64,0,107,3,114,62,100,4,124,3,155,2,157,2,125,5, - 116,1,160,2,100,5,124,5,161,2,1,0,116,3,124,5, - 102,1,105,0,124,4,164,1,142,1,130,1,124,2,100,6, - 117,1,114,116,116,0,124,0,100,2,100,7,133,2,25,0, - 131,1,124,2,100,3,64,0,107,3,114,116,116,3,100,4, - 124,3,155,2,157,2,102,1,105,0,124,4,164,1,142,1, - 130,1,100,6,83,0,41,8,97,7,2,0,0,86,97,108, - 105,100,97,116,101,32,97,32,112,121,99,32,97,103,97,105, - 110,115,116,32,116,104,101,32,115,111,117,114,99,101,32,108, - 97,115,116,45,109,111,100,105,102,105,101,100,32,116,105,109, - 101,46,10,10,32,32,32,32,42,100,97,116,97,42,32,105, - 115,32,116,104,101,32,99,111,110,116,101,110,116,115,32,111, - 102,32,116,104,101,32,112,121,99,32,102,105,108,101,46,32, - 40,79,110,108,121,32,116,104,101,32,102,105,114,115,116,32, - 49,54,32,98,121,116,101,115,32,97,114,101,10,32,32,32, - 32,114,101,113,117,105,114,101,100,46,41,10,10,32,32,32, - 32,42,115,111,117,114,99,101,95,109,116,105,109,101,42,32, - 105,115,32,116,104,101,32,108,97,115,116,32,109,111,100,105, - 102,105,101,100,32,116,105,109,101,115,116,97,109,112,32,111, - 102,32,116,104,101,32,115,111,117,114,99,101,32,102,105,108, - 101,46,10,10,32,32,32,32,42,115,111,117,114,99,101,95, - 115,105,122,101,42,32,105,115,32,78,111,110,101,32,111,114, - 32,116,104,101,32,115,105,122,101,32,111,102,32,116,104,101, - 32,115,111,117,114,99,101,32,102,105,108,101,32,105,110,32, - 98,121,116,101,115,46,10,10,32,32,32,32,42,110,97,109, - 101,42,32,105,115,32,116,104,101,32,110,97,109,101,32,111, - 102,32,116,104,101,32,109,111,100,117,108,101,32,98,101,105, - 110,103,32,105,109,112,111,114,116,101,100,46,32,73,116,32, - 105,115,32,117,115,101,100,32,102,111,114,32,108,111,103,103, - 105,110,103,46,10,10,32,32,32,32,42,101,120,99,95,100, - 101,116,97,105,108,115,42,32,105,115,32,97,32,100,105,99, - 116,105,111,110,97,114,121,32,112,97,115,115,101,100,32,116, - 111,32,73,109,112,111,114,116,69,114,114,111,114,32,105,102, - 32,105,116,32,114,97,105,115,101,100,32,102,111,114,10,32, - 32,32,32,105,109,112,114,111,118,101,100,32,100,101,98,117, - 103,103,105,110,103,46,10,10,32,32,32,32,65,110,32,73, - 109,112,111,114,116,69,114,114,111,114,32,105,115,32,114,97, - 105,115,101,100,32,105,102,32,116,104,101,32,98,121,116,101, - 99,111,100,101,32,105,115,32,115,116,97,108,101,46,10,10, - 32,32,32,32,114,170,0,0,0,233,12,0,0,0,114,33, - 0,0,0,122,22,98,121,116,101,99,111,100,101,32,105,115, - 32,115,116,97,108,101,32,102,111,114,32,114,168,0,0,0, - 78,114,169,0,0,0,41,4,114,44,0,0,0,114,158,0, - 0,0,114,173,0,0,0,114,141,0,0,0,41,6,114,43, - 0,0,0,218,12,115,111,117,114,99,101,95,109,116,105,109, - 101,218,11,115,111,117,114,99,101,95,115,105,122,101,114,140, - 0,0,0,114,175,0,0,0,114,116,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,23,95,118, - 97,108,105,100,97,116,101,95,116,105,109,101,115,116,97,109, - 112,95,112,121,99,81,2,0,0,115,16,0,0,0,0,19, - 24,1,10,1,12,1,16,1,8,1,22,255,2,2,114,180, + 105,110,103,46,10,10,32,32,32,32,65,110,32,73,109,112, + 111,114,116,69,114,114,111,114,32,105,115,32,114,97,105,115, + 101,100,32,105,102,32,116,104,101,32,98,121,116,101,99,111, + 100,101,32,105,115,32,115,116,97,108,101,46,10,10,32,32, + 32,32,114,170,0,0,0,233,12,0,0,0,114,30,0,0, + 0,122,22,98,121,116,101,99,111,100,101,32,105,115,32,115, + 116,97,108,101,32,102,111,114,32,114,168,0,0,0,78,114, + 169,0,0,0,41,4,114,42,0,0,0,114,159,0,0,0, + 114,173,0,0,0,114,142,0,0,0,41,6,114,41,0,0, + 0,218,12,115,111,117,114,99,101,95,109,116,105,109,101,218, + 11,115,111,117,114,99,101,95,115,105,122,101,114,141,0,0, + 0,114,175,0,0,0,114,117,0,0,0,114,7,0,0,0, + 114,7,0,0,0,114,8,0,0,0,218,23,95,118,97,108, + 105,100,97,116,101,95,116,105,109,101,115,116,97,109,112,95, + 112,121,99,106,2,0,0,115,18,0,0,0,24,19,10,1, + 12,1,16,1,8,1,22,1,2,255,22,2,8,254,114,180, 0,0,0,99,4,0,0,0,0,0,0,0,0,0,0,0, 4,0,0,0,4,0,0,0,67,0,0,0,115,42,0,0, 0,124,0,100,1,100,2,133,2,25,0,124,1,107,3,114, - 38,116,0,100,3,124,2,155,2,157,2,102,1,105,0,124, + 19,116,0,100,3,124,2,155,2,157,2,102,1,105,0,124, 3,164,1,142,1,130,1,100,4,83,0,41,5,97,243,1, 0,0,86,97,108,105,100,97,116,101,32,97,32,104,97,115, 104,45,98,97,115,101,100,32,112,121,99,32,98,121,32,99, @@ -872,1245 +877,1212 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 46,104,97,115,104,32,105,110,32,98,121,116,101,99,111,100, 101,32,100,111,101,115,110,39,116,32,109,97,116,99,104,32, 104,97,115,104,32,111,102,32,115,111,117,114,99,101,32,78, - 41,1,114,141,0,0,0,41,4,114,43,0,0,0,218,11, - 115,111,117,114,99,101,95,104,97,115,104,114,140,0,0,0, - 114,175,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,18,95,118,97,108,105,100,97,116,101,95, - 104,97,115,104,95,112,121,99,109,2,0,0,115,12,0,0, - 0,0,17,16,1,2,1,8,255,4,2,2,254,114,182,0, - 0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,5, - 0,0,0,5,0,0,0,67,0,0,0,115,80,0,0,0, - 116,0,160,1,124,0,161,1,125,4,116,2,124,4,116,3, - 131,2,114,56,116,4,160,5,100,1,124,2,161,2,1,0, - 124,3,100,2,117,1,114,52,116,6,160,7,124,4,124,3, - 161,2,1,0,124,4,83,0,116,8,100,3,160,9,124,2, - 161,1,124,1,124,2,100,4,141,3,130,1,100,2,83,0, - 41,5,122,35,67,111,109,112,105,108,101,32,98,121,116,101, - 99,111,100,101,32,97,115,32,102,111,117,110,100,32,105,110, - 32,97,32,112,121,99,46,122,21,99,111,100,101,32,111,98, - 106,101,99,116,32,102,114,111,109,32,123,33,114,125,78,122, - 23,78,111,110,45,99,111,100,101,32,111,98,106,101,99,116, - 32,105,110,32,123,33,114,125,169,2,114,140,0,0,0,114, - 65,0,0,0,41,10,218,7,109,97,114,115,104,97,108,90, - 5,108,111,97,100,115,218,10,105,115,105,110,115,116,97,110, - 99,101,218,10,95,99,111,100,101,95,116,121,112,101,114,158, - 0,0,0,114,173,0,0,0,218,4,95,105,109,112,90,16, - 95,102,105,120,95,99,111,95,102,105,108,101,110,97,109,101, - 114,141,0,0,0,114,88,0,0,0,41,5,114,43,0,0, - 0,114,140,0,0,0,114,131,0,0,0,114,133,0,0,0, - 218,4,99,111,100,101,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,17,95,99,111,109,112,105,108,101,95, - 98,121,116,101,99,111,100,101,133,2,0,0,115,18,0,0, - 0,0,2,10,1,10,1,12,1,8,1,12,1,4,2,10, - 1,4,255,114,189,0,0,0,99,3,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,0, - 0,115,70,0,0,0,116,0,116,1,131,1,125,3,124,3, - 160,2,116,3,100,1,131,1,161,1,1,0,124,3,160,2, - 116,3,124,1,131,1,161,1,1,0,124,3,160,2,116,3, - 124,2,131,1,161,1,1,0,124,3,160,2,116,4,160,5, - 124,0,161,1,161,1,1,0,124,3,83,0,41,2,122,43, - 80,114,111,100,117,99,101,32,116,104,101,32,100,97,116,97, - 32,102,111,114,32,97,32,116,105,109,101,115,116,97,109,112, - 45,98,97,115,101,100,32,112,121,99,46,114,0,0,0,0, - 41,6,218,9,98,121,116,101,97,114,114,97,121,114,172,0, - 0,0,218,6,101,120,116,101,110,100,114,39,0,0,0,114, - 184,0,0,0,218,5,100,117,109,112,115,41,4,114,188,0, - 0,0,218,5,109,116,105,109,101,114,179,0,0,0,114,43, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,22,95,99,111,100,101,95,116,111,95,116,105,109, - 101,115,116,97,109,112,95,112,121,99,146,2,0,0,115,12, - 0,0,0,0,2,8,1,14,1,14,1,14,1,16,1,114, - 194,0,0,0,84,99,3,0,0,0,0,0,0,0,0,0, - 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,80, - 0,0,0,116,0,116,1,131,1,125,3,100,1,124,2,100, - 1,62,0,66,0,125,4,124,3,160,2,116,3,124,4,131, - 1,161,1,1,0,116,4,124,1,131,1,100,2,107,2,115, - 50,74,0,130,1,124,3,160,2,124,1,161,1,1,0,124, - 3,160,2,116,5,160,6,124,0,161,1,161,1,1,0,124, - 3,83,0,41,3,122,38,80,114,111,100,117,99,101,32,116, - 104,101,32,100,97,116,97,32,102,111,114,32,97,32,104,97, - 115,104,45,98,97,115,101,100,32,112,121,99,46,114,4,0, - 0,0,114,170,0,0,0,41,7,114,190,0,0,0,114,172, - 0,0,0,114,191,0,0,0,114,39,0,0,0,114,6,0, - 0,0,114,184,0,0,0,114,192,0,0,0,41,5,114,188, - 0,0,0,114,181,0,0,0,90,7,99,104,101,99,107,101, - 100,114,43,0,0,0,114,22,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,17,95,99,111,100, - 101,95,116,111,95,104,97,115,104,95,112,121,99,156,2,0, - 0,115,14,0,0,0,0,2,8,1,12,1,14,1,16,1, - 10,1,16,1,114,195,0,0,0,99,1,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,6,0,0,0,67,0, - 0,0,115,62,0,0,0,100,1,100,2,108,0,125,1,116, - 1,160,2,124,0,161,1,106,3,125,2,124,1,160,4,124, - 2,161,1,125,3,116,1,160,5,100,2,100,3,161,2,125, - 4,124,4,160,6,124,0,160,6,124,3,100,1,25,0,161, - 1,161,1,83,0,41,4,122,121,68,101,99,111,100,101,32, - 98,121,116,101,115,32,114,101,112,114,101,115,101,110,116,105, - 110,103,32,115,111,117,114,99,101,32,99,111,100,101,32,97, - 110,100,32,114,101,116,117,114,110,32,116,104,101,32,115,116, - 114,105,110,103,46,10,10,32,32,32,32,85,110,105,118,101, - 114,115,97,108,32,110,101,119,108,105,110,101,32,115,117,112, - 112,111,114,116,32,105,115,32,117,115,101,100,32,105,110,32, - 116,104,101,32,100,101,99,111,100,105,110,103,46,10,32,32, - 32,32,114,0,0,0,0,78,84,41,7,218,8,116,111,107, - 101,110,105,122,101,114,90,0,0,0,90,7,66,121,116,101, - 115,73,79,90,8,114,101,97,100,108,105,110,101,90,15,100, - 101,116,101,99,116,95,101,110,99,111,100,105,110,103,90,25, - 73,110,99,114,101,109,101,110,116,97,108,78,101,119,108,105, - 110,101,68,101,99,111,100,101,114,218,6,100,101,99,111,100, - 101,41,5,218,12,115,111,117,114,99,101,95,98,121,116,101, - 115,114,196,0,0,0,90,21,115,111,117,114,99,101,95,98, - 121,116,101,115,95,114,101,97,100,108,105,110,101,218,8,101, - 110,99,111,100,105,110,103,90,15,110,101,119,108,105,110,101, - 95,100,101,99,111,100,101,114,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,13,100,101,99,111,100,101,95, - 115,111,117,114,99,101,167,2,0,0,115,10,0,0,0,0, - 5,8,1,12,1,10,1,12,1,114,200,0,0,0,169,2, - 114,164,0,0,0,218,26,115,117,98,109,111,100,117,108,101, - 95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,110, - 115,99,2,0,0,0,0,0,0,0,2,0,0,0,9,0, - 0,0,8,0,0,0,67,0,0,0,115,12,1,0,0,124, - 1,100,1,117,0,114,58,100,2,125,1,116,0,124,2,100, - 3,131,2,114,68,122,14,124,2,160,1,124,0,161,1,125, - 1,87,0,113,68,4,0,116,2,121,54,1,0,1,0,1, - 0,89,0,113,68,48,0,110,10,116,3,160,4,124,1,161, - 1,125,1,116,5,106,6,124,0,124,2,124,1,100,4,141, - 3,125,4,100,5,124,4,95,7,124,2,100,1,117,0,114, - 152,116,8,131,0,68,0,93,42,92,2,125,5,125,6,124, - 1,160,9,116,10,124,6,131,1,161,1,114,104,124,5,124, - 0,124,1,131,2,125,2,124,2,124,4,95,11,1,0,113, - 152,113,104,100,1,83,0,124,3,116,12,117,0,114,216,116, - 0,124,2,100,6,131,2,114,222,122,14,124,2,160,13,124, - 0,161,1,125,7,87,0,110,18,4,0,116,2,121,202,1, - 0,1,0,1,0,89,0,113,222,48,0,124,7,114,222,103, - 0,124,4,95,14,110,6,124,3,124,4,95,14,124,4,106, - 14,103,0,107,2,144,1,114,8,124,1,144,1,114,8,116, - 15,124,1,131,1,100,7,25,0,125,8,124,4,106,14,160, - 16,124,8,161,1,1,0,124,4,83,0,41,8,97,61,1, - 0,0,82,101,116,117,114,110,32,97,32,109,111,100,117,108, - 101,32,115,112,101,99,32,98,97,115,101,100,32,111,110,32, - 97,32,102,105,108,101,32,108,111,99,97,116,105,111,110,46, - 10,10,32,32,32,32,84,111,32,105,110,100,105,99,97,116, - 101,32,116,104,97,116,32,116,104,101,32,109,111,100,117,108, - 101,32,105,115,32,97,32,112,97,99,107,97,103,101,44,32, - 115,101,116,10,32,32,32,32,115,117,98,109,111,100,117,108, - 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, - 110,115,32,116,111,32,97,32,108,105,115,116,32,111,102,32, - 100,105,114,101,99,116,111,114,121,32,112,97,116,104,115,46, - 32,32,65,110,10,32,32,32,32,101,109,112,116,121,32,108, - 105,115,116,32,105,115,32,115,117,102,102,105,99,105,101,110, - 116,44,32,116,104,111,117,103,104,32,105,116,115,32,110,111, - 116,32,111,116,104,101,114,119,105,115,101,32,117,115,101,102, - 117,108,32,116,111,32,116,104,101,10,32,32,32,32,105,109, - 112,111,114,116,32,115,121,115,116,101,109,46,10,10,32,32, - 32,32,84,104,101,32,108,111,97,100,101,114,32,109,117,115, - 116,32,116,97,107,101,32,97,32,115,112,101,99,32,97,115, - 32,105,116,115,32,111,110,108,121,32,95,95,105,110,105,116, - 95,95,40,41,32,97,114,103,46,10,10,32,32,32,32,78, - 122,9,60,117,110,107,110,111,119,110,62,218,12,103,101,116, - 95,102,105,108,101,110,97,109,101,169,1,218,6,111,114,105, - 103,105,110,84,218,10,105,115,95,112,97,99,107,97,103,101, - 114,0,0,0,0,41,17,114,152,0,0,0,114,203,0,0, - 0,114,141,0,0,0,114,24,0,0,0,114,102,0,0,0, - 114,158,0,0,0,218,10,77,111,100,117,108,101,83,112,101, - 99,90,13,95,115,101,116,95,102,105,108,101,97,116,116,114, - 218,27,95,103,101,116,95,115,117,112,112,111,114,116,101,100, - 95,102,105,108,101,95,108,111,97,100,101,114,115,114,58,0, - 0,0,114,135,0,0,0,114,164,0,0,0,218,9,95,80, - 79,80,85,76,65,84,69,114,206,0,0,0,114,202,0,0, - 0,114,74,0,0,0,114,61,0,0,0,41,9,114,140,0, - 0,0,90,8,108,111,99,97,116,105,111,110,114,164,0,0, - 0,114,202,0,0,0,218,4,115,112,101,99,218,12,108,111, - 97,100,101,114,95,99,108,97,115,115,218,8,115,117,102,102, - 105,120,101,115,114,206,0,0,0,90,7,100,105,114,110,97, - 109,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,23,115,112,101,99,95,102,114,111,109,95,102,105,108, - 101,95,108,111,99,97,116,105,111,110,184,2,0,0,115,62, - 0,0,0,0,12,8,4,4,1,10,2,2,1,14,1,12, - 1,8,2,10,8,16,1,6,3,8,1,14,1,14,1,10, - 1,6,1,6,2,4,3,8,2,10,1,2,1,14,1,12, - 1,6,2,4,1,8,2,6,1,12,1,6,1,12,1,12, - 2,114,213,0,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, - 80,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 100,2,90,4,100,3,90,5,100,4,90,6,101,7,100,5, - 100,6,132,0,131,1,90,8,101,7,100,7,100,8,132,0, - 131,1,90,9,101,7,100,14,100,10,100,11,132,1,131,1, - 90,10,101,7,100,15,100,12,100,13,132,1,131,1,90,11, - 100,9,83,0,41,16,218,21,87,105,110,100,111,119,115,82, - 101,103,105,115,116,114,121,70,105,110,100,101,114,122,62,77, - 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32, - 102,111,114,32,109,111,100,117,108,101,115,32,100,101,99,108, - 97,114,101,100,32,105,110,32,116,104,101,32,87,105,110,100, - 111,119,115,32,114,101,103,105,115,116,114,121,46,122,59,83, - 111,102,116,119,97,114,101,92,80,121,116,104,111,110,92,80, - 121,116,104,111,110,67,111,114,101,92,123,115,121,115,95,118, - 101,114,115,105,111,110,125,92,77,111,100,117,108,101,115,92, - 123,102,117,108,108,110,97,109,101,125,122,65,83,111,102,116, - 119,97,114,101,92,80,121,116,104,111,110,92,80,121,116,104, - 111,110,67,111,114,101,92,123,115,121,115,95,118,101,114,115, - 105,111,110,125,92,77,111,100,117,108,101,115,92,123,102,117, - 108,108,110,97,109,101,125,92,68,101,98,117,103,70,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,8, - 0,0,0,67,0,0,0,115,54,0,0,0,122,16,116,0, - 160,1,116,0,106,2,124,1,161,2,87,0,83,0,4,0, - 116,3,121,48,1,0,1,0,1,0,116,0,160,1,116,0, - 106,4,124,1,161,2,6,0,89,0,83,0,48,0,100,0, - 83,0,114,69,0,0,0,41,5,218,6,119,105,110,114,101, - 103,90,7,79,112,101,110,75,101,121,90,17,72,75,69,89, - 95,67,85,82,82,69,78,84,95,85,83,69,82,114,76,0, - 0,0,90,18,72,75,69,89,95,76,79,67,65,76,95,77, - 65,67,72,73,78,69,41,2,218,3,99,108,115,114,26,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,14,95,111,112,101,110,95,114,101,103,105,115,116,114, - 121,8,3,0,0,115,8,0,0,0,0,2,2,1,16,1, - 12,1,122,36,87,105,110,100,111,119,115,82,101,103,105,115, - 116,114,121,70,105,110,100,101,114,46,95,111,112,101,110,95, - 114,101,103,105,115,116,114,121,99,2,0,0,0,0,0,0, - 0,0,0,0,0,6,0,0,0,8,0,0,0,67,0,0, - 0,115,132,0,0,0,124,0,106,0,114,14,124,0,106,1, - 125,2,110,6,124,0,106,2,125,2,124,2,106,3,124,1, - 100,1,116,4,106,5,100,0,100,2,133,2,25,0,22,0, - 100,3,141,2,125,3,122,58,124,0,160,6,124,3,161,1, - 143,28,125,4,116,7,160,8,124,4,100,4,161,2,125,5, - 87,0,100,0,4,0,4,0,131,3,1,0,110,16,49,0, - 115,94,48,0,1,0,1,0,1,0,89,0,1,0,87,0, - 110,20,4,0,116,9,121,126,1,0,1,0,1,0,89,0, - 100,0,83,0,48,0,124,5,83,0,41,5,78,122,5,37, - 100,46,37,100,114,45,0,0,0,41,2,114,163,0,0,0, - 90,11,115,121,115,95,118,101,114,115,105,111,110,114,14,0, - 0,0,41,10,218,11,68,69,66,85,71,95,66,85,73,76, - 68,218,18,82,69,71,73,83,84,82,89,95,75,69,89,95, - 68,69,66,85,71,218,12,82,69,71,73,83,84,82,89,95, - 75,69,89,114,88,0,0,0,114,21,0,0,0,218,12,118, - 101,114,115,105,111,110,95,105,110,102,111,114,217,0,0,0, - 114,215,0,0,0,90,10,81,117,101,114,121,86,97,108,117, - 101,114,76,0,0,0,41,6,114,216,0,0,0,114,163,0, - 0,0,90,12,114,101,103,105,115,116,114,121,95,107,101,121, - 114,26,0,0,0,90,4,104,107,101,121,218,8,102,105,108, - 101,112,97,116,104,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,16,95,115,101,97,114,99,104,95,114,101, - 103,105,115,116,114,121,15,3,0,0,115,24,0,0,0,0, - 2,6,1,8,2,6,1,6,1,16,255,6,2,2,1,12, - 1,46,1,12,1,8,1,122,38,87,105,110,100,111,119,115, - 82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,95, - 115,101,97,114,99,104,95,114,101,103,105,115,116,114,121,78, - 99,4,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,8,0,0,0,67,0,0,0,115,120,0,0,0,124,0, - 160,0,124,1,161,1,125,4,124,4,100,0,117,0,114,22, - 100,0,83,0,122,12,116,1,124,4,131,1,1,0,87,0, - 110,20,4,0,116,2,121,54,1,0,1,0,1,0,89,0, - 100,0,83,0,48,0,116,3,131,0,68,0,93,52,92,2, - 125,5,125,6,124,4,160,4,116,5,124,6,131,1,161,1, - 114,62,116,6,106,7,124,1,124,5,124,1,124,4,131,2, - 124,4,100,1,141,3,125,7,124,7,2,0,1,0,83,0, - 113,62,100,0,83,0,41,2,78,114,204,0,0,0,41,8, - 114,223,0,0,0,114,75,0,0,0,114,76,0,0,0,114, - 208,0,0,0,114,58,0,0,0,114,135,0,0,0,114,158, - 0,0,0,218,16,115,112,101,99,95,102,114,111,109,95,108, - 111,97,100,101,114,41,8,114,216,0,0,0,114,163,0,0, - 0,114,65,0,0,0,218,6,116,97,114,103,101,116,114,222, - 0,0,0,114,164,0,0,0,114,212,0,0,0,114,210,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,9,102,105,110,100,95,115,112,101,99,30,3,0,0, - 115,28,0,0,0,0,2,10,1,8,1,4,1,2,1,12, - 1,12,1,8,1,14,1,14,1,6,1,8,1,2,254,6, - 3,122,31,87,105,110,100,111,119,115,82,101,103,105,115,116, - 114,121,70,105,110,100,101,114,46,102,105,110,100,95,115,112, - 101,99,99,3,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,4,0,0,0,67,0,0,0,115,34,0,0,0, - 124,0,160,0,124,1,124,2,161,2,125,3,124,3,100,1, - 117,1,114,26,124,3,106,1,83,0,100,1,83,0,100,1, - 83,0,41,2,122,108,70,105,110,100,32,109,111,100,117,108, + 41,1,114,142,0,0,0,41,4,114,41,0,0,0,218,11, + 115,111,117,114,99,101,95,104,97,115,104,114,141,0,0,0, + 114,175,0,0,0,114,7,0,0,0,114,7,0,0,0,114, + 8,0,0,0,218,18,95,118,97,108,105,100,97,116,101,95, + 104,97,115,104,95,112,121,99,134,2,0,0,115,14,0,0, + 0,16,17,2,1,8,1,4,255,2,2,6,254,4,255,114, + 182,0,0,0,99,4,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,5,0,0,0,67,0,0,0,115,76,0, + 0,0,116,0,160,1,124,0,161,1,125,4,116,2,124,4, + 116,3,131,2,114,28,116,4,160,5,100,1,124,2,161,2, + 1,0,124,3,100,2,117,1,114,26,116,6,160,7,124,4, + 124,3,161,2,1,0,124,4,83,0,116,8,100,3,160,9, + 124,2,161,1,124,1,124,2,100,4,141,3,130,1,41,5, + 122,35,67,111,109,112,105,108,101,32,98,121,116,101,99,111, + 100,101,32,97,115,32,102,111,117,110,100,32,105,110,32,97, + 32,112,121,99,46,122,21,99,111,100,101,32,111,98,106,101, + 99,116,32,102,114,111,109,32,123,33,114,125,78,122,23,78, + 111,110,45,99,111,100,101,32,111,98,106,101,99,116,32,105, + 110,32,123,33,114,125,169,2,114,141,0,0,0,114,65,0, + 0,0,41,10,218,7,109,97,114,115,104,97,108,90,5,108, + 111,97,100,115,218,10,105,115,105,110,115,116,97,110,99,101, + 218,10,95,99,111,100,101,95,116,121,112,101,114,159,0,0, + 0,114,173,0,0,0,218,4,95,105,109,112,90,16,95,102, + 105,120,95,99,111,95,102,105,108,101,110,97,109,101,114,142, + 0,0,0,114,89,0,0,0,41,5,114,41,0,0,0,114, + 141,0,0,0,114,132,0,0,0,114,134,0,0,0,218,4, + 99,111,100,101,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,17,95,99,111,109,112,105,108,101,95,98,121, + 116,101,99,111,100,101,158,2,0,0,115,18,0,0,0,10, + 2,10,1,12,1,8,1,12,1,4,1,10,2,4,1,6, + 255,114,189,0,0,0,99,3,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115, + 70,0,0,0,116,0,116,1,131,1,125,3,124,3,160,2, + 116,3,100,1,131,1,161,1,1,0,124,3,160,2,116,3, + 124,1,131,1,161,1,1,0,124,3,160,2,116,3,124,2, + 131,1,161,1,1,0,124,3,160,2,116,4,160,5,124,0, + 161,1,161,1,1,0,124,3,83,0,41,2,122,43,80,114, + 111,100,117,99,101,32,116,104,101,32,100,97,116,97,32,102, + 111,114,32,97,32,116,105,109,101,115,116,97,109,112,45,98, + 97,115,101,100,32,112,121,99,46,114,0,0,0,0,41,6, + 218,9,98,121,116,101,97,114,114,97,121,114,172,0,0,0, + 218,6,101,120,116,101,110,100,114,36,0,0,0,114,184,0, + 0,0,218,5,100,117,109,112,115,41,4,114,188,0,0,0, + 218,5,109,116,105,109,101,114,179,0,0,0,114,41,0,0, + 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, + 218,22,95,99,111,100,101,95,116,111,95,116,105,109,101,115, + 116,97,109,112,95,112,121,99,171,2,0,0,115,12,0,0, + 0,8,2,14,1,14,1,14,1,16,1,4,1,114,194,0, + 0,0,84,99,3,0,0,0,0,0,0,0,0,0,0,0, + 5,0,0,0,5,0,0,0,67,0,0,0,115,80,0,0, + 0,116,0,116,1,131,1,125,3,100,1,124,2,100,1,62, + 0,66,0,125,4,124,3,160,2,116,3,124,4,131,1,161, + 1,1,0,116,4,124,1,131,1,100,2,107,2,115,25,74, + 0,130,1,124,3,160,2,124,1,161,1,1,0,124,3,160, + 2,116,5,160,6,124,0,161,1,161,1,1,0,124,3,83, + 0,41,3,122,38,80,114,111,100,117,99,101,32,116,104,101, + 32,100,97,116,97,32,102,111,114,32,97,32,104,97,115,104, + 45,98,97,115,101,100,32,112,121,99,46,114,3,0,0,0, + 114,170,0,0,0,41,7,114,190,0,0,0,114,172,0,0, + 0,114,191,0,0,0,114,36,0,0,0,114,4,0,0,0, + 114,184,0,0,0,114,192,0,0,0,41,5,114,188,0,0, + 0,114,181,0,0,0,90,7,99,104,101,99,107,101,100,114, + 41,0,0,0,114,16,0,0,0,114,7,0,0,0,114,7, + 0,0,0,114,8,0,0,0,218,17,95,99,111,100,101,95, + 116,111,95,104,97,115,104,95,112,121,99,181,2,0,0,115, + 14,0,0,0,8,2,12,1,14,1,16,1,10,1,16,1, + 4,1,114,195,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,6,0,0,0,67,0,0,0, + 115,62,0,0,0,100,1,100,2,108,0,125,1,116,1,160, + 2,124,0,161,1,106,3,125,2,124,1,160,4,124,2,161, + 1,125,3,116,1,160,5,100,2,100,3,161,2,125,4,124, + 4,160,6,124,0,160,6,124,3,100,1,25,0,161,1,161, + 1,83,0,41,4,122,121,68,101,99,111,100,101,32,98,121, + 116,101,115,32,114,101,112,114,101,115,101,110,116,105,110,103, + 32,115,111,117,114,99,101,32,99,111,100,101,32,97,110,100, + 32,114,101,116,117,114,110,32,116,104,101,32,115,116,114,105, + 110,103,46,10,10,32,32,32,32,85,110,105,118,101,114,115, + 97,108,32,110,101,119,108,105,110,101,32,115,117,112,112,111, + 114,116,32,105,115,32,117,115,101,100,32,105,110,32,116,104, + 101,32,100,101,99,111,100,105,110,103,46,10,32,32,32,32, + 114,0,0,0,0,78,84,41,7,218,8,116,111,107,101,110, + 105,122,101,114,91,0,0,0,90,7,66,121,116,101,115,73, + 79,90,8,114,101,97,100,108,105,110,101,90,15,100,101,116, + 101,99,116,95,101,110,99,111,100,105,110,103,90,25,73,110, + 99,114,101,109,101,110,116,97,108,78,101,119,108,105,110,101, + 68,101,99,111,100,101,114,218,6,100,101,99,111,100,101,41, + 5,218,12,115,111,117,114,99,101,95,98,121,116,101,115,114, + 196,0,0,0,90,21,115,111,117,114,99,101,95,98,121,116, + 101,115,95,114,101,97,100,108,105,110,101,218,8,101,110,99, + 111,100,105,110,103,90,15,110,101,119,108,105,110,101,95,100, + 101,99,111,100,101,114,114,7,0,0,0,114,7,0,0,0, + 114,8,0,0,0,218,13,100,101,99,111,100,101,95,115,111, + 117,114,99,101,192,2,0,0,115,10,0,0,0,8,5,12, + 1,10,1,12,1,20,1,114,200,0,0,0,169,2,114,164, + 0,0,0,218,26,115,117,98,109,111,100,117,108,101,95,115, + 101,97,114,99,104,95,108,111,99,97,116,105,111,110,115,99, + 2,0,0,0,0,0,0,0,2,0,0,0,9,0,0,0, + 8,0,0,0,67,0,0,0,115,54,1,0,0,124,1,100, + 1,117,0,114,29,100,2,125,1,116,0,124,2,100,3,131, + 2,114,28,122,7,124,2,160,1,124,0,161,1,125,1,87, + 0,110,38,4,0,116,2,121,27,1,0,1,0,1,0,89, + 0,110,30,119,0,110,28,116,3,160,4,124,1,161,1,125, + 1,116,5,124,1,131,1,115,57,122,9,116,6,116,3,160, + 7,161,0,124,1,131,2,125,1,87,0,110,9,4,0,116, + 8,121,56,1,0,1,0,1,0,89,0,110,1,119,0,116, + 9,106,10,124,0,124,2,124,1,100,4,141,3,125,4,100, + 5,124,4,95,11,124,2,100,1,117,0,114,99,116,12,131, + 0,68,0,93,21,92,2,125,5,125,6,124,1,160,13,116, + 14,124,6,131,1,161,1,114,96,124,5,124,0,124,1,131, + 2,125,2,124,2,124,4,95,15,1,0,110,3,113,75,100, + 1,83,0,124,3,116,16,117,0,114,131,116,0,124,2,100, + 6,131,2,114,130,122,7,124,2,160,17,124,0,161,1,125, + 7,87,0,110,9,4,0,116,2,121,124,1,0,1,0,1, + 0,89,0,110,10,119,0,124,7,114,130,103,0,124,4,95, + 18,110,3,124,3,124,4,95,18,124,4,106,18,103,0,107, + 2,114,153,124,1,114,153,116,19,124,1,131,1,100,7,25, + 0,125,8,124,4,106,18,160,20,124,8,161,1,1,0,124, + 4,83,0,41,8,97,61,1,0,0,82,101,116,117,114,110, + 32,97,32,109,111,100,117,108,101,32,115,112,101,99,32,98, + 97,115,101,100,32,111,110,32,97,32,102,105,108,101,32,108, + 111,99,97,116,105,111,110,46,10,10,32,32,32,32,84,111, + 32,105,110,100,105,99,97,116,101,32,116,104,97,116,32,116, + 104,101,32,109,111,100,117,108,101,32,105,115,32,97,32,112, + 97,99,107,97,103,101,44,32,115,101,116,10,32,32,32,32, + 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, + 95,108,111,99,97,116,105,111,110,115,32,116,111,32,97,32, + 108,105,115,116,32,111,102,32,100,105,114,101,99,116,111,114, + 121,32,112,97,116,104,115,46,32,32,65,110,10,32,32,32, + 32,101,109,112,116,121,32,108,105,115,116,32,105,115,32,115, + 117,102,102,105,99,105,101,110,116,44,32,116,104,111,117,103, + 104,32,105,116,115,32,110,111,116,32,111,116,104,101,114,119, + 105,115,101,32,117,115,101,102,117,108,32,116,111,32,116,104, + 101,10,32,32,32,32,105,109,112,111,114,116,32,115,121,115, + 116,101,109,46,10,10,32,32,32,32,84,104,101,32,108,111, + 97,100,101,114,32,109,117,115,116,32,116,97,107,101,32,97, + 32,115,112,101,99,32,97,115,32,105,116,115,32,111,110,108, + 121,32,95,95,105,110,105,116,95,95,40,41,32,97,114,103, + 46,10,10,32,32,32,32,78,122,9,60,117,110,107,110,111, + 119,110,62,218,12,103,101,116,95,102,105,108,101,110,97,109, + 101,169,1,218,6,111,114,105,103,105,110,84,218,10,105,115, + 95,112,97,99,107,97,103,101,114,0,0,0,0,41,21,114, + 153,0,0,0,114,203,0,0,0,114,142,0,0,0,114,18, + 0,0,0,114,103,0,0,0,114,86,0,0,0,114,67,0, + 0,0,114,82,0,0,0,114,76,0,0,0,114,159,0,0, + 0,218,10,77,111,100,117,108,101,83,112,101,99,90,13,95, + 115,101,116,95,102,105,108,101,97,116,116,114,218,27,95,103, + 101,116,95,115,117,112,112,111,114,116,101,100,95,102,105,108, + 101,95,108,111,97,100,101,114,115,114,58,0,0,0,114,136, + 0,0,0,114,164,0,0,0,218,9,95,80,79,80,85,76, + 65,84,69,114,206,0,0,0,114,202,0,0,0,114,74,0, + 0,0,114,61,0,0,0,41,9,114,141,0,0,0,90,8, + 108,111,99,97,116,105,111,110,114,164,0,0,0,114,202,0, + 0,0,218,4,115,112,101,99,218,12,108,111,97,100,101,114, + 95,99,108,97,115,115,218,8,115,117,102,102,105,120,101,115, + 114,206,0,0,0,90,7,100,105,114,110,97,109,101,114,7, + 0,0,0,114,7,0,0,0,114,8,0,0,0,218,23,115, + 112,101,99,95,102,114,111,109,95,102,105,108,101,95,108,111, + 99,97,116,105,111,110,209,2,0,0,115,84,0,0,0,8, + 12,4,4,10,1,2,2,14,1,12,1,4,1,2,255,2, + 252,10,7,8,1,2,1,18,1,12,1,4,1,2,255,16, + 9,6,1,8,3,14,1,14,1,10,1,6,1,4,1,2, + 253,4,5,8,3,10,2,2,1,14,1,12,1,4,1,2, + 255,4,3,6,1,2,128,6,2,10,1,4,1,12,1,12, + 1,4,2,114,213,0,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,0, + 0,115,88,0,0,0,101,0,90,1,100,0,90,2,100,1, + 90,3,100,2,90,4,100,3,90,5,101,6,111,15,100,4, + 101,7,118,0,90,8,101,9,100,5,100,6,132,0,131,1, + 90,10,101,11,100,7,100,8,132,0,131,1,90,12,101,11, + 100,14,100,10,100,11,132,1,131,1,90,13,101,11,100,15, + 100,12,100,13,132,1,131,1,90,14,100,9,83,0,41,16, + 218,21,87,105,110,100,111,119,115,82,101,103,105,115,116,114, + 121,70,105,110,100,101,114,122,62,77,101,116,97,32,112,97, + 116,104,32,102,105,110,100,101,114,32,102,111,114,32,109,111, + 100,117,108,101,115,32,100,101,99,108,97,114,101,100,32,105, + 110,32,116,104,101,32,87,105,110,100,111,119,115,32,114,101, + 103,105,115,116,114,121,46,122,59,83,111,102,116,119,97,114, + 101,92,80,121,116,104,111,110,92,80,121,116,104,111,110,67, + 111,114,101,92,123,115,121,115,95,118,101,114,115,105,111,110, + 125,92,77,111,100,117,108,101,115,92,123,102,117,108,108,110, + 97,109,101,125,122,65,83,111,102,116,119,97,114,101,92,80, + 121,116,104,111,110,92,80,121,116,104,111,110,67,111,114,101, + 92,123,115,121,115,95,118,101,114,115,105,111,110,125,92,77, + 111,100,117,108,101,115,92,123,102,117,108,108,110,97,109,101, + 125,92,68,101,98,117,103,122,6,95,100,46,112,121,100,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 8,0,0,0,67,0,0,0,115,50,0,0,0,122,8,116, + 0,160,1,116,0,106,2,124,0,161,2,87,0,83,0,4, + 0,116,3,121,24,1,0,1,0,1,0,116,0,160,1,116, + 0,106,4,124,0,161,2,6,0,89,0,83,0,119,0,114, + 69,0,0,0,41,5,218,6,119,105,110,114,101,103,90,7, + 79,112,101,110,75,101,121,90,17,72,75,69,89,95,67,85, + 82,82,69,78,84,95,85,83,69,82,114,76,0,0,0,90, + 18,72,75,69,89,95,76,79,67,65,76,95,77,65,67,72, + 73,78,69,114,19,0,0,0,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,218,14,95,111,112,101,110,95,114, + 101,103,105,115,116,114,121,38,3,0,0,115,10,0,0,0, + 2,2,16,1,12,1,18,1,2,255,122,36,87,105,110,100, + 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, + 114,46,95,111,112,101,110,95,114,101,103,105,115,116,114,121, + 99,2,0,0,0,0,0,0,0,0,0,0,0,6,0,0, + 0,8,0,0,0,67,0,0,0,115,134,0,0,0,124,0, + 106,0,114,7,124,0,106,1,125,2,110,3,124,0,106,2, + 125,2,124,2,106,3,124,1,100,1,116,4,106,5,100,0, + 100,2,133,2,25,0,22,0,100,3,141,2,125,3,122,32, + 124,0,160,6,124,3,161,1,143,16,125,4,116,7,160,8, + 124,4,100,4,161,2,125,5,87,0,100,0,4,0,4,0, + 131,3,1,0,87,0,124,5,83,0,49,0,115,49,119,1, + 1,0,1,0,1,0,89,0,1,0,87,0,124,5,83,0, + 4,0,116,9,121,66,1,0,1,0,1,0,89,0,100,0, + 83,0,119,0,41,5,78,122,5,37,100,46,37,100,114,44, + 0,0,0,41,2,114,163,0,0,0,90,11,115,121,115,95, + 118,101,114,115,105,111,110,114,10,0,0,0,41,10,218,11, + 68,69,66,85,71,95,66,85,73,76,68,218,18,82,69,71, + 73,83,84,82,89,95,75,69,89,95,68,69,66,85,71,218, + 12,82,69,71,73,83,84,82,89,95,75,69,89,114,89,0, + 0,0,114,15,0,0,0,218,12,118,101,114,115,105,111,110, + 95,105,110,102,111,114,216,0,0,0,114,215,0,0,0,90, + 10,81,117,101,114,121,86,97,108,117,101,114,76,0,0,0, + 41,6,218,3,99,108,115,114,163,0,0,0,90,12,114,101, + 103,105,115,116,114,121,95,107,101,121,114,20,0,0,0,90, + 4,104,107,101,121,218,8,102,105,108,101,112,97,116,104,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,218,16, + 95,115,101,97,114,99,104,95,114,101,103,105,115,116,114,121, + 45,3,0,0,115,32,0,0,0,6,2,8,1,6,2,6, + 1,16,1,6,255,2,2,12,1,14,1,12,255,4,4,18, + 252,4,4,12,254,6,1,2,255,122,38,87,105,110,100,111, + 119,115,82,101,103,105,115,116,114,121,70,105,110,100,101,114, + 46,95,115,101,97,114,99,104,95,114,101,103,105,115,116,114, + 121,78,99,4,0,0,0,0,0,0,0,0,0,0,0,8, + 0,0,0,8,0,0,0,67,0,0,0,115,120,0,0,0, + 124,0,160,0,124,1,161,1,125,4,124,4,100,0,117,0, + 114,11,100,0,83,0,122,6,116,1,124,4,131,1,1,0, + 87,0,110,10,4,0,116,2,121,27,1,0,1,0,1,0, + 89,0,100,0,83,0,119,0,116,3,131,0,68,0,93,26, + 92,2,125,5,125,6,124,4,160,4,116,5,124,6,131,1, + 161,1,114,57,116,6,106,7,124,1,124,5,124,1,124,4, + 131,2,124,4,100,1,141,3,125,7,124,7,2,0,1,0, + 83,0,113,31,100,0,83,0,41,2,78,114,204,0,0,0, + 41,8,114,223,0,0,0,114,75,0,0,0,114,76,0,0, + 0,114,208,0,0,0,114,58,0,0,0,114,136,0,0,0, + 114,159,0,0,0,218,16,115,112,101,99,95,102,114,111,109, + 95,108,111,97,100,101,114,41,8,114,221,0,0,0,114,163, + 0,0,0,114,65,0,0,0,218,6,116,97,114,103,101,116, + 114,222,0,0,0,114,164,0,0,0,114,212,0,0,0,114, + 210,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,9,102,105,110,100,95,115,112,101,99,60,3, + 0,0,115,34,0,0,0,10,2,8,1,4,1,2,1,12, + 1,12,1,6,1,2,255,14,2,14,1,6,1,8,1,2, + 1,6,254,8,3,2,252,4,255,122,31,87,105,110,100,111, + 119,115,82,101,103,105,115,116,114,121,70,105,110,100,101,114, + 46,102,105,110,100,95,115,112,101,99,99,3,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, + 0,0,0,115,42,0,0,0,116,0,160,1,100,1,116,2, + 161,2,1,0,124,0,160,3,124,1,124,2,161,2,125,3, + 124,3,100,2,117,1,114,19,124,3,106,4,83,0,100,2, + 83,0,41,3,122,106,70,105,110,100,32,109,111,100,117,108, 101,32,110,97,109,101,100,32,105,110,32,116,104,101,32,114, 101,103,105,115,116,114,121,46,10,10,32,32,32,32,32,32, 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,101,120,101,99,95,109,111,100,117,108,101,40,41,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, - 32,32,78,169,2,114,226,0,0,0,114,164,0,0,0,169, - 4,114,216,0,0,0,114,163,0,0,0,114,65,0,0,0, - 114,210,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,11,102,105,110,100,95,109,111,100,117,108, - 101,46,3,0,0,115,8,0,0,0,0,7,12,1,8,1, - 6,2,122,33,87,105,110,100,111,119,115,82,101,103,105,115, - 116,114,121,70,105,110,100,101,114,46,102,105,110,100,95,109, - 111,100,117,108,101,41,2,78,78,41,1,78,41,12,114,149, - 0,0,0,114,148,0,0,0,114,150,0,0,0,114,151,0, - 0,0,114,220,0,0,0,114,219,0,0,0,114,218,0,0, - 0,218,11,99,108,97,115,115,109,101,116,104,111,100,114,217, - 0,0,0,114,223,0,0,0,114,226,0,0,0,114,229,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,214,0,0,0,252,2,0,0,115, - 28,0,0,0,8,2,4,3,2,255,2,4,2,255,2,3, - 4,2,2,1,10,6,2,1,10,14,2,1,12,15,2,1, - 114,214,0,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,48, - 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, - 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100, - 6,100,7,132,0,90,6,100,8,100,9,132,0,90,7,100, - 10,83,0,41,11,218,13,95,76,111,97,100,101,114,66,97, - 115,105,99,115,122,83,66,97,115,101,32,99,108,97,115,115, - 32,111,102,32,99,111,109,109,111,110,32,99,111,100,101,32, - 110,101,101,100,101,100,32,98,121,32,98,111,116,104,32,83, - 111,117,114,99,101,76,111,97,100,101,114,32,97,110,100,10, - 32,32,32,32,83,111,117,114,99,101,108,101,115,115,70,105, - 108,101,76,111,97,100,101,114,46,99,2,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,4,0,0,0,67,0, - 0,0,115,64,0,0,0,116,0,124,0,160,1,124,1,161, - 1,131,1,100,1,25,0,125,2,124,2,160,2,100,2,100, - 1,161,2,100,3,25,0,125,3,124,1,160,3,100,2,161, - 1,100,4,25,0,125,4,124,3,100,5,107,2,111,62,124, - 4,100,5,107,3,83,0,41,6,122,141,67,111,110,99,114, - 101,116,101,32,105,109,112,108,101,109,101,110,116,97,116,105, - 111,110,32,111,102,32,73,110,115,112,101,99,116,76,111,97, - 100,101,114,46,105,115,95,112,97,99,107,97,103,101,32,98, - 121,32,99,104,101,99,107,105,110,103,32,105,102,10,32,32, - 32,32,32,32,32,32,116,104,101,32,112,97,116,104,32,114, - 101,116,117,114,110,101,100,32,98,121,32,103,101,116,95,102, - 105,108,101,110,97,109,101,32,104,97,115,32,97,32,102,105, - 108,101,110,97,109,101,32,111,102,32,39,95,95,105,110,105, - 116,95,95,46,112,121,39,46,114,4,0,0,0,114,96,0, - 0,0,114,0,0,0,0,114,45,0,0,0,218,8,95,95, - 105,110,105,116,95,95,41,4,114,74,0,0,0,114,203,0, - 0,0,114,124,0,0,0,114,103,0,0,0,41,5,114,142, - 0,0,0,114,163,0,0,0,114,119,0,0,0,90,13,102, - 105,108,101,110,97,109,101,95,98,97,115,101,90,9,116,97, - 105,108,95,110,97,109,101,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,206,0,0,0,65,3,0,0,115, - 8,0,0,0,0,3,18,1,16,1,14,1,122,24,95,76, - 111,97,100,101,114,66,97,115,105,99,115,46,105,115,95,112, - 97,99,107,97,103,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,83,0,169,2,122,42,85,115,101,32, - 100,101,102,97,117,108,116,32,115,101,109,97,110,116,105,99, - 115,32,102,111,114,32,109,111,100,117,108,101,32,99,114,101, - 97,116,105,111,110,46,78,114,10,0,0,0,169,2,114,142, - 0,0,0,114,210,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,13,99,114,101,97,116,101,95, - 109,111,100,117,108,101,73,3,0,0,115,2,0,0,0,0, - 1,122,27,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,5, - 0,0,0,67,0,0,0,115,56,0,0,0,124,0,160,0, - 124,1,106,1,161,1,125,2,124,2,100,1,117,0,114,36, - 116,2,100,2,160,3,124,1,106,1,161,1,131,1,130,1, - 116,4,160,5,116,6,124,2,124,1,106,7,161,3,1,0, - 100,1,83,0,41,3,122,19,69,120,101,99,117,116,101,32, - 116,104,101,32,109,111,100,117,108,101,46,78,122,52,99,97, - 110,110,111,116,32,108,111,97,100,32,109,111,100,117,108,101, - 32,123,33,114,125,32,119,104,101,110,32,103,101,116,95,99, - 111,100,101,40,41,32,114,101,116,117,114,110,115,32,78,111, - 110,101,41,8,218,8,103,101,116,95,99,111,100,101,114,149, - 0,0,0,114,141,0,0,0,114,88,0,0,0,114,158,0, - 0,0,218,25,95,99,97,108,108,95,119,105,116,104,95,102, - 114,97,109,101,115,95,114,101,109,111,118,101,100,218,4,101, - 120,101,99,114,155,0,0,0,41,3,114,142,0,0,0,218, - 6,109,111,100,117,108,101,114,188,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,11,101,120,101, - 99,95,109,111,100,117,108,101,76,3,0,0,115,12,0,0, - 0,0,2,12,1,8,1,6,1,4,255,6,2,122,25,95, - 76,111,97,100,101,114,66,97,115,105,99,115,46,101,120,101, - 99,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, - 0,115,12,0,0,0,116,0,160,1,124,0,124,1,161,2, - 83,0,41,1,122,26,84,104,105,115,32,109,111,100,117,108, - 101,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 41,2,114,158,0,0,0,218,17,95,108,111,97,100,95,109, - 111,100,117,108,101,95,115,104,105,109,169,2,114,142,0,0, - 0,114,163,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,11,108,111,97,100,95,109,111,100,117, - 108,101,84,3,0,0,115,2,0,0,0,0,2,122,25,95, - 76,111,97,100,101,114,66,97,115,105,99,115,46,108,111,97, - 100,95,109,111,100,117,108,101,78,41,8,114,149,0,0,0, - 114,148,0,0,0,114,150,0,0,0,114,151,0,0,0,114, - 206,0,0,0,114,235,0,0,0,114,240,0,0,0,114,243, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,231,0,0,0,60,3,0,0, - 115,10,0,0,0,8,2,4,3,8,8,8,3,8,8,114, - 231,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,64,0,0,0,115,74,0, - 0,0,101,0,90,1,100,0,90,2,100,1,100,2,132,0, - 90,3,100,3,100,4,132,0,90,4,100,5,100,6,132,0, - 90,5,100,7,100,8,132,0,90,6,100,9,100,10,132,0, - 90,7,100,11,100,12,156,1,100,13,100,14,132,2,90,8, - 100,15,100,16,132,0,90,9,100,17,83,0,41,18,218,12, - 83,111,117,114,99,101,76,111,97,100,101,114,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,8,0,0,0,116,0,130,1,100,1, - 83,0,41,2,122,165,79,112,116,105,111,110,97,108,32,109, - 101,116,104,111,100,32,116,104,97,116,32,114,101,116,117,114, - 110,115,32,116,104,101,32,109,111,100,105,102,105,99,97,116, - 105,111,110,32,116,105,109,101,32,40,97,110,32,105,110,116, - 41,32,102,111,114,32,116,104,101,10,32,32,32,32,32,32, - 32,32,115,112,101,99,105,102,105,101,100,32,112,97,116,104, - 32,40,97,32,115,116,114,41,46,10,10,32,32,32,32,32, - 32,32,32,82,97,105,115,101,115,32,79,83,69,114,114,111, - 114,32,119,104,101,110,32,116,104,101,32,112,97,116,104,32, - 99,97,110,110,111,116,32,98,101,32,104,97,110,100,108,101, - 100,46,10,32,32,32,32,32,32,32,32,78,41,1,114,76, - 0,0,0,169,2,114,142,0,0,0,114,65,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,10, - 112,97,116,104,95,109,116,105,109,101,91,3,0,0,115,2, - 0,0,0,0,6,122,23,83,111,117,114,99,101,76,111,97, - 100,101,114,46,112,97,116,104,95,109,116,105,109,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, - 0,0,0,67,0,0,0,115,14,0,0,0,100,1,124,0, - 160,0,124,1,161,1,105,1,83,0,41,2,97,158,1,0, - 0,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, - 32,114,101,116,117,114,110,105,110,103,32,97,32,109,101,116, - 97,100,97,116,97,32,100,105,99,116,32,102,111,114,32,116, - 104,101,32,115,112,101,99,105,102,105,101,100,10,32,32,32, - 32,32,32,32,32,112,97,116,104,32,40,97,32,115,116,114, - 41,46,10,10,32,32,32,32,32,32,32,32,80,111,115,115, - 105,98,108,101,32,107,101,121,115,58,10,32,32,32,32,32, - 32,32,32,45,32,39,109,116,105,109,101,39,32,40,109,97, - 110,100,97,116,111,114,121,41,32,105,115,32,116,104,101,32, - 110,117,109,101,114,105,99,32,116,105,109,101,115,116,97,109, - 112,32,111,102,32,108,97,115,116,32,115,111,117,114,99,101, - 10,32,32,32,32,32,32,32,32,32,32,99,111,100,101,32, - 109,111,100,105,102,105,99,97,116,105,111,110,59,10,32,32, - 32,32,32,32,32,32,45,32,39,115,105,122,101,39,32,40, - 111,112,116,105,111,110,97,108,41,32,105,115,32,116,104,101, - 32,115,105,122,101,32,105,110,32,98,121,116,101,115,32,111, - 102,32,116,104,101,32,115,111,117,114,99,101,32,99,111,100, - 101,46,10,10,32,32,32,32,32,32,32,32,73,109,112,108, - 101,109,101,110,116,105,110,103,32,116,104,105,115,32,109,101, - 116,104,111,100,32,97,108,108,111,119,115,32,116,104,101,32, - 108,111,97,100,101,114,32,116,111,32,114,101,97,100,32,98, - 121,116,101,99,111,100,101,32,102,105,108,101,115,46,10,32, - 32,32,32,32,32,32,32,82,97,105,115,101,115,32,79,83, - 69,114,114,111,114,32,119,104,101,110,32,116,104,101,32,112, - 97,116,104,32,99,97,110,110,111,116,32,98,101,32,104,97, - 110,100,108,101,100,46,10,32,32,32,32,32,32,32,32,114, - 193,0,0,0,41,1,114,246,0,0,0,114,245,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 10,112,97,116,104,95,115,116,97,116,115,99,3,0,0,115, - 2,0,0,0,0,12,122,23,83,111,117,114,99,101,76,111, - 97,100,101,114,46,112,97,116,104,95,115,116,97,116,115,99, - 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, - 4,0,0,0,67,0,0,0,115,12,0,0,0,124,0,160, - 0,124,2,124,3,161,2,83,0,41,1,122,228,79,112,116, - 105,111,110,97,108,32,109,101,116,104,111,100,32,119,104,105, - 99,104,32,119,114,105,116,101,115,32,100,97,116,97,32,40, - 98,121,116,101,115,41,32,116,111,32,97,32,102,105,108,101, - 32,112,97,116,104,32,40,97,32,115,116,114,41,46,10,10, - 32,32,32,32,32,32,32,32,73,109,112,108,101,109,101,110, - 116,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100, - 32,97,108,108,111,119,115,32,102,111,114,32,116,104,101,32, - 119,114,105,116,105,110,103,32,111,102,32,98,121,116,101,99, - 111,100,101,32,102,105,108,101,115,46,10,10,32,32,32,32, - 32,32,32,32,84,104,101,32,115,111,117,114,99,101,32,112, - 97,116,104,32,105,115,32,110,101,101,100,101,100,32,105,110, - 32,111,114,100,101,114,32,116,111,32,99,111,114,114,101,99, - 116,108,121,32,116,114,97,110,115,102,101,114,32,112,101,114, - 109,105,115,115,105,111,110,115,10,32,32,32,32,32,32,32, - 32,41,1,218,8,115,101,116,95,100,97,116,97,41,4,114, - 142,0,0,0,114,133,0,0,0,90,10,99,97,99,104,101, - 95,112,97,116,104,114,43,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,15,95,99,97,99,104, - 101,95,98,121,116,101,99,111,100,101,113,3,0,0,115,2, - 0,0,0,0,8,122,28,83,111,117,114,99,101,76,111,97, - 100,101,114,46,95,99,97,99,104,101,95,98,121,116,101,99, - 111,100,101,99,3,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, - 0,100,1,83,0,41,2,122,150,79,112,116,105,111,110,97, - 108,32,109,101,116,104,111,100,32,119,104,105,99,104,32,119, - 114,105,116,101,115,32,100,97,116,97,32,40,98,121,116,101, - 115,41,32,116,111,32,97,32,102,105,108,101,32,112,97,116, - 104,32,40,97,32,115,116,114,41,46,10,10,32,32,32,32, - 32,32,32,32,73,109,112,108,101,109,101,110,116,105,110,103, - 32,116,104,105,115,32,109,101,116,104,111,100,32,97,108,108, - 111,119,115,32,102,111,114,32,116,104,101,32,119,114,105,116, - 105,110,103,32,111,102,32,98,121,116,101,99,111,100,101,32, - 102,105,108,101,115,46,10,32,32,32,32,32,32,32,32,78, - 114,10,0,0,0,41,3,114,142,0,0,0,114,65,0,0, - 0,114,43,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,248,0,0,0,123,3,0,0,115,2, - 0,0,0,0,1,122,21,83,111,117,114,99,101,76,111,97, - 100,101,114,46,115,101,116,95,100,97,116,97,99,2,0,0, - 0,0,0,0,0,0,0,0,0,5,0,0,0,10,0,0, - 0,67,0,0,0,115,84,0,0,0,124,0,160,0,124,1, - 161,1,125,2,122,14,124,0,160,1,124,2,161,1,125,3, - 87,0,110,50,4,0,116,2,121,74,1,0,125,4,1,0, - 122,26,116,3,100,1,124,1,100,2,141,2,124,4,130,2, - 87,0,89,0,100,3,125,4,126,4,110,10,100,3,125,4, - 126,4,48,0,48,0,116,4,124,3,131,1,83,0,41,4, - 122,52,67,111,110,99,114,101,116,101,32,105,109,112,108,101, - 109,101,110,116,97,116,105,111,110,32,111,102,32,73,110,115, - 112,101,99,116,76,111,97,100,101,114,46,103,101,116,95,115, - 111,117,114,99,101,46,122,39,115,111,117,114,99,101,32,110, - 111,116,32,97,118,97,105,108,97,98,108,101,32,116,104,114, - 111,117,103,104,32,103,101,116,95,100,97,116,97,40,41,114, - 139,0,0,0,78,41,5,114,203,0,0,0,218,8,103,101, - 116,95,100,97,116,97,114,76,0,0,0,114,141,0,0,0, - 114,200,0,0,0,41,5,114,142,0,0,0,114,163,0,0, - 0,114,65,0,0,0,114,198,0,0,0,218,3,101,120,99, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 10,103,101,116,95,115,111,117,114,99,101,130,3,0,0,115, - 20,0,0,0,0,2,10,1,2,1,14,1,14,1,4,1, - 2,255,4,1,2,255,24,2,122,23,83,111,117,114,99,101, - 76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99, - 101,114,129,0,0,0,41,1,218,9,95,111,112,116,105,109, - 105,122,101,99,3,0,0,0,0,0,0,0,1,0,0,0, - 4,0,0,0,8,0,0,0,67,0,0,0,115,22,0,0, - 0,116,0,106,1,116,2,124,1,124,2,100,1,100,2,124, - 3,100,3,141,6,83,0,41,4,122,130,82,101,116,117,114, - 110,32,116,104,101,32,99,111,100,101,32,111,98,106,101,99, - 116,32,99,111,109,112,105,108,101,100,32,102,114,111,109,32, - 115,111,117,114,99,101,46,10,10,32,32,32,32,32,32,32, - 32,84,104,101,32,39,100,97,116,97,39,32,97,114,103,117, - 109,101,110,116,32,99,97,110,32,98,101,32,97,110,121,32, - 111,98,106,101,99,116,32,116,121,112,101,32,116,104,97,116, - 32,99,111,109,112,105,108,101,40,41,32,115,117,112,112,111, - 114,116,115,46,10,32,32,32,32,32,32,32,32,114,238,0, - 0,0,84,41,2,218,12,100,111,110,116,95,105,110,104,101, - 114,105,116,114,107,0,0,0,41,3,114,158,0,0,0,114, - 237,0,0,0,218,7,99,111,109,112,105,108,101,41,4,114, - 142,0,0,0,114,43,0,0,0,114,65,0,0,0,114,253, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,14,115,111,117,114,99,101,95,116,111,95,99,111, - 100,101,140,3,0,0,115,6,0,0,0,0,5,12,1,4, - 255,122,27,83,111,117,114,99,101,76,111,97,100,101,114,46, - 115,111,117,114,99,101,95,116,111,95,99,111,100,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,9, - 0,0,0,67,0,0,0,115,24,2,0,0,124,0,160,0, - 124,1,161,1,125,2,100,1,125,3,100,1,125,4,100,1, - 125,5,100,2,125,6,100,3,125,7,122,12,116,1,124,2, - 131,1,125,8,87,0,110,24,4,0,116,2,121,66,1,0, - 1,0,1,0,100,1,125,8,89,0,144,1,110,42,48,0, - 122,14,124,0,160,3,124,2,161,1,125,9,87,0,110,20, - 4,0,116,4,121,102,1,0,1,0,1,0,89,0,144,1, - 110,6,48,0,116,5,124,9,100,4,25,0,131,1,125,3, - 122,14,124,0,160,6,124,8,161,1,125,10,87,0,110,18, - 4,0,116,4,121,148,1,0,1,0,1,0,89,0,110,216, - 48,0,124,1,124,8,100,5,156,2,125,11,122,148,116,7, - 124,10,124,1,124,11,131,3,125,12,116,8,124,10,131,1, - 100,6,100,1,133,2,25,0,125,13,124,12,100,7,64,0, - 100,8,107,3,125,6,124,6,144,1,114,30,124,12,100,9, - 64,0,100,8,107,3,125,7,116,9,106,10,100,10,107,3, - 144,1,114,50,124,7,115,248,116,9,106,10,100,11,107,2, - 144,1,114,50,124,0,160,6,124,2,161,1,125,4,116,9, - 160,11,116,12,124,4,161,2,125,5,116,13,124,10,124,5, - 124,1,124,11,131,4,1,0,110,20,116,14,124,10,124,3, - 124,9,100,12,25,0,124,1,124,11,131,5,1,0,87,0, - 110,24,4,0,116,15,116,16,102,2,144,1,121,76,1,0, - 1,0,1,0,89,0,110,32,48,0,116,17,160,18,100,13, - 124,8,124,2,161,3,1,0,116,19,124,13,124,1,124,8, - 124,2,100,14,141,4,83,0,124,4,100,1,117,0,144,1, - 114,128,124,0,160,6,124,2,161,1,125,4,124,0,160,20, - 124,4,124,2,161,2,125,14,116,17,160,18,100,15,124,2, - 161,2,1,0,116,21,106,22,144,2,115,20,124,8,100,1, - 117,1,144,2,114,20,124,3,100,1,117,1,144,2,114,20, - 124,6,144,1,114,220,124,5,100,1,117,0,144,1,114,206, - 116,9,160,11,124,4,161,1,125,5,116,23,124,14,124,5, - 124,7,131,3,125,10,110,16,116,24,124,14,124,3,116,25, - 124,4,131,1,131,3,125,10,122,18,124,0,160,26,124,2, - 124,8,124,10,161,3,1,0,87,0,110,20,4,0,116,2, - 144,2,121,18,1,0,1,0,1,0,89,0,110,2,48,0, - 124,14,83,0,41,16,122,190,67,111,110,99,114,101,116,101, - 32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,32, - 111,102,32,73,110,115,112,101,99,116,76,111,97,100,101,114, - 46,103,101,116,95,99,111,100,101,46,10,10,32,32,32,32, - 32,32,32,32,82,101,97,100,105,110,103,32,111,102,32,98, - 121,116,101,99,111,100,101,32,114,101,113,117,105,114,101,115, - 32,112,97,116,104,95,115,116,97,116,115,32,116,111,32,98, - 101,32,105,109,112,108,101,109,101,110,116,101,100,46,32,84, - 111,32,119,114,105,116,101,10,32,32,32,32,32,32,32,32, - 98,121,116,101,99,111,100,101,44,32,115,101,116,95,100,97, - 116,97,32,109,117,115,116,32,97,108,115,111,32,98,101,32, - 105,109,112,108,101,109,101,110,116,101,100,46,10,10,32,32, - 32,32,32,32,32,32,78,70,84,114,193,0,0,0,114,183, - 0,0,0,114,169,0,0,0,114,4,0,0,0,114,0,0, - 0,0,114,45,0,0,0,90,5,110,101,118,101,114,90,6, - 97,108,119,97,121,115,218,4,115,105,122,101,122,13,123,125, - 32,109,97,116,99,104,101,115,32,123,125,41,3,114,140,0, - 0,0,114,131,0,0,0,114,133,0,0,0,122,19,99,111, - 100,101,32,111,98,106,101,99,116,32,102,114,111,109,32,123, - 125,41,27,114,203,0,0,0,114,120,0,0,0,114,106,0, - 0,0,114,247,0,0,0,114,76,0,0,0,114,36,0,0, - 0,114,250,0,0,0,114,176,0,0,0,218,10,109,101,109, - 111,114,121,118,105,101,119,114,187,0,0,0,90,21,99,104, - 101,99,107,95,104,97,115,104,95,98,97,115,101,100,95,112, - 121,99,115,114,181,0,0,0,218,17,95,82,65,87,95,77, - 65,71,73,67,95,78,85,77,66,69,82,114,182,0,0,0, - 114,180,0,0,0,114,141,0,0,0,114,174,0,0,0,114, - 158,0,0,0,114,173,0,0,0,114,189,0,0,0,114,0, - 1,0,0,114,21,0,0,0,218,19,100,111,110,116,95,119, - 114,105,116,101,95,98,121,116,101,99,111,100,101,114,195,0, - 0,0,114,194,0,0,0,114,6,0,0,0,114,249,0,0, - 0,41,15,114,142,0,0,0,114,163,0,0,0,114,133,0, - 0,0,114,178,0,0,0,114,198,0,0,0,114,181,0,0, - 0,90,10,104,97,115,104,95,98,97,115,101,100,90,12,99, - 104,101,99,107,95,115,111,117,114,99,101,114,131,0,0,0, - 218,2,115,116,114,43,0,0,0,114,175,0,0,0,114,22, - 0,0,0,90,10,98,121,116,101,115,95,100,97,116,97,90, - 11,99,111,100,101,95,111,98,106,101,99,116,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,236,0,0,0, - 148,3,0,0,115,152,0,0,0,0,7,10,1,4,1,4, - 1,4,1,4,1,4,1,2,1,12,1,12,1,12,2,2, - 1,14,1,12,1,8,2,12,1,2,1,14,1,12,1,6, - 3,2,1,2,254,6,4,2,1,12,1,16,1,12,1,6, - 1,12,1,12,1,2,255,2,2,8,254,4,3,10,1,4, - 1,2,1,2,254,4,4,8,1,2,255,6,3,2,1,2, - 1,2,1,6,1,2,1,2,251,8,7,18,1,6,2,8, - 1,2,255,4,2,6,1,2,1,2,254,6,3,10,1,10, - 1,12,1,12,1,18,1,6,255,4,2,6,1,10,1,10, - 1,14,2,6,1,6,255,4,2,2,1,18,1,14,1,6, - 1,122,21,83,111,117,114,99,101,76,111,97,100,101,114,46, - 103,101,116,95,99,111,100,101,78,41,10,114,149,0,0,0, - 114,148,0,0,0,114,150,0,0,0,114,246,0,0,0,114, - 247,0,0,0,114,249,0,0,0,114,248,0,0,0,114,252, - 0,0,0,114,0,1,0,0,114,236,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,244,0,0,0,89,3,0,0,115,14,0,0,0,8, - 2,8,8,8,14,8,10,8,7,8,10,14,8,114,244,0, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,0,0,0,0,115,124,0,0,0, - 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, - 132,0,90,4,100,4,100,5,132,0,90,5,100,6,100,7, - 132,0,90,6,101,7,135,0,102,1,100,8,100,9,132,8, - 131,1,90,8,101,7,100,10,100,11,132,0,131,1,90,9, - 100,12,100,13,132,0,90,10,101,7,100,14,100,15,132,0, - 131,1,90,11,100,16,100,17,132,0,90,12,100,18,100,19, - 132,0,90,13,100,20,100,21,132,0,90,14,100,22,100,23, - 132,0,90,15,135,0,4,0,90,16,83,0,41,24,218,10, - 70,105,108,101,76,111,97,100,101,114,122,103,66,97,115,101, - 32,102,105,108,101,32,108,111,97,100,101,114,32,99,108,97, - 115,115,32,119,104,105,99,104,32,105,109,112,108,101,109,101, - 110,116,115,32,116,104,101,32,108,111,97,100,101,114,32,112, - 114,111,116,111,99,111,108,32,109,101,116,104,111,100,115,32, - 116,104,97,116,10,32,32,32,32,114,101,113,117,105,114,101, - 32,102,105,108,101,32,115,121,115,116,101,109,32,117,115,97, - 103,101,46,99,3,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, - 0,124,1,124,0,95,0,124,2,124,0,95,1,100,1,83, - 0,41,2,122,75,67,97,99,104,101,32,116,104,101,32,109, - 111,100,117,108,101,32,110,97,109,101,32,97,110,100,32,116, - 104,101,32,112,97,116,104,32,116,111,32,116,104,101,32,102, - 105,108,101,32,102,111,117,110,100,32,98,121,32,116,104,101, - 10,32,32,32,32,32,32,32,32,102,105,110,100,101,114,46, - 78,114,183,0,0,0,41,3,114,142,0,0,0,114,163,0, - 0,0,114,65,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,232,0,0,0,238,3,0,0,115, - 4,0,0,0,0,3,6,1,122,19,70,105,108,101,76,111, - 97,100,101,114,46,95,95,105,110,105,116,95,95,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0, - 0,0,67,0,0,0,115,24,0,0,0,124,0,106,0,124, - 1,106,0,107,2,111,22,124,0,106,1,124,1,106,1,107, - 2,83,0,114,69,0,0,0,169,2,218,9,95,95,99,108, - 97,115,115,95,95,114,155,0,0,0,169,2,114,142,0,0, - 0,90,5,111,116,104,101,114,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,6,95,95,101,113,95,95,244, - 3,0,0,115,6,0,0,0,0,1,12,1,10,255,122,17, - 70,105,108,101,76,111,97,100,101,114,46,95,95,101,113,95, - 95,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,3,0,0,0,67,0,0,0,115,20,0,0,0,116, - 0,124,0,106,1,131,1,116,0,124,0,106,2,131,1,65, - 0,83,0,114,69,0,0,0,169,3,218,4,104,97,115,104, - 114,140,0,0,0,114,65,0,0,0,169,1,114,142,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,8,95,95,104,97,115,104,95,95,248,3,0,0,115,2, - 0,0,0,0,1,122,19,70,105,108,101,76,111,97,100,101, - 114,46,95,95,104,97,115,104,95,95,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,3, - 0,0,0,115,16,0,0,0,116,0,116,1,124,0,131,2, - 160,2,124,1,161,1,83,0,41,1,122,100,76,111,97,100, - 32,97,32,109,111,100,117,108,101,32,102,114,111,109,32,97, - 32,102,105,108,101,46,10,10,32,32,32,32,32,32,32,32, - 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, - 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, - 101,120,101,99,95,109,111,100,117,108,101,40,41,32,105,110, + 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, - 41,3,218,5,115,117,112,101,114,114,6,1,0,0,114,243, - 0,0,0,114,242,0,0,0,169,1,114,8,1,0,0,114, - 10,0,0,0,114,11,0,0,0,114,243,0,0,0,251,3, - 0,0,115,2,0,0,0,0,10,122,22,70,105,108,101,76, - 111,97,100,101,114,46,108,111,97,100,95,109,111,100,117,108, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,1,0,0,0,67,0,0,0,115,6,0,0,0,124, - 0,106,0,83,0,169,1,122,58,82,101,116,117,114,110,32, - 116,104,101,32,112,97,116,104,32,116,111,32,116,104,101,32, - 115,111,117,114,99,101,32,102,105,108,101,32,97,115,32,102, - 111,117,110,100,32,98,121,32,116,104,101,32,102,105,110,100, - 101,114,46,114,71,0,0,0,114,242,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,203,0,0, - 0,7,4,0,0,115,2,0,0,0,0,3,122,23,70,105, - 108,101,76,111,97,100,101,114,46,103,101,116,95,102,105,108, - 101,110,97,109,101,99,2,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,8,0,0,0,67,0,0,0,115,126, - 0,0,0,116,0,124,0,116,1,116,2,102,2,131,2,114, - 70,116,3,160,4,116,5,124,1,131,1,161,1,143,24,125, - 2,124,2,160,6,161,0,87,0,2,0,100,1,4,0,4, - 0,131,3,1,0,83,0,49,0,115,58,48,0,1,0,1, - 0,1,0,89,0,1,0,110,52,116,3,160,7,124,1,100, - 2,161,2,143,24,125,2,124,2,160,6,161,0,87,0,2, - 0,100,1,4,0,4,0,131,3,1,0,83,0,49,0,115, - 112,48,0,1,0,1,0,1,0,89,0,1,0,100,1,83, - 0,41,3,122,39,82,101,116,117,114,110,32,116,104,101,32, - 100,97,116,97,32,102,114,111,109,32,112,97,116,104,32,97, - 115,32,114,97,119,32,98,121,116,101,115,46,78,218,1,114, - 41,8,114,185,0,0,0,114,244,0,0,0,218,19,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,114,90,0,0,0,90,9,111,112,101,110,95,99,111,100, - 101,114,108,0,0,0,90,4,114,101,97,100,114,91,0,0, - 0,41,3,114,142,0,0,0,114,65,0,0,0,114,93,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,250,0,0,0,12,4,0,0,115,10,0,0,0,0, - 2,14,1,16,1,40,2,14,1,122,19,70,105,108,101,76, - 111,97,100,101,114,46,103,101,116,95,100,97,116,97,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, - 0,0,0,67,0,0,0,115,18,0,0,0,124,0,160,0, - 124,1,161,1,114,14,124,0,83,0,100,0,83,0,114,69, - 0,0,0,41,1,114,206,0,0,0,169,2,114,142,0,0, - 0,114,239,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,19,103,101,116,95,114,101,115,111,117, - 114,99,101,95,114,101,97,100,101,114,23,4,0,0,115,6, - 0,0,0,0,2,10,1,4,1,122,30,70,105,108,101,76, - 111,97,100,101,114,46,103,101,116,95,114,101,115,111,117,114, - 99,101,95,114,101,97,100,101,114,99,2,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, - 0,0,115,32,0,0,0,116,0,116,1,124,0,106,2,131, - 1,100,1,25,0,124,1,131,2,125,2,116,3,160,4,124, - 2,100,2,161,2,83,0,41,3,78,114,0,0,0,0,114, - 18,1,0,0,41,5,114,67,0,0,0,114,74,0,0,0, - 114,65,0,0,0,114,90,0,0,0,114,91,0,0,0,169, - 3,114,142,0,0,0,90,8,114,101,115,111,117,114,99,101, - 114,65,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,13,111,112,101,110,95,114,101,115,111,117, - 114,99,101,29,4,0,0,115,4,0,0,0,0,1,20,1, - 122,24,70,105,108,101,76,111,97,100,101,114,46,111,112,101, - 110,95,114,101,115,111,117,114,99,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,124,0,160,0,124,1,161,1, - 115,14,116,1,130,1,116,2,116,3,124,0,106,4,131,1, - 100,1,25,0,124,1,131,2,125,2,124,2,83,0,169,2, - 78,114,0,0,0,0,41,5,218,11,105,115,95,114,101,115, - 111,117,114,99,101,218,17,70,105,108,101,78,111,116,70,111, - 117,110,100,69,114,114,111,114,114,67,0,0,0,114,74,0, - 0,0,114,65,0,0,0,114,22,1,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,13,114,101,115, - 111,117,114,99,101,95,112,97,116,104,33,4,0,0,115,8, - 0,0,0,0,1,10,1,4,1,20,1,122,24,70,105,108, - 101,76,111,97,100,101,114,46,114,101,115,111,117,114,99,101, - 95,112,97,116,104,99,2,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,40, - 0,0,0,116,0,124,1,118,0,114,12,100,1,83,0,116, - 1,116,2,124,0,106,3,131,1,100,2,25,0,124,1,131, - 2,125,2,116,4,124,2,131,1,83,0,41,3,78,70,114, - 0,0,0,0,41,5,114,59,0,0,0,114,67,0,0,0, - 114,74,0,0,0,114,65,0,0,0,114,80,0,0,0,169, - 3,114,142,0,0,0,114,140,0,0,0,114,65,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 25,1,0,0,39,4,0,0,115,8,0,0,0,0,1,8, - 1,4,1,20,1,122,22,70,105,108,101,76,111,97,100,101, - 114,46,105,115,95,114,101,115,111,117,114,99,101,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,0, - 0,0,67,0,0,0,115,24,0,0,0,116,0,116,1,160, - 2,116,3,124,0,106,4,131,1,100,1,25,0,161,1,131, - 1,83,0,114,24,1,0,0,41,5,218,4,105,116,101,114, - 114,24,0,0,0,218,7,108,105,115,116,100,105,114,114,74, - 0,0,0,114,65,0,0,0,114,13,1,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,8,99,111, - 110,116,101,110,116,115,45,4,0,0,115,2,0,0,0,0, - 1,122,19,70,105,108,101,76,111,97,100,101,114,46,99,111, - 110,116,101,110,116,115,41,17,114,149,0,0,0,114,148,0, - 0,0,114,150,0,0,0,114,151,0,0,0,114,232,0,0, - 0,114,10,1,0,0,114,14,1,0,0,114,160,0,0,0, - 114,243,0,0,0,114,203,0,0,0,114,250,0,0,0,114, - 21,1,0,0,114,23,1,0,0,114,27,1,0,0,114,25, - 1,0,0,114,31,1,0,0,90,13,95,95,99,108,97,115, - 115,99,101,108,108,95,95,114,10,0,0,0,114,10,0,0, - 0,114,16,1,0,0,114,11,0,0,0,114,6,1,0,0, - 233,3,0,0,115,30,0,0,0,8,2,4,3,8,6,8, - 4,8,3,2,1,14,11,2,1,10,4,8,11,2,1,10, - 5,8,4,8,6,8,6,114,6,1,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,64,0,0,0,115,46,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4, - 100,5,132,0,90,5,100,6,100,7,156,1,100,8,100,9, - 132,2,90,6,100,10,83,0,41,11,218,16,83,111,117,114, - 99,101,70,105,108,101,76,111,97,100,101,114,122,62,67,111, - 110,99,114,101,116,101,32,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,32,111,102,32,83,111,117,114,99,101,76, - 111,97,100,101,114,32,117,115,105,110,103,32,116,104,101,32, - 102,105,108,101,32,115,121,115,116,101,109,46,99,2,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, - 0,67,0,0,0,115,22,0,0,0,116,0,124,1,131,1, - 125,2,124,2,106,1,124,2,106,2,100,1,156,2,83,0, - 41,2,122,33,82,101,116,117,114,110,32,116,104,101,32,109, - 101,116,97,100,97,116,97,32,102,111,114,32,116,104,101,32, - 112,97,116,104,46,41,2,114,193,0,0,0,114,1,1,0, - 0,41,3,114,75,0,0,0,218,8,115,116,95,109,116,105, - 109,101,90,7,115,116,95,115,105,122,101,41,3,114,142,0, - 0,0,114,65,0,0,0,114,5,1,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,247,0,0,0, - 53,4,0,0,115,4,0,0,0,0,2,8,1,122,27,83, - 111,117,114,99,101,70,105,108,101,76,111,97,100,101,114,46, - 112,97,116,104,95,115,116,97,116,115,99,4,0,0,0,0, - 0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,67, - 0,0,0,115,24,0,0,0,116,0,124,1,131,1,125,4, - 124,0,106,1,124,2,124,3,124,4,100,1,141,3,83,0, - 41,2,78,169,1,218,5,95,109,111,100,101,41,2,114,138, - 0,0,0,114,248,0,0,0,41,5,114,142,0,0,0,114, - 133,0,0,0,114,131,0,0,0,114,43,0,0,0,114,78, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,249,0,0,0,58,4,0,0,115,4,0,0,0, - 0,2,8,1,122,32,83,111,117,114,99,101,70,105,108,101, - 76,111,97,100,101,114,46,95,99,97,99,104,101,95,98,121, - 116,101,99,111,100,101,114,86,0,0,0,114,34,1,0,0, - 99,3,0,0,0,0,0,0,0,1,0,0,0,9,0,0, - 0,11,0,0,0,67,0,0,0,115,252,0,0,0,116,0, - 124,1,131,1,92,2,125,4,125,5,103,0,125,6,124,4, - 114,52,116,1,124,4,131,1,115,52,116,0,124,4,131,1, - 92,2,125,4,125,7,124,6,160,2,124,7,161,1,1,0, - 113,16,116,3,124,6,131,1,68,0,93,104,125,7,116,4, - 124,4,124,7,131,2,125,4,122,14,116,5,160,6,124,4, - 161,1,1,0,87,0,113,60,4,0,116,7,121,110,1,0, - 1,0,1,0,89,0,113,60,89,0,113,60,4,0,116,8, - 121,162,1,0,125,8,1,0,122,30,116,9,160,10,100,1, - 124,4,124,8,161,3,1,0,87,0,89,0,100,2,125,8, - 126,8,1,0,100,2,83,0,100,2,125,8,126,8,48,0, - 48,0,113,60,122,28,116,11,124,1,124,2,124,3,131,3, - 1,0,116,9,160,10,100,3,124,1,161,2,1,0,87,0, - 110,52,4,0,116,8,144,0,121,246,1,0,125,8,1,0, - 122,26,116,9,160,10,100,1,124,1,124,8,161,3,1,0, - 87,0,89,0,100,2,125,8,126,8,110,10,100,2,125,8, - 126,8,48,0,48,0,100,2,83,0,41,4,122,27,87,114, - 105,116,101,32,98,121,116,101,115,32,100,97,116,97,32,116, - 111,32,97,32,102,105,108,101,46,122,27,99,111,117,108,100, - 32,110,111,116,32,99,114,101,97,116,101,32,123,33,114,125, - 58,32,123,33,114,125,78,122,12,99,114,101,97,116,101,100, - 32,123,33,114,125,41,12,114,74,0,0,0,114,82,0,0, - 0,114,61,0,0,0,218,8,114,101,118,101,114,115,101,100, - 114,67,0,0,0,114,24,0,0,0,90,5,109,107,100,105, - 114,218,15,70,105,108,101,69,120,105,115,116,115,69,114,114, - 111,114,114,76,0,0,0,114,158,0,0,0,114,173,0,0, - 0,114,94,0,0,0,41,9,114,142,0,0,0,114,65,0, - 0,0,114,43,0,0,0,114,35,1,0,0,218,6,112,97, - 114,101,110,116,114,119,0,0,0,114,63,0,0,0,114,68, - 0,0,0,114,251,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,248,0,0,0,63,4,0,0, - 115,46,0,0,0,0,2,12,1,4,2,12,1,12,1,12, - 2,12,1,10,1,2,1,14,1,12,2,8,1,14,3,6, - 1,4,255,4,2,28,1,2,1,12,1,16,1,16,2,8, - 1,2,255,122,25,83,111,117,114,99,101,70,105,108,101,76, - 111,97,100,101,114,46,115,101,116,95,100,97,116,97,78,41, - 7,114,149,0,0,0,114,148,0,0,0,114,150,0,0,0, - 114,151,0,0,0,114,247,0,0,0,114,249,0,0,0,114, - 248,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,32,1,0,0,49,4,0, - 0,115,8,0,0,0,8,2,4,2,8,5,8,5,114,32, - 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,64,0,0,0,115,32,0,0, - 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, - 3,132,0,90,4,100,4,100,5,132,0,90,5,100,6,83, - 0,41,7,218,20,83,111,117,114,99,101,108,101,115,115,70, - 105,108,101,76,111,97,100,101,114,122,45,76,111,97,100,101, - 114,32,119,104,105,99,104,32,104,97,110,100,108,101,115,32, - 115,111,117,114,99,101,108,101,115,115,32,102,105,108,101,32, - 105,109,112,111,114,116,115,46,99,2,0,0,0,0,0,0, - 0,0,0,0,0,5,0,0,0,5,0,0,0,67,0,0, - 0,115,68,0,0,0,124,0,160,0,124,1,161,1,125,2, - 124,0,160,1,124,2,161,1,125,3,124,1,124,2,100,1, - 156,2,125,4,116,2,124,3,124,1,124,4,131,3,1,0, - 116,3,116,4,124,3,131,1,100,2,100,0,133,2,25,0, - 124,1,124,2,100,3,141,3,83,0,41,4,78,114,183,0, - 0,0,114,169,0,0,0,41,2,114,140,0,0,0,114,131, - 0,0,0,41,5,114,203,0,0,0,114,250,0,0,0,114, - 176,0,0,0,114,189,0,0,0,114,2,1,0,0,41,5, - 114,142,0,0,0,114,163,0,0,0,114,65,0,0,0,114, - 43,0,0,0,114,175,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,236,0,0,0,98,4,0, - 0,115,22,0,0,0,0,1,10,1,10,4,2,1,2,254, - 6,4,12,1,2,1,14,1,2,1,2,253,122,29,83,111, - 117,114,99,101,108,101,115,115,70,105,108,101,76,111,97,100, - 101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122, - 39,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, - 116,104,101,114,101,32,105,115,32,110,111,32,115,111,117,114, - 99,101,32,99,111,100,101,46,78,114,10,0,0,0,114,242, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,252,0,0,0,114,4,0,0,115,2,0,0,0, - 0,2,122,31,83,111,117,114,99,101,108,101,115,115,70,105, - 108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,78,41,6,114,149,0,0,0,114,148,0,0,0, - 114,150,0,0,0,114,151,0,0,0,114,236,0,0,0,114, - 252,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,39,1,0,0,94,4,0, - 0,115,6,0,0,0,8,2,4,2,8,16,114,39,1,0, + 122,112,87,105,110,100,111,119,115,82,101,103,105,115,116,114, + 121,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, + 117,108,101,40,41,32,105,115,32,100,101,112,114,101,99,97, + 116,101,100,32,97,110,100,32,115,108,97,116,101,100,32,102, + 111,114,32,114,101,109,111,118,97,108,32,105,110,32,80,121, + 116,104,111,110,32,51,46,49,50,59,32,117,115,101,32,102, + 105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,101, + 97,100,78,169,5,114,99,0,0,0,114,100,0,0,0,114, + 101,0,0,0,114,226,0,0,0,114,164,0,0,0,169,4, + 114,221,0,0,0,114,163,0,0,0,114,65,0,0,0,114, + 210,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,11,102,105,110,100,95,109,111,100,117,108,101, + 76,3,0,0,115,14,0,0,0,6,7,2,2,4,254,12, + 3,8,1,6,1,4,2,122,33,87,105,110,100,111,119,115, + 82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,102, + 105,110,100,95,109,111,100,117,108,101,169,2,78,78,114,69, + 0,0,0,41,15,114,150,0,0,0,114,149,0,0,0,114, + 151,0,0,0,114,152,0,0,0,114,219,0,0,0,114,218, + 0,0,0,218,11,95,77,83,95,87,73,78,68,79,87,83, + 218,18,69,88,84,69,78,83,73,79,78,95,83,85,70,70, + 73,88,69,83,114,217,0,0,0,218,12,115,116,97,116,105, + 99,109,101,116,104,111,100,114,216,0,0,0,218,11,99,108, + 97,115,115,109,101,116,104,111,100,114,223,0,0,0,114,226, + 0,0,0,114,229,0,0,0,114,7,0,0,0,114,7,0, + 0,0,114,7,0,0,0,114,8,0,0,0,114,214,0,0, + 0,26,3,0,0,115,30,0,0,0,8,0,4,2,2,3, + 2,255,2,4,2,255,12,3,2,2,10,1,2,6,10,1, + 2,14,12,1,2,15,16,1,114,214,0,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,64,0,0,0,115,48,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, + 4,100,5,132,0,90,5,100,6,100,7,132,0,90,6,100, + 8,100,9,132,0,90,7,100,10,83,0,41,11,218,13,95, + 76,111,97,100,101,114,66,97,115,105,99,115,122,83,66,97, + 115,101,32,99,108,97,115,115,32,111,102,32,99,111,109,109, + 111,110,32,99,111,100,101,32,110,101,101,100,101,100,32,98, + 121,32,98,111,116,104,32,83,111,117,114,99,101,76,111,97, + 100,101,114,32,97,110,100,10,32,32,32,32,83,111,117,114, + 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, + 46,99,2,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,4,0,0,0,67,0,0,0,115,64,0,0,0,116, + 0,124,0,160,1,124,1,161,1,131,1,100,1,25,0,125, + 2,124,2,160,2,100,2,100,1,161,2,100,3,25,0,125, + 3,124,1,160,3,100,2,161,1,100,4,25,0,125,4,124, + 3,100,5,107,2,111,31,124,4,100,5,107,3,83,0,41, + 6,122,141,67,111,110,99,114,101,116,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,73,110, + 115,112,101,99,116,76,111,97,100,101,114,46,105,115,95,112, + 97,99,107,97,103,101,32,98,121,32,99,104,101,99,107,105, + 110,103,32,105,102,10,32,32,32,32,32,32,32,32,116,104, + 101,32,112,97,116,104,32,114,101,116,117,114,110,101,100,32, + 98,121,32,103,101,116,95,102,105,108,101,110,97,109,101,32, + 104,97,115,32,97,32,102,105,108,101,110,97,109,101,32,111, + 102,32,39,95,95,105,110,105,116,95,95,46,112,121,39,46, + 114,3,0,0,0,114,97,0,0,0,114,0,0,0,0,114, + 44,0,0,0,218,8,95,95,105,110,105,116,95,95,41,4, + 114,74,0,0,0,114,203,0,0,0,114,125,0,0,0,114, + 104,0,0,0,41,5,114,143,0,0,0,114,163,0,0,0, + 114,120,0,0,0,90,13,102,105,108,101,110,97,109,101,95, + 98,97,115,101,90,9,116,97,105,108,95,110,97,109,101,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,206, + 0,0,0,98,3,0,0,115,8,0,0,0,18,3,16,1, + 14,1,16,1,122,24,95,76,111,97,100,101,114,66,97,115, + 105,99,115,46,105,115,95,112,97,99,107,97,103,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, + 0,0,0,67,0,0,0,114,23,0,0,0,169,2,122,42, + 85,115,101,32,100,101,102,97,117,108,116,32,115,101,109,97, + 110,116,105,99,115,32,102,111,114,32,109,111,100,117,108,101, + 32,99,114,101,97,116,105,111,110,46,78,114,7,0,0,0, + 169,2,114,143,0,0,0,114,210,0,0,0,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,218,13,99,114,101, + 97,116,101,95,109,111,100,117,108,101,106,3,0,0,243,2, + 0,0,0,4,0,122,27,95,76,111,97,100,101,114,66,97, + 115,105,99,115,46,99,114,101,97,116,101,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,5,0,0,0,67,0,0,0,115,56,0,0,0, + 124,0,160,0,124,1,106,1,161,1,125,2,124,2,100,1, + 117,0,114,18,116,2,100,2,160,3,124,1,106,1,161,1, + 131,1,130,1,116,4,160,5,116,6,124,2,124,1,106,7, + 161,3,1,0,100,1,83,0,41,3,122,19,69,120,101,99, + 117,116,101,32,116,104,101,32,109,111,100,117,108,101,46,78, + 122,52,99,97,110,110,111,116,32,108,111,97,100,32,109,111, + 100,117,108,101,32,123,33,114,125,32,119,104,101,110,32,103, + 101,116,95,99,111,100,101,40,41,32,114,101,116,117,114,110, + 115,32,78,111,110,101,41,8,218,8,103,101,116,95,99,111, + 100,101,114,150,0,0,0,114,142,0,0,0,114,89,0,0, + 0,114,159,0,0,0,218,25,95,99,97,108,108,95,119,105, + 116,104,95,102,114,97,109,101,115,95,114,101,109,111,118,101, + 100,218,4,101,120,101,99,114,156,0,0,0,41,3,114,143, + 0,0,0,218,6,109,111,100,117,108,101,114,188,0,0,0, + 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, + 11,101,120,101,99,95,109,111,100,117,108,101,109,3,0,0, + 115,12,0,0,0,12,2,8,1,4,1,8,1,4,255,20, + 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, + 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, + 0,67,0,0,0,115,12,0,0,0,116,0,160,1,124,0, + 124,1,161,2,83,0,41,1,122,26,84,104,105,115,32,109, + 101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97, + 116,101,100,46,41,2,114,159,0,0,0,218,17,95,108,111, + 97,100,95,109,111,100,117,108,101,95,115,104,105,109,169,2, + 114,143,0,0,0,114,163,0,0,0,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,218,11,108,111,97,100,95, + 109,111,100,117,108,101,117,3,0,0,115,2,0,0,0,12, + 3,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, + 46,108,111,97,100,95,109,111,100,117,108,101,78,41,8,114, + 150,0,0,0,114,149,0,0,0,114,151,0,0,0,114,152, + 0,0,0,114,206,0,0,0,114,239,0,0,0,114,245,0, + 0,0,114,248,0,0,0,114,7,0,0,0,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,114,235,0,0,0, + 93,3,0,0,115,12,0,0,0,8,0,4,2,8,3,8, + 8,8,3,12,8,114,235,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,64, + 0,0,0,115,74,0,0,0,101,0,90,1,100,0,90,2, + 100,1,100,2,132,0,90,3,100,3,100,4,132,0,90,4, + 100,5,100,6,132,0,90,5,100,7,100,8,132,0,90,6, + 100,9,100,10,132,0,90,7,100,11,100,12,156,1,100,13, + 100,14,132,2,90,8,100,15,100,16,132,0,90,9,100,17, + 83,0,41,18,218,12,83,111,117,114,99,101,76,111,97,100, + 101,114,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 116,0,130,1,41,1,122,165,79,112,116,105,111,110,97,108, + 32,109,101,116,104,111,100,32,116,104,97,116,32,114,101,116, + 117,114,110,115,32,116,104,101,32,109,111,100,105,102,105,99, + 97,116,105,111,110,32,116,105,109,101,32,40,97,110,32,105, + 110,116,41,32,102,111,114,32,116,104,101,10,32,32,32,32, + 32,32,32,32,115,112,101,99,105,102,105,101,100,32,112,97, + 116,104,32,40,97,32,115,116,114,41,46,10,10,32,32,32, + 32,32,32,32,32,82,97,105,115,101,115,32,79,83,69,114, + 114,111,114,32,119,104,101,110,32,116,104,101,32,112,97,116, + 104,32,99,97,110,110,111,116,32,98,101,32,104,97,110,100, + 108,101,100,46,10,32,32,32,32,32,32,32,32,41,1,114, + 76,0,0,0,169,2,114,143,0,0,0,114,65,0,0,0, + 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, + 10,112,97,116,104,95,109,116,105,109,101,125,3,0,0,115, + 2,0,0,0,4,6,122,23,83,111,117,114,99,101,76,111, + 97,100,101,114,46,112,97,116,104,95,109,116,105,109,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 4,0,0,0,67,0,0,0,115,14,0,0,0,100,1,124, + 0,160,0,124,1,161,1,105,1,83,0,41,2,97,158,1, + 0,0,79,112,116,105,111,110,97,108,32,109,101,116,104,111, + 100,32,114,101,116,117,114,110,105,110,103,32,97,32,109,101, + 116,97,100,97,116,97,32,100,105,99,116,32,102,111,114,32, + 116,104,101,32,115,112,101,99,105,102,105,101,100,10,32,32, + 32,32,32,32,32,32,112,97,116,104,32,40,97,32,115,116, + 114,41,46,10,10,32,32,32,32,32,32,32,32,80,111,115, + 115,105,98,108,101,32,107,101,121,115,58,10,32,32,32,32, + 32,32,32,32,45,32,39,109,116,105,109,101,39,32,40,109, + 97,110,100,97,116,111,114,121,41,32,105,115,32,116,104,101, + 32,110,117,109,101,114,105,99,32,116,105,109,101,115,116,97, + 109,112,32,111,102,32,108,97,115,116,32,115,111,117,114,99, + 101,10,32,32,32,32,32,32,32,32,32,32,99,111,100,101, + 32,109,111,100,105,102,105,99,97,116,105,111,110,59,10,32, + 32,32,32,32,32,32,32,45,32,39,115,105,122,101,39,32, + 40,111,112,116,105,111,110,97,108,41,32,105,115,32,116,104, + 101,32,115,105,122,101,32,105,110,32,98,121,116,101,115,32, + 111,102,32,116,104,101,32,115,111,117,114,99,101,32,99,111, + 100,101,46,10,10,32,32,32,32,32,32,32,32,73,109,112, + 108,101,109,101,110,116,105,110,103,32,116,104,105,115,32,109, + 101,116,104,111,100,32,97,108,108,111,119,115,32,116,104,101, + 32,108,111,97,100,101,114,32,116,111,32,114,101,97,100,32, + 98,121,116,101,99,111,100,101,32,102,105,108,101,115,46,10, + 32,32,32,32,32,32,32,32,82,97,105,115,101,115,32,79, + 83,69,114,114,111,114,32,119,104,101,110,32,116,104,101,32, + 112,97,116,104,32,99,97,110,110,111,116,32,98,101,32,104, + 97,110,100,108,101,100,46,10,32,32,32,32,32,32,32,32, + 114,193,0,0,0,41,1,114,251,0,0,0,114,250,0,0, + 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, + 218,10,112,97,116,104,95,115,116,97,116,115,133,3,0,0, + 115,2,0,0,0,14,12,122,23,83,111,117,114,99,101,76, + 111,97,100,101,114,46,112,97,116,104,95,115,116,97,116,115, + 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,4,0,0,0,67,0,0,0,115,12,0,0,0,124,0, + 160,0,124,2,124,3,161,2,83,0,41,1,122,228,79,112, + 116,105,111,110,97,108,32,109,101,116,104,111,100,32,119,104, + 105,99,104,32,119,114,105,116,101,115,32,100,97,116,97,32, + 40,98,121,116,101,115,41,32,116,111,32,97,32,102,105,108, + 101,32,112,97,116,104,32,40,97,32,115,116,114,41,46,10, + 10,32,32,32,32,32,32,32,32,73,109,112,108,101,109,101, + 110,116,105,110,103,32,116,104,105,115,32,109,101,116,104,111, + 100,32,97,108,108,111,119,115,32,102,111,114,32,116,104,101, + 32,119,114,105,116,105,110,103,32,111,102,32,98,121,116,101, + 99,111,100,101,32,102,105,108,101,115,46,10,10,32,32,32, + 32,32,32,32,32,84,104,101,32,115,111,117,114,99,101,32, + 112,97,116,104,32,105,115,32,110,101,101,100,101,100,32,105, + 110,32,111,114,100,101,114,32,116,111,32,99,111,114,114,101, + 99,116,108,121,32,116,114,97,110,115,102,101,114,32,112,101, + 114,109,105,115,115,105,111,110,115,10,32,32,32,32,32,32, + 32,32,41,1,218,8,115,101,116,95,100,97,116,97,41,4, + 114,143,0,0,0,114,134,0,0,0,90,10,99,97,99,104, + 101,95,112,97,116,104,114,41,0,0,0,114,7,0,0,0, + 114,7,0,0,0,114,8,0,0,0,218,15,95,99,97,99, + 104,101,95,98,121,116,101,99,111,100,101,147,3,0,0,115, + 2,0,0,0,12,8,122,28,83,111,117,114,99,101,76,111, + 97,100,101,114,46,95,99,97,99,104,101,95,98,121,116,101, + 99,111,100,101,99,3,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,1,0,0,0,67,0,0,0,114,23,0, + 0,0,41,2,122,150,79,112,116,105,111,110,97,108,32,109, + 101,116,104,111,100,32,119,104,105,99,104,32,119,114,105,116, + 101,115,32,100,97,116,97,32,40,98,121,116,101,115,41,32, + 116,111,32,97,32,102,105,108,101,32,112,97,116,104,32,40, + 97,32,115,116,114,41,46,10,10,32,32,32,32,32,32,32, + 32,73,109,112,108,101,109,101,110,116,105,110,103,32,116,104, + 105,115,32,109,101,116,104,111,100,32,97,108,108,111,119,115, + 32,102,111,114,32,116,104,101,32,119,114,105,116,105,110,103, + 32,111,102,32,98,121,116,101,99,111,100,101,32,102,105,108, + 101,115,46,10,32,32,32,32,32,32,32,32,78,114,7,0, + 0,0,41,3,114,143,0,0,0,114,65,0,0,0,114,41, + 0,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,253,0,0,0,157,3,0,0,114,240,0,0,0, + 122,21,83,111,117,114,99,101,76,111,97,100,101,114,46,115, + 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,10,0,0,0,67,0,0,0, + 115,70,0,0,0,124,0,160,0,124,1,161,1,125,2,122, + 10,124,0,160,1,124,2,161,1,125,3,87,0,116,4,124, + 3,131,1,83,0,4,0,116,2,121,34,1,0,125,4,1, + 0,122,7,116,3,100,1,124,1,100,2,141,2,124,4,130, + 2,100,3,125,4,126,4,119,1,119,0,41,4,122,52,67, + 111,110,99,114,101,116,101,32,105,109,112,108,101,109,101,110, + 116,97,116,105,111,110,32,111,102,32,73,110,115,112,101,99, + 116,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, + 99,101,46,122,39,115,111,117,114,99,101,32,110,111,116,32, + 97,118,97,105,108,97,98,108,101,32,116,104,114,111,117,103, + 104,32,103,101,116,95,100,97,116,97,40,41,114,140,0,0, + 0,78,41,5,114,203,0,0,0,218,8,103,101,116,95,100, + 97,116,97,114,76,0,0,0,114,142,0,0,0,114,200,0, + 0,0,41,5,114,143,0,0,0,114,163,0,0,0,114,65, + 0,0,0,114,198,0,0,0,218,3,101,120,99,114,7,0, + 0,0,114,7,0,0,0,114,8,0,0,0,218,10,103,101, + 116,95,115,111,117,114,99,101,164,3,0,0,115,24,0,0, + 0,10,2,2,1,12,1,8,4,14,253,4,1,2,1,4, + 255,2,1,2,255,8,128,2,255,122,23,83,111,117,114,99, + 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, + 99,101,114,130,0,0,0,41,1,218,9,95,111,112,116,105, + 109,105,122,101,99,3,0,0,0,0,0,0,0,1,0,0, + 0,4,0,0,0,8,0,0,0,67,0,0,0,115,22,0, + 0,0,116,0,106,1,116,2,124,1,124,2,100,1,100,2, + 124,3,100,3,141,6,83,0,41,4,122,130,82,101,116,117, + 114,110,32,116,104,101,32,99,111,100,101,32,111,98,106,101, + 99,116,32,99,111,109,112,105,108,101,100,32,102,114,111,109, + 32,115,111,117,114,99,101,46,10,10,32,32,32,32,32,32, + 32,32,84,104,101,32,39,100,97,116,97,39,32,97,114,103, + 117,109,101,110,116,32,99,97,110,32,98,101,32,97,110,121, + 32,111,98,106,101,99,116,32,116,121,112,101,32,116,104,97, + 116,32,99,111,109,112,105,108,101,40,41,32,115,117,112,112, + 111,114,116,115,46,10,32,32,32,32,32,32,32,32,114,243, + 0,0,0,84,41,2,218,12,100,111,110,116,95,105,110,104, + 101,114,105,116,114,108,0,0,0,41,3,114,159,0,0,0, + 114,242,0,0,0,218,7,99,111,109,112,105,108,101,41,4, + 114,143,0,0,0,114,41,0,0,0,114,65,0,0,0,114, + 2,1,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,14,115,111,117,114,99,101,95,116,111,95,99, + 111,100,101,174,3,0,0,115,6,0,0,0,12,5,4,1, + 6,255,122,27,83,111,117,114,99,101,76,111,97,100,101,114, + 46,115,111,117,114,99,101,95,116,111,95,99,111,100,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0, + 9,0,0,0,67,0,0,0,115,2,2,0,0,124,0,160, + 0,124,1,161,1,125,2,100,1,125,3,100,1,125,4,100, + 1,125,5,100,2,125,6,100,3,125,7,122,6,116,1,124, + 2,131,1,125,8,87,0,110,11,4,0,116,2,121,32,1, + 0,1,0,1,0,100,1,125,8,89,0,110,144,119,0,122, + 7,124,0,160,3,124,2,161,1,125,9,87,0,110,9,4, + 0,116,4,121,49,1,0,1,0,1,0,89,0,110,127,119, + 0,116,5,124,9,100,4,25,0,131,1,125,3,122,7,124, + 0,160,6,124,8,161,1,125,10,87,0,110,9,4,0,116, + 4,121,72,1,0,1,0,1,0,89,0,110,104,119,0,124, + 1,124,8,100,5,156,2,125,11,122,71,116,7,124,10,124, + 1,124,11,131,3,125,12,116,8,124,10,131,1,100,6,100, + 1,133,2,25,0,125,13,124,12,100,7,64,0,100,8,107, + 3,125,6,124,6,114,138,124,12,100,9,64,0,100,8,107, + 3,125,7,116,9,106,10,100,10,107,3,114,137,124,7,115, + 119,116,9,106,10,100,11,107,2,114,137,124,0,160,6,124, + 2,161,1,125,4,116,9,160,11,116,12,124,4,161,2,125, + 5,116,13,124,10,124,5,124,1,124,11,131,4,1,0,110, + 10,116,14,124,10,124,3,124,9,100,12,25,0,124,1,124, + 11,131,5,1,0,87,0,110,11,4,0,116,15,116,16,102, + 2,121,160,1,0,1,0,1,0,89,0,110,16,119,0,116, + 17,160,18,100,13,124,8,124,2,161,3,1,0,116,19,124, + 13,124,1,124,8,124,2,100,14,141,4,83,0,124,4,100, + 1,117,0,114,185,124,0,160,6,124,2,161,1,125,4,124, + 0,160,20,124,4,124,2,161,2,125,14,116,17,160,18,100, + 15,124,2,161,2,1,0,116,21,106,22,115,255,124,8,100, + 1,117,1,114,255,124,3,100,1,117,1,114,255,124,6,114, + 226,124,5,100,1,117,0,114,219,116,9,160,11,124,4,161, + 1,125,5,116,23,124,14,124,5,124,7,131,3,125,10,110, + 8,116,24,124,14,124,3,116,25,124,4,131,1,131,3,125, + 10,122,10,124,0,160,26,124,2,124,8,124,10,161,3,1, + 0,87,0,124,14,83,0,4,0,116,2,121,254,1,0,1, + 0,1,0,89,0,124,14,83,0,119,0,124,14,83,0,41, + 16,122,190,67,111,110,99,114,101,116,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,73,110, + 115,112,101,99,116,76,111,97,100,101,114,46,103,101,116,95, + 99,111,100,101,46,10,10,32,32,32,32,32,32,32,32,82, + 101,97,100,105,110,103,32,111,102,32,98,121,116,101,99,111, + 100,101,32,114,101,113,117,105,114,101,115,32,112,97,116,104, + 95,115,116,97,116,115,32,116,111,32,98,101,32,105,109,112, + 108,101,109,101,110,116,101,100,46,32,84,111,32,119,114,105, + 116,101,10,32,32,32,32,32,32,32,32,98,121,116,101,99, + 111,100,101,44,32,115,101,116,95,100,97,116,97,32,109,117, + 115,116,32,97,108,115,111,32,98,101,32,105,109,112,108,101, + 109,101,110,116,101,100,46,10,10,32,32,32,32,32,32,32, + 32,78,70,84,114,193,0,0,0,114,183,0,0,0,114,169, + 0,0,0,114,3,0,0,0,114,0,0,0,0,114,44,0, + 0,0,90,5,110,101,118,101,114,90,6,97,108,119,97,121, + 115,218,4,115,105,122,101,122,13,123,125,32,109,97,116,99, + 104,101,115,32,123,125,41,3,114,141,0,0,0,114,132,0, + 0,0,114,134,0,0,0,122,19,99,111,100,101,32,111,98, + 106,101,99,116,32,102,114,111,109,32,123,125,41,27,114,203, + 0,0,0,114,121,0,0,0,114,107,0,0,0,114,252,0, + 0,0,114,76,0,0,0,114,33,0,0,0,114,255,0,0, + 0,114,176,0,0,0,218,10,109,101,109,111,114,121,118,105, + 101,119,114,187,0,0,0,90,21,99,104,101,99,107,95,104, + 97,115,104,95,98,97,115,101,100,95,112,121,99,115,114,181, + 0,0,0,218,17,95,82,65,87,95,77,65,71,73,67,95, + 78,85,77,66,69,82,114,182,0,0,0,114,180,0,0,0, + 114,142,0,0,0,114,174,0,0,0,114,159,0,0,0,114, + 173,0,0,0,114,189,0,0,0,114,5,1,0,0,114,15, + 0,0,0,218,19,100,111,110,116,95,119,114,105,116,101,95, + 98,121,116,101,99,111,100,101,114,195,0,0,0,114,194,0, + 0,0,114,4,0,0,0,114,254,0,0,0,41,15,114,143, + 0,0,0,114,163,0,0,0,114,134,0,0,0,114,178,0, + 0,0,114,198,0,0,0,114,181,0,0,0,90,10,104,97, + 115,104,95,98,97,115,101,100,90,12,99,104,101,99,107,95, + 115,111,117,114,99,101,114,132,0,0,0,218,2,115,116,114, + 41,0,0,0,114,175,0,0,0,114,16,0,0,0,90,10, + 98,121,116,101,115,95,100,97,116,97,90,11,99,111,100,101, + 95,111,98,106,101,99,116,114,7,0,0,0,114,7,0,0, + 0,114,8,0,0,0,114,241,0,0,0,182,3,0,0,115, + 170,0,0,0,10,7,4,1,4,1,4,1,4,1,4,1, + 2,1,12,1,12,1,8,1,2,255,2,3,14,1,12,1, + 4,1,2,255,12,3,2,1,14,1,12,1,4,1,2,255, + 2,4,2,1,6,254,2,4,12,1,16,1,12,1,4,1, + 12,1,10,1,2,1,2,255,8,2,2,254,10,3,4,1, + 2,1,2,1,4,254,8,4,2,1,4,255,2,128,2,3, + 2,1,2,1,6,1,2,1,2,1,4,251,4,128,16,7, + 4,1,2,255,8,3,2,1,4,255,6,2,2,1,2,1, + 6,254,8,3,10,1,12,1,12,1,14,1,6,1,2,255, + 4,2,8,1,10,1,14,1,6,2,6,1,4,255,2,2, + 16,1,4,3,12,254,2,1,4,1,2,254,4,2,122,21, + 83,111,117,114,99,101,76,111,97,100,101,114,46,103,101,116, + 95,99,111,100,101,78,41,10,114,150,0,0,0,114,149,0, + 0,0,114,151,0,0,0,114,251,0,0,0,114,252,0,0, + 0,114,254,0,0,0,114,253,0,0,0,114,1,1,0,0, + 114,5,1,0,0,114,241,0,0,0,114,7,0,0,0,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,249, + 0,0,0,123,3,0,0,115,16,0,0,0,8,0,8,2, + 8,8,8,14,8,10,8,7,14,10,12,8,114,249,0,0, 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,64,0,0,0,115,92,0,0,0,101, + 0,0,4,0,0,0,0,0,0,0,115,92,0,0,0,101, 0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,132, 0,90,4,100,4,100,5,132,0,90,5,100,6,100,7,132, - 0,90,6,100,8,100,9,132,0,90,7,100,10,100,11,132, - 0,90,8,100,12,100,13,132,0,90,9,100,14,100,15,132, - 0,90,10,100,16,100,17,132,0,90,11,101,12,100,18,100, - 19,132,0,131,1,90,13,100,20,83,0,41,21,114,19,1, - 0,0,122,93,76,111,97,100,101,114,32,102,111,114,32,101, - 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,115, - 46,10,10,32,32,32,32,84,104,101,32,99,111,110,115,116, - 114,117,99,116,111,114,32,105,115,32,100,101,115,105,103,110, - 101,100,32,116,111,32,119,111,114,107,32,119,105,116,104,32, - 70,105,108,101,70,105,110,100,101,114,46,10,10,32,32,32, - 32,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,8,0,0,0,67,0,0,0,115,62,0,0,0,124, - 1,124,0,95,0,116,1,124,2,131,1,115,52,122,18,116, - 2,116,3,160,4,161,0,124,2,131,2,125,2,87,0,110, - 18,4,0,116,5,121,50,1,0,1,0,1,0,89,0,110, - 2,48,0,124,2,124,0,95,6,100,0,83,0,114,69,0, - 0,0,41,7,114,140,0,0,0,114,85,0,0,0,114,67, - 0,0,0,114,24,0,0,0,114,81,0,0,0,114,76,0, - 0,0,114,65,0,0,0,114,28,1,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,232,0,0,0, - 131,4,0,0,115,14,0,0,0,0,1,6,1,8,1,2, - 1,18,1,12,1,6,1,122,28,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,95,95,105, - 110,105,116,95,95,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,24, - 0,0,0,124,0,106,0,124,1,106,0,107,2,111,22,124, - 0,106,1,124,1,106,1,107,2,83,0,114,69,0,0,0, - 114,7,1,0,0,114,9,1,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,10,1,0,0,140,4, - 0,0,115,6,0,0,0,0,1,12,1,10,255,122,26,69, + 0,90,6,101,7,135,0,102,1,100,8,100,9,132,8,131, + 1,90,8,101,7,100,10,100,11,132,0,131,1,90,9,100, + 12,100,13,132,0,90,10,101,7,100,14,100,15,132,0,131, + 1,90,11,135,0,4,0,90,12,83,0,41,16,218,10,70, + 105,108,101,76,111,97,100,101,114,122,103,66,97,115,101,32, + 102,105,108,101,32,108,111,97,100,101,114,32,99,108,97,115, + 115,32,119,104,105,99,104,32,105,109,112,108,101,109,101,110, + 116,115,32,116,104,101,32,108,111,97,100,101,114,32,112,114, + 111,116,111,99,111,108,32,109,101,116,104,111,100,115,32,116, + 104,97,116,10,32,32,32,32,114,101,113,117,105,114,101,32, + 102,105,108,101,32,115,121,115,116,101,109,32,117,115,97,103, + 101,46,99,3,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, + 124,1,124,0,95,0,124,2,124,0,95,1,100,1,83,0, + 41,2,122,75,67,97,99,104,101,32,116,104,101,32,109,111, + 100,117,108,101,32,110,97,109,101,32,97,110,100,32,116,104, + 101,32,112,97,116,104,32,116,111,32,116,104,101,32,102,105, + 108,101,32,102,111,117,110,100,32,98,121,32,116,104,101,10, + 32,32,32,32,32,32,32,32,102,105,110,100,101,114,46,78, + 114,183,0,0,0,41,3,114,143,0,0,0,114,163,0,0, + 0,114,65,0,0,0,114,7,0,0,0,114,7,0,0,0, + 114,8,0,0,0,114,236,0,0,0,16,4,0,0,115,4, + 0,0,0,6,3,10,1,122,19,70,105,108,101,76,111,97, + 100,101,114,46,95,95,105,110,105,116,95,95,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0, + 0,67,0,0,0,243,24,0,0,0,124,0,106,0,124,1, + 106,0,107,2,111,11,124,0,106,1,124,1,106,1,107,2, + 83,0,114,69,0,0,0,169,2,218,9,95,95,99,108,97, + 115,115,95,95,114,156,0,0,0,169,2,114,143,0,0,0, + 90,5,111,116,104,101,114,114,7,0,0,0,114,7,0,0, + 0,114,8,0,0,0,218,6,95,95,101,113,95,95,22,4, + 0,0,243,6,0,0,0,12,1,10,1,2,255,122,17,70, + 105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,95, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,243,20,0,0,0,116,0, + 124,0,106,1,131,1,116,0,124,0,106,2,131,1,65,0, + 83,0,114,69,0,0,0,169,3,218,4,104,97,115,104,114, + 141,0,0,0,114,65,0,0,0,169,1,114,143,0,0,0, + 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, + 8,95,95,104,97,115,104,95,95,26,4,0,0,243,2,0, + 0,0,20,1,122,19,70,105,108,101,76,111,97,100,101,114, + 46,95,95,104,97,115,104,95,95,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,3,0,0,0,3,0, + 0,0,115,16,0,0,0,116,0,116,1,124,0,131,2,160, + 2,124,1,161,1,83,0,41,1,122,100,76,111,97,100,32, + 97,32,109,111,100,117,108,101,32,102,114,111,109,32,97,32, + 102,105,108,101,46,10,10,32,32,32,32,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,101, + 120,101,99,95,109,111,100,117,108,101,40,41,32,105,110,115, + 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,41, + 3,218,5,115,117,112,101,114,114,11,1,0,0,114,248,0, + 0,0,114,247,0,0,0,169,1,114,14,1,0,0,114,7, + 0,0,0,114,8,0,0,0,114,248,0,0,0,29,4,0, + 0,115,2,0,0,0,16,10,122,22,70,105,108,101,76,111, + 97,100,101,114,46,108,111,97,100,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,243,6,0,0,0,124,0, + 106,0,83,0,169,1,122,58,82,101,116,117,114,110,32,116, + 104,101,32,112,97,116,104,32,116,111,32,116,104,101,32,115, + 111,117,114,99,101,32,102,105,108,101,32,97,115,32,102,111, + 117,110,100,32,98,121,32,116,104,101,32,102,105,110,100,101, + 114,46,114,71,0,0,0,114,247,0,0,0,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,114,203,0,0,0, + 41,4,0,0,243,2,0,0,0,6,3,122,23,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,102,105,108,101, + 110,97,109,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,8,0,0,0,67,0,0,0,115,128,0, + 0,0,116,0,124,0,116,1,116,2,102,2,131,2,114,36, + 116,3,160,4,116,5,124,1,131,1,161,1,143,12,125,2, + 124,2,160,6,161,0,87,0,2,0,100,1,4,0,4,0, + 131,3,1,0,83,0,49,0,115,29,119,1,1,0,1,0, + 1,0,89,0,1,0,100,1,83,0,116,3,160,7,124,1, + 100,2,161,2,143,12,125,2,124,2,160,6,161,0,87,0, + 2,0,100,1,4,0,4,0,131,3,1,0,83,0,49,0, + 115,57,119,1,1,0,1,0,1,0,89,0,1,0,100,1, + 83,0,41,3,122,39,82,101,116,117,114,110,32,116,104,101, + 32,100,97,116,97,32,102,114,111,109,32,112,97,116,104,32, + 97,115,32,114,97,119,32,98,121,116,101,115,46,78,218,1, + 114,41,8,114,185,0,0,0,114,249,0,0,0,218,19,69, 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, - 101,114,46,95,95,101,113,95,95,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,20,0,0,0,116,0,124,0,106,1,131,1,116, - 0,124,0,106,2,131,1,65,0,83,0,114,69,0,0,0, - 114,11,1,0,0,114,13,1,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,14,1,0,0,144,4, - 0,0,115,2,0,0,0,0,1,122,28,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,95, - 95,104,97,115,104,95,95,99,2,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,5,0,0,0,67,0,0,0, - 115,36,0,0,0,116,0,160,1,116,2,106,3,124,1,161, - 2,125,2,116,0,160,4,100,1,124,1,106,5,124,0,106, - 6,161,3,1,0,124,2,83,0,41,2,122,38,67,114,101, - 97,116,101,32,97,110,32,117,110,105,116,105,97,108,105,122, - 101,100,32,101,120,116,101,110,115,105,111,110,32,109,111,100, - 117,108,101,122,38,101,120,116,101,110,115,105,111,110,32,109, - 111,100,117,108,101,32,123,33,114,125,32,108,111,97,100,101, - 100,32,102,114,111,109,32,123,33,114,125,41,7,114,158,0, - 0,0,114,237,0,0,0,114,187,0,0,0,90,14,99,114, - 101,97,116,101,95,100,121,110,97,109,105,99,114,173,0,0, - 0,114,140,0,0,0,114,65,0,0,0,41,3,114,142,0, - 0,0,114,210,0,0,0,114,239,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,235,0,0,0, - 147,4,0,0,115,14,0,0,0,0,2,4,1,6,255,4, - 2,6,1,8,255,4,2,122,33,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,99,114,101, - 97,116,101,95,109,111,100,117,108,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,5,0,0,0,67, - 0,0,0,115,36,0,0,0,116,0,160,1,116,2,106,3, - 124,1,161,2,1,0,116,0,160,4,100,1,124,0,106,5, - 124,0,106,6,161,3,1,0,100,2,83,0,41,3,122,30, - 73,110,105,116,105,97,108,105,122,101,32,97,110,32,101,120, - 116,101,110,115,105,111,110,32,109,111,100,117,108,101,122,40, + 101,114,114,91,0,0,0,90,9,111,112,101,110,95,99,111, + 100,101,114,109,0,0,0,90,4,114,101,97,100,114,92,0, + 0,0,41,3,114,143,0,0,0,114,65,0,0,0,114,94, + 0,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,255,0,0,0,46,4,0,0,115,14,0,0,0, + 14,2,16,1,6,1,36,255,14,3,6,1,36,255,122,19, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,100, + 97,116,97,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,2,0,0,0,67,0,0,0,115,20,0,0, + 0,100,1,100,2,108,0,109,1,125,2,1,0,124,2,124, + 0,131,1,83,0,41,3,78,114,0,0,0,0,41,1,218, + 10,70,105,108,101,82,101,97,100,101,114,41,2,218,17,105, + 109,112,111,114,116,108,105,98,46,114,101,97,100,101,114,115, + 114,31,1,0,0,41,3,114,143,0,0,0,114,244,0,0, + 0,114,31,1,0,0,114,7,0,0,0,114,7,0,0,0, + 114,8,0,0,0,218,19,103,101,116,95,114,101,115,111,117, + 114,99,101,95,114,101,97,100,101,114,55,4,0,0,115,4, + 0,0,0,12,2,8,1,122,30,70,105,108,101,76,111,97, + 100,101,114,46,103,101,116,95,114,101,115,111,117,114,99,101, + 95,114,101,97,100,101,114,41,13,114,150,0,0,0,114,149, + 0,0,0,114,151,0,0,0,114,152,0,0,0,114,236,0, + 0,0,114,16,1,0,0,114,22,1,0,0,114,160,0,0, + 0,114,248,0,0,0,114,203,0,0,0,114,255,0,0,0, + 114,33,1,0,0,90,13,95,95,99,108,97,115,115,99,101, + 108,108,95,95,114,7,0,0,0,114,7,0,0,0,114,25, + 1,0,0,114,8,0,0,0,114,11,1,0,0,11,4,0, + 0,115,24,0,0,0,8,0,4,2,8,3,8,6,8,4, + 2,3,14,1,2,11,10,1,8,4,2,9,18,1,114,11, + 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,64,0,0,0,115,46,0,0, + 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, + 3,132,0,90,4,100,4,100,5,132,0,90,5,100,6,100, + 7,156,1,100,8,100,9,132,2,90,6,100,10,83,0,41, + 11,218,16,83,111,117,114,99,101,70,105,108,101,76,111,97, + 100,101,114,122,62,67,111,110,99,114,101,116,101,32,105,109, + 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, + 83,111,117,114,99,101,76,111,97,100,101,114,32,117,115,105, + 110,103,32,116,104,101,32,102,105,108,101,32,115,121,115,116, + 101,109,46,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,3,0,0,0,67,0,0,0,115,22,0,0, + 0,116,0,124,1,131,1,125,2,124,2,106,1,124,2,106, + 2,100,1,156,2,83,0,41,2,122,33,82,101,116,117,114, + 110,32,116,104,101,32,109,101,116,97,100,97,116,97,32,102, + 111,114,32,116,104,101,32,112,97,116,104,46,41,2,114,193, + 0,0,0,114,6,1,0,0,41,3,114,75,0,0,0,218, + 8,115,116,95,109,116,105,109,101,90,7,115,116,95,115,105, + 122,101,41,3,114,143,0,0,0,114,65,0,0,0,114,10, + 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,252,0,0,0,65,4,0,0,115,4,0,0,0, + 8,2,14,1,122,27,83,111,117,114,99,101,70,105,108,101, + 76,111,97,100,101,114,46,112,97,116,104,95,115,116,97,116, + 115,99,4,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,5,0,0,0,67,0,0,0,115,24,0,0,0,116, + 0,124,1,131,1,125,4,124,0,106,1,124,2,124,3,124, + 4,100,1,141,3,83,0,41,2,78,169,1,218,5,95,109, + 111,100,101,41,2,114,139,0,0,0,114,253,0,0,0,41, + 5,114,143,0,0,0,114,134,0,0,0,114,132,0,0,0, + 114,41,0,0,0,114,78,0,0,0,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,114,254,0,0,0,70,4, + 0,0,115,4,0,0,0,8,2,16,1,122,32,83,111,117, + 114,99,101,70,105,108,101,76,111,97,100,101,114,46,95,99, + 97,99,104,101,95,98,121,116,101,99,111,100,101,114,87,0, + 0,0,114,36,1,0,0,99,3,0,0,0,0,0,0,0, + 1,0,0,0,9,0,0,0,11,0,0,0,67,0,0,0, + 115,254,0,0,0,116,0,124,1,131,1,92,2,125,4,125, + 5,103,0,125,6,124,4,114,31,116,1,124,4,131,1,115, + 31,116,0,124,4,131,1,92,2,125,4,125,7,124,6,160, + 2,124,7,161,1,1,0,124,4,114,31,116,1,124,4,131, + 1,114,14,116,3,124,6,131,1,68,0,93,49,125,7,116, + 4,124,4,124,7,131,2,125,4,122,7,116,5,160,6,124, + 4,161,1,1,0,87,0,113,35,4,0,116,7,121,58,1, + 0,1,0,1,0,89,0,113,35,4,0,116,8,121,84,1, + 0,125,8,1,0,122,15,116,9,160,10,100,1,124,4,124, + 8,161,3,1,0,87,0,89,0,100,2,125,8,126,8,1, + 0,100,2,83,0,100,2,125,8,126,8,119,1,119,0,122, + 15,116,11,124,1,124,2,124,3,131,3,1,0,116,9,160, + 10,100,3,124,1,161,2,1,0,87,0,100,2,83,0,4, + 0,116,8,121,126,1,0,125,8,1,0,122,14,116,9,160, + 10,100,1,124,1,124,8,161,3,1,0,87,0,89,0,100, + 2,125,8,126,8,100,2,83,0,100,2,125,8,126,8,119, + 1,119,0,41,4,122,27,87,114,105,116,101,32,98,121,116, + 101,115,32,100,97,116,97,32,116,111,32,97,32,102,105,108, + 101,46,122,27,99,111,117,108,100,32,110,111,116,32,99,114, + 101,97,116,101,32,123,33,114,125,58,32,123,33,114,125,78, + 122,12,99,114,101,97,116,101,100,32,123,33,114,125,41,12, + 114,74,0,0,0,114,83,0,0,0,114,61,0,0,0,218, + 8,114,101,118,101,114,115,101,100,114,67,0,0,0,114,18, + 0,0,0,90,5,109,107,100,105,114,218,15,70,105,108,101, + 69,120,105,115,116,115,69,114,114,111,114,114,76,0,0,0, + 114,159,0,0,0,114,173,0,0,0,114,95,0,0,0,41, + 9,114,143,0,0,0,114,65,0,0,0,114,41,0,0,0, + 114,37,1,0,0,218,6,112,97,114,101,110,116,114,120,0, + 0,0,114,63,0,0,0,114,68,0,0,0,114,0,1,0, + 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, + 114,253,0,0,0,75,4,0,0,115,56,0,0,0,12,2, + 4,1,12,2,12,1,10,1,12,254,12,4,10,1,2,1, + 14,1,12,1,4,2,14,1,6,3,4,1,4,255,16,2, + 8,128,2,251,2,6,12,1,18,1,14,1,8,2,2,1, + 18,255,8,128,2,254,122,25,83,111,117,114,99,101,70,105, + 108,101,76,111,97,100,101,114,46,115,101,116,95,100,97,116, + 97,78,41,7,114,150,0,0,0,114,149,0,0,0,114,151, + 0,0,0,114,152,0,0,0,114,252,0,0,0,114,254,0, + 0,0,114,253,0,0,0,114,7,0,0,0,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,114,34,1,0,0, + 61,4,0,0,115,10,0,0,0,8,0,4,2,8,2,8, + 5,18,5,114,34,1,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, + 0,115,32,0,0,0,101,0,90,1,100,0,90,2,100,1, + 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, + 90,5,100,6,83,0,41,7,218,20,83,111,117,114,99,101, + 108,101,115,115,70,105,108,101,76,111,97,100,101,114,122,45, + 76,111,97,100,101,114,32,119,104,105,99,104,32,104,97,110, + 100,108,101,115,32,115,111,117,114,99,101,108,101,115,115,32, + 102,105,108,101,32,105,109,112,111,114,116,115,46,99,2,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0, + 0,0,67,0,0,0,115,68,0,0,0,124,0,160,0,124, + 1,161,1,125,2,124,0,160,1,124,2,161,1,125,3,124, + 1,124,2,100,1,156,2,125,4,116,2,124,3,124,1,124, + 4,131,3,1,0,116,3,116,4,124,3,131,1,100,2,100, + 0,133,2,25,0,124,1,124,2,100,3,141,3,83,0,41, + 4,78,114,183,0,0,0,114,169,0,0,0,41,2,114,141, + 0,0,0,114,132,0,0,0,41,5,114,203,0,0,0,114, + 255,0,0,0,114,176,0,0,0,114,189,0,0,0,114,7, + 1,0,0,41,5,114,143,0,0,0,114,163,0,0,0,114, + 65,0,0,0,114,41,0,0,0,114,175,0,0,0,114,7, + 0,0,0,114,7,0,0,0,114,8,0,0,0,114,241,0, + 0,0,110,4,0,0,115,22,0,0,0,10,1,10,1,2, + 4,2,1,6,254,12,4,2,1,14,1,2,1,2,1,6, + 253,122,29,83,111,117,114,99,101,108,101,115,115,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,114,23,0,0,0,41,2, + 122,39,82,101,116,117,114,110,32,78,111,110,101,32,97,115, + 32,116,104,101,114,101,32,105,115,32,110,111,32,115,111,117, + 114,99,101,32,99,111,100,101,46,78,114,7,0,0,0,114, + 247,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,114,1,1,0,0,126,4,0,0,114,24,0,0, + 0,122,31,83,111,117,114,99,101,108,101,115,115,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, + 99,101,78,41,6,114,150,0,0,0,114,149,0,0,0,114, + 151,0,0,0,114,152,0,0,0,114,241,0,0,0,114,1, + 1,0,0,114,7,0,0,0,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,114,41,1,0,0,106,4,0,0, + 115,8,0,0,0,8,0,4,2,8,2,12,16,114,41,1, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,64,0,0,0,115,92,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, + 132,0,90,4,100,4,100,5,132,0,90,5,100,6,100,7, + 132,0,90,6,100,8,100,9,132,0,90,7,100,10,100,11, + 132,0,90,8,100,12,100,13,132,0,90,9,100,14,100,15, + 132,0,90,10,100,16,100,17,132,0,90,11,101,12,100,18, + 100,19,132,0,131,1,90,13,100,20,83,0,41,21,114,30, + 1,0,0,122,93,76,111,97,100,101,114,32,102,111,114,32, 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 32,123,33,114,125,32,101,120,101,99,117,116,101,100,32,102, - 114,111,109,32,123,33,114,125,78,41,7,114,158,0,0,0, - 114,237,0,0,0,114,187,0,0,0,90,12,101,120,101,99, - 95,100,121,110,97,109,105,99,114,173,0,0,0,114,140,0, - 0,0,114,65,0,0,0,114,20,1,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,240,0,0,0, - 155,4,0,0,115,8,0,0,0,0,2,14,1,6,1,8, - 255,122,31,69,120,116,101,110,115,105,111,110,70,105,108,101, - 76,111,97,100,101,114,46,101,120,101,99,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,4,0,0,0,3,0,0,0,115,36,0,0,0, - 116,0,124,0,106,1,131,1,100,1,25,0,137,0,116,2, - 135,0,102,1,100,2,100,3,132,8,116,3,68,0,131,1, - 131,1,83,0,41,4,122,49,82,101,116,117,114,110,32,84, - 114,117,101,32,105,102,32,116,104,101,32,101,120,116,101,110, - 115,105,111,110,32,109,111,100,117,108,101,32,105,115,32,97, - 32,112,97,99,107,97,103,101,46,114,4,0,0,0,99,1, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, - 0,0,0,51,0,0,0,115,26,0,0,0,124,0,93,18, - 125,1,136,0,100,0,124,1,23,0,107,2,86,0,1,0, - 113,2,100,1,83,0,41,2,114,232,0,0,0,78,114,10, - 0,0,0,169,2,114,8,0,0,0,218,6,115,117,102,102, - 105,120,169,1,90,9,102,105,108,101,95,110,97,109,101,114, - 10,0,0,0,114,11,0,0,0,114,12,0,0,0,164,4, - 0,0,115,4,0,0,0,4,1,2,255,122,49,69,120,116, - 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, - 46,105,115,95,112,97,99,107,97,103,101,46,60,108,111,99, - 97,108,115,62,46,60,103,101,110,101,120,112,114,62,41,4, - 114,74,0,0,0,114,65,0,0,0,218,3,97,110,121,218, - 18,69,88,84,69,78,83,73,79,78,95,83,85,70,70,73, - 88,69,83,114,242,0,0,0,114,10,0,0,0,114,42,1, - 0,0,114,11,0,0,0,114,206,0,0,0,161,4,0,0, - 115,8,0,0,0,0,2,14,1,12,1,2,255,122,30,69, - 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, - 101,114,46,105,115,95,112,97,99,107,97,103,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,122,63,82,101,116,117,114,110,32,78,111,110,101,32,97, - 115,32,97,110,32,101,120,116,101,110,115,105,111,110,32,109, - 111,100,117,108,101,32,99,97,110,110,111,116,32,99,114,101, - 97,116,101,32,97,32,99,111,100,101,32,111,98,106,101,99, - 116,46,78,114,10,0,0,0,114,242,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,236,0,0, - 0,167,4,0,0,115,2,0,0,0,0,2,122,28,69,120, + 115,46,10,10,32,32,32,32,84,104,101,32,99,111,110,115, + 116,114,117,99,116,111,114,32,105,115,32,100,101,115,105,103, + 110,101,100,32,116,111,32,119,111,114,107,32,119,105,116,104, + 32,70,105,108,101,70,105,110,100,101,114,46,10,10,32,32, + 32,32,99,3,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, + 124,1,124,0,95,0,124,2,124,0,95,1,100,0,83,0, + 114,69,0,0,0,114,183,0,0,0,41,3,114,143,0,0, + 0,114,141,0,0,0,114,65,0,0,0,114,7,0,0,0, + 114,7,0,0,0,114,8,0,0,0,114,236,0,0,0,139, + 4,0,0,115,4,0,0,0,6,1,10,1,122,28,69,120, 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,53, - 82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,101, - 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,115, - 32,104,97,118,101,32,110,111,32,115,111,117,114,99,101,32, - 99,111,100,101,46,78,114,10,0,0,0,114,242,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 252,0,0,0,171,4,0,0,115,2,0,0,0,0,2,122, - 30,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 1,0,0,0,67,0,0,0,115,6,0,0,0,124,0,106, - 0,83,0,114,17,1,0,0,114,71,0,0,0,114,242,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,203,0,0,0,175,4,0,0,115,2,0,0,0,0, - 3,122,32,69,120,116,101,110,115,105,111,110,70,105,108,101, - 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, - 97,109,101,78,41,14,114,149,0,0,0,114,148,0,0,0, - 114,150,0,0,0,114,151,0,0,0,114,232,0,0,0,114, - 10,1,0,0,114,14,1,0,0,114,235,0,0,0,114,240, - 0,0,0,114,206,0,0,0,114,236,0,0,0,114,252,0, - 0,0,114,160,0,0,0,114,203,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,19,1,0,0,123,4,0,0,115,22,0,0,0,8,2, - 4,6,8,9,8,4,8,3,8,8,8,6,8,6,8,4, - 8,4,2,1,114,19,1,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, - 0,0,115,108,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,90,4,100,3,100,4,132,0,90,5,100, - 5,100,6,132,0,90,6,100,7,100,8,132,0,90,7,100, - 9,100,10,132,0,90,8,100,11,100,12,132,0,90,9,100, - 13,100,14,132,0,90,10,100,15,100,16,132,0,90,11,100, - 17,100,18,132,0,90,12,100,19,100,20,132,0,90,13,100, - 21,100,22,132,0,90,14,100,23,100,24,132,0,90,15,100, - 25,83,0,41,26,218,14,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,97,38,1,0,0,82,101,112,114,101,115, - 101,110,116,115,32,97,32,110,97,109,101,115,112,97,99,101, - 32,112,97,99,107,97,103,101,39,115,32,112,97,116,104,46, - 32,32,73,116,32,117,115,101,115,32,116,104,101,32,109,111, - 100,117,108,101,32,110,97,109,101,10,32,32,32,32,116,111, - 32,102,105,110,100,32,105,116,115,32,112,97,114,101,110,116, - 32,109,111,100,117,108,101,44,32,97,110,100,32,102,114,111, - 109,32,116,104,101,114,101,32,105,116,32,108,111,111,107,115, - 32,117,112,32,116,104,101,32,112,97,114,101,110,116,39,115, - 10,32,32,32,32,95,95,112,97,116,104,95,95,46,32,32, - 87,104,101,110,32,116,104,105,115,32,99,104,97,110,103,101, - 115,44,32,116,104,101,32,109,111,100,117,108,101,39,115,32, - 111,119,110,32,112,97,116,104,32,105,115,32,114,101,99,111, - 109,112,117,116,101,100,44,10,32,32,32,32,117,115,105,110, - 103,32,112,97,116,104,95,102,105,110,100,101,114,46,32,32, - 70,111,114,32,116,111,112,45,108,101,118,101,108,32,109,111, - 100,117,108,101,115,44,32,116,104,101,32,112,97,114,101,110, - 116,32,109,111,100,117,108,101,39,115,32,112,97,116,104,10, - 32,32,32,32,105,115,32,115,121,115,46,112,97,116,104,46, - 114,0,0,0,0,99,4,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,44, - 0,0,0,124,1,124,0,95,0,124,2,124,0,95,1,116, - 2,124,0,160,3,161,0,131,1,124,0,95,4,124,0,106, - 5,124,0,95,6,124,3,124,0,95,7,100,0,83,0,114, - 69,0,0,0,41,8,218,5,95,110,97,109,101,218,5,95, - 112,97,116,104,114,135,0,0,0,218,16,95,103,101,116,95, - 112,97,114,101,110,116,95,112,97,116,104,218,17,95,108,97, - 115,116,95,112,97,114,101,110,116,95,112,97,116,104,218,6, - 95,101,112,111,99,104,218,11,95,108,97,115,116,95,101,112, - 111,99,104,218,12,95,112,97,116,104,95,102,105,110,100,101, - 114,169,4,114,142,0,0,0,114,140,0,0,0,114,65,0, - 0,0,90,11,112,97,116,104,95,102,105,110,100,101,114,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,232, - 0,0,0,192,4,0,0,115,10,0,0,0,0,1,6,1, - 6,1,14,1,8,1,122,23,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,95,95,105,110,105,116,95,95,99, - 1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, - 3,0,0,0,67,0,0,0,115,38,0,0,0,124,0,106, - 0,160,1,100,1,161,1,92,3,125,1,125,2,125,3,124, - 2,100,2,107,2,114,30,100,3,83,0,124,1,100,4,102, - 2,83,0,41,5,122,62,82,101,116,117,114,110,115,32,97, - 32,116,117,112,108,101,32,111,102,32,40,112,97,114,101,110, - 116,45,109,111,100,117,108,101,45,110,97,109,101,44,32,112, - 97,114,101,110,116,45,112,97,116,104,45,97,116,116,114,45, - 110,97,109,101,41,114,96,0,0,0,114,14,0,0,0,41, - 2,114,21,0,0,0,114,65,0,0,0,90,8,95,95,112, - 97,116,104,95,95,41,2,114,46,1,0,0,114,103,0,0, - 0,41,4,114,142,0,0,0,114,38,1,0,0,218,3,100, - 111,116,90,2,109,101,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,23,95,102,105,110,100,95,112,97,114, - 101,110,116,95,112,97,116,104,95,110,97,109,101,115,199,4, - 0,0,115,8,0,0,0,0,2,18,1,8,2,4,3,122, - 38,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 95,102,105,110,100,95,112,97,114,101,110,116,95,112,97,116, - 104,95,110,97,109,101,115,99,1,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, - 115,28,0,0,0,124,0,160,0,161,0,92,2,125,1,125, - 2,116,1,116,2,106,3,124,1,25,0,124,2,131,2,83, - 0,114,69,0,0,0,41,4,114,55,1,0,0,114,154,0, - 0,0,114,21,0,0,0,218,7,109,111,100,117,108,101,115, - 41,3,114,142,0,0,0,90,18,112,97,114,101,110,116,95, - 109,111,100,117,108,101,95,110,97,109,101,90,14,112,97,116, - 104,95,97,116,116,114,95,110,97,109,101,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,48,1,0,0,209, - 4,0,0,115,4,0,0,0,0,1,12,1,122,31,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,103,101, - 116,95,112,97,114,101,110,116,95,112,97,116,104,99,1,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, - 0,0,67,0,0,0,115,100,0,0,0,116,0,124,0,160, - 1,161,0,131,1,125,1,124,1,124,0,106,2,107,3,115, - 34,124,0,106,3,124,0,106,4,107,3,114,94,124,0,160, - 5,124,0,106,6,124,1,161,2,125,2,124,2,100,0,117, - 1,114,80,124,2,106,7,100,0,117,0,114,80,124,2,106, - 8,114,80,124,2,106,8,124,0,95,9,124,1,124,0,95, - 2,124,0,106,3,124,0,95,4,124,0,106,9,83,0,114, - 69,0,0,0,41,10,114,135,0,0,0,114,48,1,0,0, - 114,49,1,0,0,114,50,1,0,0,114,51,1,0,0,114, - 52,1,0,0,114,46,1,0,0,114,164,0,0,0,114,202, - 0,0,0,114,47,1,0,0,41,3,114,142,0,0,0,90, - 11,112,97,114,101,110,116,95,112,97,116,104,114,210,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,12,95,114,101,99,97,108,99,117,108,97,116,101,213,4, - 0,0,115,18,0,0,0,0,2,12,1,22,1,14,3,18, - 1,6,1,8,1,6,1,8,1,122,27,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,114,101,99,97,108, - 99,117,108,97,116,101,99,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, - 12,0,0,0,116,0,124,0,160,1,161,0,131,1,83,0, - 114,69,0,0,0,41,2,114,29,1,0,0,114,57,1,0, - 0,114,13,1,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,8,95,95,105,116,101,114,95,95,227, - 4,0,0,115,2,0,0,0,0,1,122,23,95,78,97,109, - 101,115,112,97,99,101,80,97,116,104,46,95,95,105,116,101, - 114,95,95,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,2,0,0,0,67,0,0,0,115,12,0,0, - 0,124,0,160,0,161,0,124,1,25,0,83,0,114,69,0, - 0,0,169,1,114,57,1,0,0,41,2,114,142,0,0,0, - 218,5,105,110,100,101,120,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,11,95,95,103,101,116,105,116,101, - 109,95,95,230,4,0,0,115,2,0,0,0,0,1,122,26, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,103,101,116,105,116,101,109,95,95,99,3,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,14,0,0,0,124,2,124,0,106,0,124,1, - 60,0,100,0,83,0,114,69,0,0,0,41,1,114,47,1, - 0,0,41,3,114,142,0,0,0,114,60,1,0,0,114,65, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,11,95,95,115,101,116,105,116,101,109,95,95,233, - 4,0,0,115,2,0,0,0,0,1,122,26,95,78,97,109, - 101,115,112,97,99,101,80,97,116,104,46,95,95,115,101,116, - 105,116,101,109,95,95,99,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, - 12,0,0,0,116,0,124,0,160,1,161,0,131,1,83,0, - 114,69,0,0,0,41,2,114,6,0,0,0,114,57,1,0, - 0,114,13,1,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,7,95,95,108,101,110,95,95,236,4, - 0,0,115,2,0,0,0,0,1,122,22,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,95,108,101,110,95, - 95,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,100, - 1,160,0,124,0,106,1,161,1,83,0,41,2,78,122,20, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,40,123, - 33,114,125,41,41,2,114,88,0,0,0,114,47,1,0,0, - 114,13,1,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,8,95,95,114,101,112,114,95,95,239,4, - 0,0,115,2,0,0,0,0,1,122,23,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,95,114,101,112,114, + 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, + 0,0,0,114,12,1,0,0,114,69,0,0,0,114,13,1, + 0,0,114,15,1,0,0,114,7,0,0,0,114,7,0,0, + 0,114,8,0,0,0,114,16,1,0,0,143,4,0,0,114, + 17,1,0,0,122,26,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,95, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,114,18,1,0,0,114,69, + 0,0,0,114,19,1,0,0,114,21,1,0,0,114,7,0, + 0,0,114,7,0,0,0,114,8,0,0,0,114,22,1,0, + 0,147,4,0,0,114,23,1,0,0,122,28,69,120,116,101, + 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, + 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,5,0,0,0,67,0,0, + 0,115,36,0,0,0,116,0,160,1,116,2,106,3,124,1, + 161,2,125,2,116,0,160,4,100,1,124,1,106,5,124,0, + 106,6,161,3,1,0,124,2,83,0,41,2,122,38,67,114, + 101,97,116,101,32,97,110,32,117,110,105,116,105,97,108,105, + 122,101,100,32,101,120,116,101,110,115,105,111,110,32,109,111, + 100,117,108,101,122,38,101,120,116,101,110,115,105,111,110,32, + 109,111,100,117,108,101,32,123,33,114,125,32,108,111,97,100, + 101,100,32,102,114,111,109,32,123,33,114,125,41,7,114,159, + 0,0,0,114,242,0,0,0,114,187,0,0,0,90,14,99, + 114,101,97,116,101,95,100,121,110,97,109,105,99,114,173,0, + 0,0,114,141,0,0,0,114,65,0,0,0,41,3,114,143, + 0,0,0,114,210,0,0,0,114,244,0,0,0,114,7,0, + 0,0,114,7,0,0,0,114,8,0,0,0,114,239,0,0, + 0,150,4,0,0,115,14,0,0,0,4,2,6,1,4,255, + 6,2,8,1,4,255,4,2,122,33,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,99,114, + 101,97,116,101,95,109,111,100,117,108,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,5,0,0,0, + 67,0,0,0,115,36,0,0,0,116,0,160,1,116,2,106, + 3,124,1,161,2,1,0,116,0,160,4,100,1,124,0,106, + 5,124,0,106,6,161,3,1,0,100,2,83,0,41,3,122, + 30,73,110,105,116,105,97,108,105,122,101,32,97,110,32,101, + 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,122, + 40,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, + 101,32,123,33,114,125,32,101,120,101,99,117,116,101,100,32, + 102,114,111,109,32,123,33,114,125,78,41,7,114,159,0,0, + 0,114,242,0,0,0,114,187,0,0,0,90,12,101,120,101, + 99,95,100,121,110,97,109,105,99,114,173,0,0,0,114,141, + 0,0,0,114,65,0,0,0,169,2,114,143,0,0,0,114, + 244,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,114,245,0,0,0,158,4,0,0,115,8,0,0, + 0,14,2,6,1,8,1,8,255,122,31,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,3, + 0,0,0,115,36,0,0,0,116,0,124,0,106,1,131,1, + 100,1,25,0,137,0,116,2,135,0,102,1,100,2,100,3, + 132,8,116,3,68,0,131,1,131,1,83,0,41,4,122,49, + 82,101,116,117,114,110,32,84,114,117,101,32,105,102,32,116, + 104,101,32,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,32,105,115,32,97,32,112,97,99,107,97,103,101, + 46,114,3,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,51,0,0,0,115, + 28,0,0,0,129,0,124,0,93,9,125,1,136,0,100,0, + 124,1,23,0,107,2,86,0,1,0,113,2,100,1,83,0, + 41,2,114,236,0,0,0,78,114,7,0,0,0,169,2,114, + 5,0,0,0,218,6,115,117,102,102,105,120,169,1,90,9, + 102,105,108,101,95,110,97,109,101,114,7,0,0,0,114,8, + 0,0,0,114,9,0,0,0,167,4,0,0,115,8,0,0, + 0,2,128,4,0,2,1,20,255,122,49,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,46,60,108,111,99,97,108, + 115,62,46,60,103,101,110,101,120,112,114,62,41,4,114,74, + 0,0,0,114,65,0,0,0,218,3,97,110,121,114,232,0, + 0,0,114,247,0,0,0,114,7,0,0,0,114,45,1,0, + 0,114,8,0,0,0,114,206,0,0,0,164,4,0,0,115, + 8,0,0,0,14,2,12,1,2,1,8,255,122,30,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,105,115,95,112,97,99,107,97,103,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,114,23,0,0,0,41,2,122,63,82,101, + 116,117,114,110,32,78,111,110,101,32,97,115,32,97,110,32, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 32,99,97,110,110,111,116,32,99,114,101,97,116,101,32,97, + 32,99,111,100,101,32,111,98,106,101,99,116,46,78,114,7, + 0,0,0,114,247,0,0,0,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,114,241,0,0,0,170,4,0,0, + 114,24,0,0,0,122,28,69,120,116,101,110,115,105,111,110, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,99, + 111,100,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,1,0,0,0,67,0,0,0,114,23,0,0, + 0,41,2,122,53,82,101,116,117,114,110,32,78,111,110,101, + 32,97,115,32,101,120,116,101,110,115,105,111,110,32,109,111, + 100,117,108,101,115,32,104,97,118,101,32,110,111,32,115,111, + 117,114,99,101,32,99,111,100,101,46,78,114,7,0,0,0, + 114,247,0,0,0,114,7,0,0,0,114,7,0,0,0,114, + 8,0,0,0,114,1,1,0,0,174,4,0,0,114,24,0, + 0,0,122,30,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, + 99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,114,26,1,0,0, + 114,27,1,0,0,114,71,0,0,0,114,247,0,0,0,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,203, + 0,0,0,178,4,0,0,114,28,1,0,0,122,32,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,103,101,116,95,102,105,108,101,110,97,109,101,78,41, + 14,114,150,0,0,0,114,149,0,0,0,114,151,0,0,0, + 114,152,0,0,0,114,236,0,0,0,114,16,1,0,0,114, + 22,1,0,0,114,239,0,0,0,114,245,0,0,0,114,206, + 0,0,0,114,241,0,0,0,114,1,1,0,0,114,160,0, + 0,0,114,203,0,0,0,114,7,0,0,0,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,114,30,1,0,0, + 131,4,0,0,115,24,0,0,0,8,0,4,2,8,6,8, + 4,8,4,8,3,8,8,8,6,8,6,8,4,2,4,14, + 1,114,30,1,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115, + 108,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, + 100,2,90,4,100,3,100,4,132,0,90,5,100,5,100,6, + 132,0,90,6,100,7,100,8,132,0,90,7,100,9,100,10, + 132,0,90,8,100,11,100,12,132,0,90,9,100,13,100,14, + 132,0,90,10,100,15,100,16,132,0,90,11,100,17,100,18, + 132,0,90,12,100,19,100,20,132,0,90,13,100,21,100,22, + 132,0,90,14,100,23,100,24,132,0,90,15,100,25,83,0, + 41,26,218,14,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,97,38,1,0,0,82,101,112,114,101,115,101,110,116, + 115,32,97,32,110,97,109,101,115,112,97,99,101,32,112,97, + 99,107,97,103,101,39,115,32,112,97,116,104,46,32,32,73, + 116,32,117,115,101,115,32,116,104,101,32,109,111,100,117,108, + 101,32,110,97,109,101,10,32,32,32,32,116,111,32,102,105, + 110,100,32,105,116,115,32,112,97,114,101,110,116,32,109,111, + 100,117,108,101,44,32,97,110,100,32,102,114,111,109,32,116, + 104,101,114,101,32,105,116,32,108,111,111,107,115,32,117,112, + 32,116,104,101,32,112,97,114,101,110,116,39,115,10,32,32, + 32,32,95,95,112,97,116,104,95,95,46,32,32,87,104,101, + 110,32,116,104,105,115,32,99,104,97,110,103,101,115,44,32, + 116,104,101,32,109,111,100,117,108,101,39,115,32,111,119,110, + 32,112,97,116,104,32,105,115,32,114,101,99,111,109,112,117, + 116,101,100,44,10,32,32,32,32,117,115,105,110,103,32,112, + 97,116,104,95,102,105,110,100,101,114,46,32,32,70,111,114, + 32,116,111,112,45,108,101,118,101,108,32,109,111,100,117,108, + 101,115,44,32,116,104,101,32,112,97,114,101,110,116,32,109, + 111,100,117,108,101,39,115,32,112,97,116,104,10,32,32,32, + 32,105,115,32,115,121,115,46,112,97,116,104,46,114,0,0, + 0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,3,0,0,0,67,0,0,0,115,44,0,0,0, + 124,1,124,0,95,0,124,2,124,0,95,1,116,2,124,0, + 160,3,161,0,131,1,124,0,95,4,124,0,106,5,124,0, + 95,6,124,3,124,0,95,7,100,0,83,0,114,69,0,0, + 0,41,8,218,5,95,110,97,109,101,218,5,95,112,97,116, + 104,114,136,0,0,0,218,16,95,103,101,116,95,112,97,114, + 101,110,116,95,112,97,116,104,218,17,95,108,97,115,116,95, + 112,97,114,101,110,116,95,112,97,116,104,218,6,95,101,112, + 111,99,104,218,11,95,108,97,115,116,95,101,112,111,99,104, + 218,12,95,112,97,116,104,95,102,105,110,100,101,114,169,4, + 114,143,0,0,0,114,141,0,0,0,114,65,0,0,0,90, + 11,112,97,116,104,95,102,105,110,100,101,114,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,114,236,0,0,0, + 195,4,0,0,115,10,0,0,0,6,1,6,1,14,1,8, + 1,10,1,122,23,95,78,97,109,101,115,112,97,99,101,80, + 97,116,104,46,95,95,105,110,105,116,95,95,99,1,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,3,0,0, + 0,67,0,0,0,115,38,0,0,0,124,0,106,0,160,1, + 100,1,161,1,92,3,125,1,125,2,125,3,124,2,100,2, + 107,2,114,15,100,3,83,0,124,1,100,4,102,2,83,0, + 41,5,122,62,82,101,116,117,114,110,115,32,97,32,116,117, + 112,108,101,32,111,102,32,40,112,97,114,101,110,116,45,109, + 111,100,117,108,101,45,110,97,109,101,44,32,112,97,114,101, + 110,116,45,112,97,116,104,45,97,116,116,114,45,110,97,109, + 101,41,114,97,0,0,0,114,10,0,0,0,41,2,114,15, + 0,0,0,114,65,0,0,0,90,8,95,95,112,97,116,104, + 95,95,41,2,114,48,1,0,0,114,104,0,0,0,41,4, + 114,143,0,0,0,114,40,1,0,0,218,3,100,111,116,90, + 2,109,101,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,218,23,95,102,105,110,100,95,112,97,114,101,110,116, + 95,112,97,116,104,95,110,97,109,101,115,202,4,0,0,115, + 8,0,0,0,18,2,8,1,4,2,8,3,122,38,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,102,105, + 110,100,95,112,97,114,101,110,116,95,112,97,116,104,95,110, + 97,109,101,115,99,1,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,3,0,0,0,67,0,0,0,115,28,0, + 0,0,124,0,160,0,161,0,92,2,125,1,125,2,116,1, + 116,2,106,3,124,1,25,0,124,2,131,2,83,0,114,69, + 0,0,0,41,4,114,57,1,0,0,114,155,0,0,0,114, + 15,0,0,0,218,7,109,111,100,117,108,101,115,41,3,114, + 143,0,0,0,90,18,112,97,114,101,110,116,95,109,111,100, + 117,108,101,95,110,97,109,101,90,14,112,97,116,104,95,97, + 116,116,114,95,110,97,109,101,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,114,50,1,0,0,212,4,0,0, + 115,4,0,0,0,12,1,16,1,122,31,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,103,101,116,95,112, + 97,114,101,110,116,95,112,97,116,104,99,1,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,4,0,0,0,67, + 0,0,0,115,100,0,0,0,116,0,124,0,160,1,161,0, + 131,1,125,1,124,1,124,0,106,2,107,3,115,17,124,0, + 106,3,124,0,106,4,107,3,114,47,124,0,160,5,124,0, + 106,6,124,1,161,2,125,2,124,2,100,0,117,1,114,40, + 124,2,106,7,100,0,117,0,114,40,124,2,106,8,114,40, + 124,2,106,8,124,0,95,9,124,1,124,0,95,2,124,0, + 106,3,124,0,95,4,124,0,106,9,83,0,114,69,0,0, + 0,41,10,114,136,0,0,0,114,50,1,0,0,114,51,1, + 0,0,114,52,1,0,0,114,53,1,0,0,114,54,1,0, + 0,114,48,1,0,0,114,164,0,0,0,114,202,0,0,0, + 114,49,1,0,0,41,3,114,143,0,0,0,90,11,112,97, + 114,101,110,116,95,112,97,116,104,114,210,0,0,0,114,7, + 0,0,0,114,7,0,0,0,114,8,0,0,0,218,12,95, + 114,101,99,97,108,99,117,108,97,116,101,216,4,0,0,115, + 18,0,0,0,12,2,22,1,14,1,18,3,6,1,8,1, + 6,1,8,1,6,1,122,27,95,78,97,109,101,115,112,97, + 99,101,80,97,116,104,46,95,114,101,99,97,108,99,117,108, + 97,116,101,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,67,0,0,0,243,12,0,0, + 0,116,0,124,0,160,1,161,0,131,1,83,0,114,69,0, + 0,0,41,2,218,4,105,116,101,114,114,59,1,0,0,114, + 21,1,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,218,8,95,95,105,116,101,114,95,95,230,4,0, + 0,243,2,0,0,0,12,1,122,23,95,78,97,109,101,115, + 112,97,99,101,80,97,116,104,46,95,95,105,116,101,114,95, + 95,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,2,0,0,0,67,0,0,0,115,12,0,0,0,124, + 0,160,0,161,0,124,1,25,0,83,0,114,69,0,0,0, + 169,1,114,59,1,0,0,41,2,114,143,0,0,0,218,5, + 105,110,100,101,120,114,7,0,0,0,114,7,0,0,0,114, + 8,0,0,0,218,11,95,95,103,101,116,105,116,101,109,95, + 95,233,4,0,0,114,63,1,0,0,122,26,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,95,103,101,116, + 105,116,101,109,95,95,99,3,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, + 14,0,0,0,124,2,124,0,106,0,124,1,60,0,100,0, + 83,0,114,69,0,0,0,41,1,114,49,1,0,0,41,3, + 114,143,0,0,0,114,65,1,0,0,114,65,0,0,0,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,218,11, + 95,95,115,101,116,105,116,101,109,95,95,236,4,0,0,115, + 2,0,0,0,14,1,122,26,95,78,97,109,101,115,112,97, + 99,101,80,97,116,104,46,95,95,115,101,116,105,116,101,109, + 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,114,60,1,0,0, + 114,69,0,0,0,41,2,114,4,0,0,0,114,59,1,0, + 0,114,21,1,0,0,114,7,0,0,0,114,7,0,0,0, + 114,8,0,0,0,218,7,95,95,108,101,110,95,95,239,4, + 0,0,114,63,1,0,0,122,22,95,78,97,109,101,115,112, + 97,99,101,80,97,116,104,46,95,95,108,101,110,95,95,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,243,12,0,0,0,100,1,160, + 0,124,0,106,1,161,1,83,0,41,2,78,122,20,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,40,123,33,114, + 125,41,41,2,114,89,0,0,0,114,49,1,0,0,114,21, + 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,218,8,95,95,114,101,112,114,95,95,242,4,0,0, + 114,63,1,0,0,122,23,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,95,95,114,101,112,114,95,95,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,67,0,0,0,115,12,0,0,0,124,1,124,0, + 160,0,161,0,118,0,83,0,114,69,0,0,0,114,64,1, + 0,0,169,2,114,143,0,0,0,218,4,105,116,101,109,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,218,12, + 95,95,99,111,110,116,97,105,110,115,95,95,245,4,0,0, + 114,63,1,0,0,122,27,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,95,95,99,111,110,116,97,105,110,115, 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,67,0,0,0,115,12,0,0,0, - 124,1,124,0,160,0,161,0,118,0,83,0,114,69,0,0, - 0,114,59,1,0,0,169,2,114,142,0,0,0,218,4,105, - 116,101,109,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,12,95,95,99,111,110,116,97,105,110,115,95,95, - 242,4,0,0,115,2,0,0,0,0,1,122,27,95,78,97, - 109,101,115,112,97,99,101,80,97,116,104,46,95,95,99,111, - 110,116,97,105,110,115,95,95,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, - 0,115,16,0,0,0,124,0,106,0,160,1,124,1,161,1, - 1,0,100,0,83,0,114,69,0,0,0,41,2,114,47,1, - 0,0,114,61,0,0,0,114,65,1,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,61,0,0,0, - 245,4,0,0,115,2,0,0,0,0,1,122,21,95,78,97, - 109,101,115,112,97,99,101,80,97,116,104,46,97,112,112,101, - 110,100,78,41,16,114,149,0,0,0,114,148,0,0,0,114, - 150,0,0,0,114,151,0,0,0,114,50,1,0,0,114,232, - 0,0,0,114,55,1,0,0,114,48,1,0,0,114,57,1, - 0,0,114,58,1,0,0,114,61,1,0,0,114,62,1,0, - 0,114,63,1,0,0,114,64,1,0,0,114,67,1,0,0, - 114,61,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,45,1,0,0,181,4, - 0,0,115,26,0,0,0,8,1,4,8,4,2,8,7,8, - 10,8,4,8,14,8,3,8,3,8,3,8,3,8,3,8, - 3,114,45,1,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, - 80,0,0,0,101,0,90,1,100,0,90,2,100,1,100,2, - 132,0,90,3,101,4,100,3,100,4,132,0,131,1,90,5, - 100,5,100,6,132,0,90,6,100,7,100,8,132,0,90,7, - 100,9,100,10,132,0,90,8,100,11,100,12,132,0,90,9, - 100,13,100,14,132,0,90,10,100,15,100,16,132,0,90,11, - 100,17,83,0,41,18,218,16,95,78,97,109,101,115,112,97, - 99,101,76,111,97,100,101,114,99,4,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,4,0,0,0,67,0,0, - 0,115,18,0,0,0,116,0,124,1,124,2,124,3,131,3, - 124,0,95,1,100,0,83,0,114,69,0,0,0,41,2,114, - 45,1,0,0,114,47,1,0,0,114,53,1,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,232,0, - 0,0,251,4,0,0,115,2,0,0,0,0,1,122,25,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 95,95,105,110,105,116,95,95,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, - 0,115,12,0,0,0,100,1,160,0,124,1,106,1,161,1, - 83,0,41,2,122,115,82,101,116,117,114,110,32,114,101,112, + 0,0,0,3,0,0,0,67,0,0,0,115,16,0,0,0, + 124,0,106,0,160,1,124,1,161,1,1,0,100,0,83,0, + 114,69,0,0,0,41,2,114,49,1,0,0,114,61,0,0, + 0,114,71,1,0,0,114,7,0,0,0,114,7,0,0,0, + 114,8,0,0,0,114,61,0,0,0,248,4,0,0,243,2, + 0,0,0,16,1,122,21,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,97,112,112,101,110,100,78,41,16,114, + 150,0,0,0,114,149,0,0,0,114,151,0,0,0,114,152, + 0,0,0,114,52,1,0,0,114,236,0,0,0,114,57,1, + 0,0,114,50,1,0,0,114,59,1,0,0,114,62,1,0, + 0,114,66,1,0,0,114,67,1,0,0,114,68,1,0,0, + 114,70,1,0,0,114,73,1,0,0,114,61,0,0,0,114, + 7,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, + 0,0,0,114,47,1,0,0,184,4,0,0,115,28,0,0, + 0,8,0,4,1,4,8,8,2,8,7,8,10,8,4,8, + 14,8,3,8,3,8,3,8,3,8,3,12,3,114,47,1, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,64,0,0,0,115,88,0,0,0, + 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, + 101,4,100,3,100,4,132,0,131,1,90,5,100,5,100,6, + 132,0,90,6,100,7,100,8,132,0,90,7,100,9,100,10, + 132,0,90,8,100,11,100,12,132,0,90,9,100,13,100,14, + 132,0,90,10,100,15,100,16,132,0,90,11,100,17,100,18, + 132,0,90,12,100,19,83,0,41,20,218,16,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,99,4,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, + 0,67,0,0,0,115,18,0,0,0,116,0,124,1,124,2, + 124,3,131,3,124,0,95,1,100,0,83,0,114,69,0,0, + 0,41,2,114,47,1,0,0,114,49,1,0,0,114,55,1, + 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, + 0,114,236,0,0,0,254,4,0,0,115,2,0,0,0,18, + 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, + 100,101,114,46,95,95,105,110,105,116,95,95,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,67,0,0,0,115,24,0,0,0,116,0,160,1,100,1, + 116,2,161,2,1,0,100,2,160,3,124,0,106,4,161,1, + 83,0,41,3,122,115,82,101,116,117,114,110,32,114,101,112, 114,32,102,111,114,32,116,104,101,32,109,111,100,117,108,101, 46,10,10,32,32,32,32,32,32,32,32,84,104,101,32,109, 101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97, 116,101,100,46,32,32,84,104,101,32,105,109,112,111,114,116, 32,109,97,99,104,105,110,101,114,121,32,100,111,101,115,32, 116,104,101,32,106,111,98,32,105,116,115,101,108,102,46,10, - 10,32,32,32,32,32,32,32,32,122,25,60,109,111,100,117, - 108,101,32,123,33,114,125,32,40,110,97,109,101,115,112,97, - 99,101,41,62,41,2,114,88,0,0,0,114,149,0,0,0, - 41,2,114,216,0,0,0,114,239,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,11,109,111,100, - 117,108,101,95,114,101,112,114,254,4,0,0,115,2,0,0, - 0,0,7,122,28,95,78,97,109,101,115,112,97,99,101,76, - 111,97,100,101,114,46,109,111,100,117,108,101,95,114,101,112, - 114,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, - 1,83,0,41,2,78,84,114,10,0,0,0,114,242,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,206,0,0,0,7,5,0,0,115,2,0,0,0,0,1, + 10,32,32,32,32,32,32,32,32,122,82,95,78,97,109,101, + 115,112,97,99,101,76,111,97,100,101,114,46,109,111,100,117, + 108,101,95,114,101,112,114,40,41,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,32,97,110,100,32,115,108,97,116, + 101,100,32,102,111,114,32,114,101,109,111,118,97,108,32,105, + 110,32,80,121,116,104,111,110,32,51,46,49,50,122,25,60, + 109,111,100,117,108,101,32,123,33,114,125,32,40,110,97,109, + 101,115,112,97,99,101,41,62,41,5,114,99,0,0,0,114, + 100,0,0,0,114,101,0,0,0,114,89,0,0,0,114,150, + 0,0,0,41,1,114,244,0,0,0,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,218,11,109,111,100,117,108, + 101,95,114,101,112,114,1,5,0,0,115,8,0,0,0,6, + 7,2,1,4,255,12,2,122,28,95,78,97,109,101,115,112, + 97,99,101,76,111,97,100,101,114,46,109,111,100,117,108,101, + 95,114,101,112,114,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,114,23, + 0,0,0,41,2,78,84,114,7,0,0,0,114,247,0,0, + 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, + 114,206,0,0,0,12,5,0,0,243,2,0,0,0,4,1, 122,27,95,78,97,109,101,115,112,97,99,101,76,111,97,100, 101,114,46,105,115,95,112,97,99,107,97,103,101,99,2,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,78,114,14,0,0,0,114,10,0,0,0,114,242,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,252,0,0,0,10,5,0,0,115,2,0,0,0,0,1, - 122,27,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,103,101,116,95,115,111,117,114,99,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,6,0, - 0,0,67,0,0,0,115,16,0,0,0,116,0,100,1,100, - 2,100,3,100,4,100,5,141,4,83,0,41,6,78,114,14, - 0,0,0,122,8,60,115,116,114,105,110,103,62,114,238,0, - 0,0,84,41,1,114,254,0,0,0,41,1,114,255,0,0, - 0,114,242,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,236,0,0,0,13,5,0,0,115,2, - 0,0,0,0,1,122,25,95,78,97,109,101,115,112,97,99, - 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, - 83,0,114,233,0,0,0,114,10,0,0,0,114,234,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,235,0,0,0,16,5,0,0,115,2,0,0,0,0,1, - 122,30,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,99,114,101,97,116,101,95,109,111,100,117,108,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,0, - 83,0,114,69,0,0,0,114,10,0,0,0,114,20,1,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,240,0,0,0,19,5,0,0,115,2,0,0,0,0,1, + 0,0,67,0,0,0,114,23,0,0,0,41,2,78,114,10, + 0,0,0,114,7,0,0,0,114,247,0,0,0,114,7,0, + 0,0,114,7,0,0,0,114,8,0,0,0,114,1,1,0, + 0,15,5,0,0,114,77,1,0,0,122,27,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,46,103,101,116, + 95,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,6,0,0,0,67,0,0,0, + 115,16,0,0,0,116,0,100,1,100,2,100,3,100,4,100, + 5,141,4,83,0,41,6,78,114,10,0,0,0,122,8,60, + 115,116,114,105,110,103,62,114,243,0,0,0,84,41,1,114, + 3,1,0,0,41,1,114,4,1,0,0,114,247,0,0,0, + 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,114, + 241,0,0,0,18,5,0,0,114,74,1,0,0,122,25,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,114,23,0,0,0,114,237,0,0,0,114,7,0,0,0, + 114,238,0,0,0,114,7,0,0,0,114,7,0,0,0,114, + 8,0,0,0,114,239,0,0,0,21,5,0,0,114,240,0, + 0,0,122,30,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,99,114,101,97,116,101,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 100,0,83,0,114,69,0,0,0,114,7,0,0,0,114,42, + 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,245,0,0,0,24,5,0,0,114,77,1,0,0, 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, 101,114,46,101,120,101,99,95,109,111,100,117,108,101,99,2, 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, @@ -2125,249 +2097,282 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 100,46,10,10,32,32,32,32,32,32,32,32,122,38,110,97, 109,101,115,112,97,99,101,32,109,111,100,117,108,101,32,108, 111,97,100,101,100,32,119,105,116,104,32,112,97,116,104,32, - 123,33,114,125,41,4,114,158,0,0,0,114,173,0,0,0, - 114,47,1,0,0,114,241,0,0,0,114,242,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,243, - 0,0,0,22,5,0,0,115,8,0,0,0,0,7,6,1, - 4,255,4,2,122,28,95,78,97,109,101,115,112,97,99,101, + 123,33,114,125,41,4,114,159,0,0,0,114,173,0,0,0, + 114,49,1,0,0,114,246,0,0,0,114,247,0,0,0,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,248, + 0,0,0,27,5,0,0,115,8,0,0,0,6,7,4,1, + 4,255,12,3,122,28,95,78,97,109,101,115,112,97,99,101, 76,111,97,100,101,114,46,108,111,97,100,95,109,111,100,117, - 108,101,78,41,12,114,149,0,0,0,114,148,0,0,0,114, - 150,0,0,0,114,232,0,0,0,114,230,0,0,0,114,69, - 1,0,0,114,206,0,0,0,114,252,0,0,0,114,236,0, - 0,0,114,235,0,0,0,114,240,0,0,0,114,243,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,68,1,0,0,250,4,0,0,115,18, - 0,0,0,8,1,8,3,2,1,10,8,8,3,8,3,8, - 3,8,3,8,3,114,68,1,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,64, - 0,0,0,115,118,0,0,0,101,0,90,1,100,0,90,2, - 100,1,90,3,101,4,100,2,100,3,132,0,131,1,90,5, - 101,4,100,4,100,5,132,0,131,1,90,6,101,4,100,6, - 100,7,132,0,131,1,90,7,101,4,100,8,100,9,132,0, - 131,1,90,8,101,4,100,19,100,11,100,12,132,1,131,1, - 90,9,101,4,100,20,100,13,100,14,132,1,131,1,90,10, - 101,4,100,21,100,15,100,16,132,1,131,1,90,11,101,4, - 100,17,100,18,132,0,131,1,90,12,100,10,83,0,41,22, - 218,10,80,97,116,104,70,105,110,100,101,114,122,62,77,101, - 116,97,32,112,97,116,104,32,102,105,110,100,101,114,32,102, - 111,114,32,115,121,115,46,112,97,116,104,32,97,110,100,32, - 112,97,99,107,97,103,101,32,95,95,112,97,116,104,95,95, - 32,97,116,116,114,105,98,117,116,101,115,46,99,1,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, - 0,67,0,0,0,115,78,0,0,0,116,0,116,1,106,2, - 160,3,161,0,131,1,68,0,93,44,92,2,125,1,125,2, - 124,2,100,1,117,0,114,40,116,1,106,2,124,1,61,0, - 113,14,116,4,124,2,100,2,131,2,114,14,124,2,160,5, - 161,0,1,0,113,14,116,6,4,0,106,7,100,3,55,0, - 2,0,95,7,100,1,83,0,41,4,122,125,67,97,108,108, - 32,116,104,101,32,105,110,118,97,108,105,100,97,116,101,95, - 99,97,99,104,101,115,40,41,32,109,101,116,104,111,100,32, - 111,110,32,97,108,108,32,112,97,116,104,32,101,110,116,114, - 121,32,102,105,110,100,101,114,115,10,32,32,32,32,32,32, - 32,32,115,116,111,114,101,100,32,105,110,32,115,121,115,46, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,2,0,0,0,67,0,0,0,115,22,0,0,0, + 100,1,100,2,108,0,109,1,125,2,1,0,124,2,124,0, + 106,2,131,1,83,0,41,3,78,114,0,0,0,0,41,1, + 218,15,78,97,109,101,115,112,97,99,101,82,101,97,100,101, + 114,41,3,114,32,1,0,0,114,78,1,0,0,114,49,1, + 0,0,41,3,114,143,0,0,0,114,244,0,0,0,114,78, + 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,33,1,0,0,39,5,0,0,115,4,0,0,0, + 12,1,10,1,122,36,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,101,114,46,103,101,116,95,114,101,115,111,117, + 114,99,101,95,114,101,97,100,101,114,78,41,13,114,150,0, + 0,0,114,149,0,0,0,114,151,0,0,0,114,236,0,0, + 0,114,233,0,0,0,114,76,1,0,0,114,206,0,0,0, + 114,1,1,0,0,114,241,0,0,0,114,239,0,0,0,114, + 245,0,0,0,114,248,0,0,0,114,33,1,0,0,114,7, + 0,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,75,1,0,0,253,4,0,0,115,22,0,0,0, + 8,0,8,1,2,3,10,1,8,10,8,3,8,3,8,3, + 8,3,8,3,12,12,114,75,1,0,0,99,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 64,0,0,0,115,118,0,0,0,101,0,90,1,100,0,90, + 2,100,1,90,3,101,4,100,2,100,3,132,0,131,1,90, + 5,101,4,100,4,100,5,132,0,131,1,90,6,101,7,100, + 6,100,7,132,0,131,1,90,8,101,7,100,8,100,9,132, + 0,131,1,90,9,101,7,100,19,100,11,100,12,132,1,131, + 1,90,10,101,7,100,20,100,13,100,14,132,1,131,1,90, + 11,101,7,100,19,100,15,100,16,132,1,131,1,90,12,101, + 4,100,17,100,18,132,0,131,1,90,13,100,10,83,0,41, + 21,218,10,80,97,116,104,70,105,110,100,101,114,122,62,77, + 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32, + 102,111,114,32,115,121,115,46,112,97,116,104,32,97,110,100, + 32,112,97,99,107,97,103,101,32,95,95,112,97,116,104,95, + 95,32,97,116,116,114,105,98,117,116,101,115,46,99,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,67,0,0,0,115,78,0,0,0,116,0,116,1,106, + 2,160,3,161,0,131,1,68,0,93,22,92,2,125,0,125, + 1,124,1,100,1,117,0,114,20,116,1,106,2,124,0,61, + 0,113,7,116,4,124,1,100,2,131,2,114,29,124,1,160, + 5,161,0,1,0,113,7,116,6,4,0,106,7,100,3,55, + 0,2,0,95,7,100,1,83,0,41,4,122,125,67,97,108, + 108,32,116,104,101,32,105,110,118,97,108,105,100,97,116,101, + 95,99,97,99,104,101,115,40,41,32,109,101,116,104,111,100, + 32,111,110,32,97,108,108,32,112,97,116,104,32,101,110,116, + 114,121,32,102,105,110,100,101,114,115,10,32,32,32,32,32, + 32,32,32,115,116,111,114,101,100,32,105,110,32,115,121,115, + 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, + 97,99,104,101,115,32,40,119,104,101,114,101,32,105,109,112, + 108,101,109,101,110,116,101,100,41,46,78,218,17,105,110,118, + 97,108,105,100,97,116,101,95,99,97,99,104,101,115,114,3, + 0,0,0,41,8,218,4,108,105,115,116,114,15,0,0,0, + 218,19,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,218,5,105,116,101,109,115,114,153,0,0, + 0,114,80,1,0,0,114,47,1,0,0,114,52,1,0,0, + 41,2,114,141,0,0,0,218,6,102,105,110,100,101,114,114, + 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,80, + 1,0,0,50,5,0,0,115,14,0,0,0,22,4,8,1, + 10,1,10,1,8,1,2,128,18,3,122,28,80,97,116,104, + 70,105,110,100,101,114,46,105,110,118,97,108,105,100,97,116, + 101,95,99,97,99,104,101,115,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,9,0,0,0,67,0,0, + 0,115,76,0,0,0,116,0,106,1,100,1,117,1,114,14, + 116,0,106,1,115,14,116,2,160,3,100,2,116,4,161,2, + 1,0,116,0,106,1,68,0,93,18,125,1,122,7,124,1, + 124,0,131,1,87,0,2,0,1,0,83,0,4,0,116,5, + 121,35,1,0,1,0,1,0,89,0,113,17,119,0,100,1, + 83,0,41,3,122,46,83,101,97,114,99,104,32,115,121,115, + 46,112,97,116,104,95,104,111,111,107,115,32,102,111,114,32, + 97,32,102,105,110,100,101,114,32,102,111,114,32,39,112,97, + 116,104,39,46,78,122,23,115,121,115,46,112,97,116,104,95, + 104,111,111,107,115,32,105,115,32,101,109,112,116,121,41,6, + 114,15,0,0,0,218,10,112,97,116,104,95,104,111,111,107, + 115,114,99,0,0,0,114,100,0,0,0,114,162,0,0,0, + 114,142,0,0,0,41,2,114,65,0,0,0,90,4,104,111, + 111,107,114,7,0,0,0,114,7,0,0,0,114,8,0,0, + 0,218,11,95,112,97,116,104,95,104,111,111,107,115,63,5, + 0,0,115,18,0,0,0,16,3,12,1,10,1,2,1,14, + 1,12,1,4,1,2,255,4,3,122,22,80,97,116,104,70, + 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, + 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,8,0,0,0,67,0,0,0,115,100,0,0,0,124, + 1,100,1,107,2,114,21,122,6,116,0,160,1,161,0,125, + 1,87,0,110,10,4,0,116,2,121,20,1,0,1,0,1, + 0,89,0,100,2,83,0,119,0,122,8,116,3,106,4,124, + 1,25,0,125,2,87,0,124,2,83,0,4,0,116,5,121, + 49,1,0,1,0,1,0,124,0,160,6,124,1,161,1,125, + 2,124,2,116,3,106,4,124,1,60,0,89,0,124,2,83, + 0,119,0,41,3,122,210,71,101,116,32,116,104,101,32,102, + 105,110,100,101,114,32,102,111,114,32,116,104,101,32,112,97, + 116,104,32,101,110,116,114,121,32,102,114,111,109,32,115,121, + 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,46,10,10,32,32,32,32,32,32,32,32, + 73,102,32,116,104,101,32,112,97,116,104,32,101,110,116,114, + 121,32,105,115,32,110,111,116,32,105,110,32,116,104,101,32, + 99,97,99,104,101,44,32,102,105,110,100,32,116,104,101,32, + 97,112,112,114,111,112,114,105,97,116,101,32,102,105,110,100, + 101,114,10,32,32,32,32,32,32,32,32,97,110,100,32,99, + 97,99,104,101,32,105,116,46,32,73,102,32,110,111,32,102, + 105,110,100,101,114,32,105,115,32,97,118,97,105,108,97,98, + 108,101,44,32,115,116,111,114,101,32,78,111,110,101,46,10, + 10,32,32,32,32,32,32,32,32,114,10,0,0,0,78,41, + 7,114,18,0,0,0,114,82,0,0,0,218,17,70,105,108, + 101,78,111,116,70,111,117,110,100,69,114,114,111,114,114,15, + 0,0,0,114,82,1,0,0,218,8,75,101,121,69,114,114, + 111,114,114,86,1,0,0,41,3,114,221,0,0,0,114,65, + 0,0,0,114,84,1,0,0,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,218,20,95,112,97,116,104,95,105, + 109,112,111,114,116,101,114,95,99,97,99,104,101,76,5,0, + 0,115,28,0,0,0,8,8,2,1,12,1,12,1,6,3, + 2,253,2,4,12,1,4,4,12,253,10,1,12,1,4,1, + 2,253,122,31,80,97,116,104,70,105,110,100,101,114,46,95, 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,115,32,40,119,104,101,114,101,32,105,109,112,108, - 101,109,101,110,116,101,100,41,46,78,218,17,105,110,118,97, - 108,105,100,97,116,101,95,99,97,99,104,101,115,114,4,0, - 0,0,41,8,218,4,108,105,115,116,114,21,0,0,0,218, - 19,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, - 97,99,104,101,218,5,105,116,101,109,115,114,152,0,0,0, - 114,71,1,0,0,114,45,1,0,0,114,50,1,0,0,41, - 3,114,216,0,0,0,114,140,0,0,0,218,6,102,105,110, - 100,101,114,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,71,1,0,0,40,5,0,0,115,12,0,0,0, - 0,4,22,1,8,1,10,1,10,1,10,3,122,28,80,97, - 116,104,70,105,110,100,101,114,46,105,110,118,97,108,105,100, - 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,9,0,0,0,67, - 0,0,0,115,82,0,0,0,116,0,106,1,100,1,117,1, - 114,28,116,0,106,1,115,28,116,2,160,3,100,2,116,4, - 161,2,1,0,116,0,106,1,68,0,93,42,125,2,122,14, - 124,2,124,1,131,1,87,0,2,0,1,0,83,0,4,0, - 116,5,121,74,1,0,1,0,1,0,89,0,113,34,89,0, - 113,34,48,0,113,34,100,1,83,0,41,3,122,46,83,101, - 97,114,99,104,32,115,121,115,46,112,97,116,104,95,104,111, - 111,107,115,32,102,111,114,32,97,32,102,105,110,100,101,114, - 32,102,111,114,32,39,112,97,116,104,39,46,78,122,23,115, - 121,115,46,112,97,116,104,95,104,111,111,107,115,32,105,115, - 32,101,109,112,116,121,41,6,114,21,0,0,0,218,10,112, - 97,116,104,95,104,111,111,107,115,114,98,0,0,0,114,99, - 0,0,0,114,162,0,0,0,114,141,0,0,0,41,3,114, - 216,0,0,0,114,65,0,0,0,90,4,104,111,111,107,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,11, - 95,112,97,116,104,95,104,111,111,107,115,53,5,0,0,115, - 16,0,0,0,0,3,16,1,12,1,10,1,2,1,14,1, - 12,1,12,2,122,22,80,97,116,104,70,105,110,100,101,114, - 46,95,112,97,116,104,95,104,111,111,107,115,99,2,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,8,0,0, - 0,67,0,0,0,115,100,0,0,0,124,1,100,1,107,2, - 114,42,122,12,116,0,160,1,161,0,125,1,87,0,110,20, - 4,0,116,2,121,40,1,0,1,0,1,0,89,0,100,2, - 83,0,48,0,122,14,116,3,106,4,124,1,25,0,125,2, - 87,0,110,38,4,0,116,5,121,94,1,0,1,0,1,0, - 124,0,160,6,124,1,161,1,125,2,124,2,116,3,106,4, - 124,1,60,0,89,0,110,2,48,0,124,2,83,0,41,3, - 122,210,71,101,116,32,116,104,101,32,102,105,110,100,101,114, - 32,102,111,114,32,116,104,101,32,112,97,116,104,32,101,110, - 116,114,121,32,102,114,111,109,32,115,121,115,46,112,97,116, - 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, - 46,10,10,32,32,32,32,32,32,32,32,73,102,32,116,104, - 101,32,112,97,116,104,32,101,110,116,114,121,32,105,115,32, - 110,111,116,32,105,110,32,116,104,101,32,99,97,99,104,101, - 44,32,102,105,110,100,32,116,104,101,32,97,112,112,114,111, - 112,114,105,97,116,101,32,102,105,110,100,101,114,10,32,32, - 32,32,32,32,32,32,97,110,100,32,99,97,99,104,101,32, - 105,116,46,32,73,102,32,110,111,32,102,105,110,100,101,114, - 32,105,115,32,97,118,97,105,108,97,98,108,101,44,32,115, - 116,111,114,101,32,78,111,110,101,46,10,10,32,32,32,32, - 32,32,32,32,114,14,0,0,0,78,41,7,114,24,0,0, - 0,114,81,0,0,0,114,26,1,0,0,114,21,0,0,0, - 114,73,1,0,0,218,8,75,101,121,69,114,114,111,114,114, - 77,1,0,0,41,3,114,216,0,0,0,114,65,0,0,0, - 114,75,1,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,20,95,112,97,116,104,95,105,109,112,111, - 114,116,101,114,95,99,97,99,104,101,66,5,0,0,115,22, - 0,0,0,0,8,8,1,2,1,12,1,12,3,8,1,2, - 1,14,1,12,1,10,1,16,1,122,31,80,97,116,104,70, - 105,110,100,101,114,46,95,112,97,116,104,95,105,109,112,111, - 114,116,101,114,95,99,97,99,104,101,99,3,0,0,0,0, - 0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,67, - 0,0,0,115,82,0,0,0,116,0,124,2,100,1,131,2, - 114,26,124,2,160,1,124,1,161,1,92,2,125,3,125,4, - 110,14,124,2,160,2,124,1,161,1,125,3,103,0,125,4, - 124,3,100,0,117,1,114,60,116,3,160,4,124,1,124,3, - 161,2,83,0,116,3,160,5,124,1,100,0,161,2,125,5, - 124,4,124,5,95,6,124,5,83,0,41,2,78,114,161,0, - 0,0,41,7,114,152,0,0,0,114,161,0,0,0,114,229, - 0,0,0,114,158,0,0,0,114,224,0,0,0,114,207,0, - 0,0,114,202,0,0,0,41,6,114,216,0,0,0,114,163, - 0,0,0,114,75,1,0,0,114,164,0,0,0,114,165,0, - 0,0,114,210,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,16,95,108,101,103,97,99,121,95, - 103,101,116,95,115,112,101,99,88,5,0,0,115,18,0,0, - 0,0,4,10,1,16,2,10,1,4,1,8,1,12,1,12, - 1,6,1,122,27,80,97,116,104,70,105,110,100,101,114,46, - 95,108,101,103,97,99,121,95,103,101,116,95,115,112,101,99, - 78,99,4,0,0,0,0,0,0,0,0,0,0,0,9,0, - 0,0,5,0,0,0,67,0,0,0,115,166,0,0,0,103, - 0,125,4,124,2,68,0,93,134,125,5,116,0,124,5,116, - 1,116,2,102,2,131,2,115,28,113,8,124,0,160,3,124, - 5,161,1,125,6,124,6,100,1,117,1,114,8,116,4,124, - 6,100,2,131,2,114,70,124,6,160,5,124,1,124,3,161, - 2,125,7,110,12,124,0,160,6,124,1,124,6,161,2,125, - 7,124,7,100,1,117,0,114,92,113,8,124,7,106,7,100, - 1,117,1,114,110,124,7,2,0,1,0,83,0,124,7,106, - 8,125,8,124,8,100,1,117,0,114,132,116,9,100,3,131, - 1,130,1,124,4,160,10,124,8,161,1,1,0,113,8,116, - 11,160,12,124,1,100,1,161,2,125,7,124,4,124,7,95, - 8,124,7,83,0,41,4,122,63,70,105,110,100,32,116,104, - 101,32,108,111,97,100,101,114,32,111,114,32,110,97,109,101, - 115,112,97,99,101,95,112,97,116,104,32,102,111,114,32,116, - 104,105,115,32,109,111,100,117,108,101,47,112,97,99,107,97, - 103,101,32,110,97,109,101,46,78,114,226,0,0,0,122,19, - 115,112,101,99,32,109,105,115,115,105,110,103,32,108,111,97, - 100,101,114,41,13,114,185,0,0,0,114,108,0,0,0,218, - 5,98,121,116,101,115,114,79,1,0,0,114,152,0,0,0, - 114,226,0,0,0,114,80,1,0,0,114,164,0,0,0,114, - 202,0,0,0,114,141,0,0,0,114,191,0,0,0,114,158, - 0,0,0,114,207,0,0,0,41,9,114,216,0,0,0,114, - 163,0,0,0,114,65,0,0,0,114,225,0,0,0,218,14, - 110,97,109,101,115,112,97,99,101,95,112,97,116,104,90,5, - 101,110,116,114,121,114,75,1,0,0,114,210,0,0,0,114, - 165,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,9,95,103,101,116,95,115,112,101,99,103,5, - 0,0,115,40,0,0,0,0,5,4,1,8,1,14,1,2, - 1,10,1,8,1,10,1,14,2,12,1,8,1,2,1,10, - 1,8,1,6,1,8,1,8,5,12,2,12,1,6,1,122, - 20,80,97,116,104,70,105,110,100,101,114,46,95,103,101,116, - 95,115,112,101,99,99,4,0,0,0,0,0,0,0,0,0, - 0,0,6,0,0,0,5,0,0,0,67,0,0,0,115,100, - 0,0,0,124,2,100,1,117,0,114,14,116,0,106,1,125, - 2,124,0,160,2,124,1,124,2,124,3,161,3,125,4,124, - 4,100,1,117,0,114,40,100,1,83,0,124,4,106,3,100, - 1,117,0,114,92,124,4,106,4,125,5,124,5,114,86,100, - 1,124,4,95,5,116,6,124,1,124,5,124,0,106,2,131, - 3,124,4,95,4,124,4,83,0,100,1,83,0,110,4,124, - 4,83,0,100,1,83,0,41,2,122,141,84,114,121,32,116, - 111,32,102,105,110,100,32,97,32,115,112,101,99,32,102,111, - 114,32,39,102,117,108,108,110,97,109,101,39,32,111,110,32, - 115,121,115,46,112,97,116,104,32,111,114,32,39,112,97,116, - 104,39,46,10,10,32,32,32,32,32,32,32,32,84,104,101, - 32,115,101,97,114,99,104,32,105,115,32,98,97,115,101,100, - 32,111,110,32,115,121,115,46,112,97,116,104,95,104,111,111, - 107,115,32,97,110,100,32,115,121,115,46,112,97,116,104,95, - 105,109,112,111,114,116,101,114,95,99,97,99,104,101,46,10, - 32,32,32,32,32,32,32,32,78,41,7,114,21,0,0,0, - 114,65,0,0,0,114,83,1,0,0,114,164,0,0,0,114, - 202,0,0,0,114,205,0,0,0,114,45,1,0,0,41,6, - 114,216,0,0,0,114,163,0,0,0,114,65,0,0,0,114, - 225,0,0,0,114,210,0,0,0,114,82,1,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,226,0, - 0,0,135,5,0,0,115,26,0,0,0,0,6,8,1,6, - 1,14,1,8,1,4,1,10,1,6,1,4,3,6,1,16, - 1,4,2,6,2,122,20,80,97,116,104,70,105,110,100,101, - 114,46,102,105,110,100,95,115,112,101,99,99,3,0,0,0, - 0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, - 67,0,0,0,115,30,0,0,0,124,0,160,0,124,1,124, - 2,161,2,125,3,124,3,100,1,117,0,114,24,100,1,83, - 0,124,3,106,1,83,0,41,2,122,170,102,105,110,100,32, - 116,104,101,32,109,111,100,117,108,101,32,111,110,32,115,121, - 115,46,112,97,116,104,32,111,114,32,39,112,97,116,104,39, - 32,98,97,115,101,100,32,111,110,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,115,32,97,110,100,10,32,32,32, - 32,32,32,32,32,115,121,115,46,112,97,116,104,95,105,109, - 112,111,114,116,101,114,95,99,97,99,104,101,46,10,10,32, - 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, - 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, - 32,32,32,32,32,78,114,227,0,0,0,114,228,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 229,0,0,0,159,5,0,0,115,8,0,0,0,0,8,12, - 1,8,1,4,1,122,22,80,97,116,104,70,105,110,100,101, - 114,46,102,105,110,100,95,109,111,100,117,108,101,99,1,0, - 0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0, - 0,0,79,0,0,0,115,28,0,0,0,100,1,100,2,108, - 0,109,1,125,3,1,0,124,3,106,2,124,1,105,0,124, - 2,164,1,142,1,83,0,41,3,97,32,1,0,0,10,32, - 32,32,32,32,32,32,32,70,105,110,100,32,100,105,115,116, - 114,105,98,117,116,105,111,110,115,46,10,10,32,32,32,32, - 32,32,32,32,82,101,116,117,114,110,32,97,110,32,105,116, - 101,114,97,98,108,101,32,111,102,32,97,108,108,32,68,105, - 115,116,114,105,98,117,116,105,111,110,32,105,110,115,116,97, - 110,99,101,115,32,99,97,112,97,98,108,101,32,111,102,10, - 32,32,32,32,32,32,32,32,108,111,97,100,105,110,103,32, - 116,104,101,32,109,101,116,97,100,97,116,97,32,102,111,114, - 32,112,97,99,107,97,103,101,115,32,109,97,116,99,104,105, - 110,103,32,96,96,99,111,110,116,101,120,116,46,110,97,109, - 101,96,96,10,32,32,32,32,32,32,32,32,40,111,114,32, - 97,108,108,32,110,97,109,101,115,32,105,102,32,96,96,78, - 111,110,101,96,96,32,105,110,100,105,99,97,116,101,100,41, - 32,97,108,111,110,103,32,116,104,101,32,112,97,116,104,115, - 32,105,110,32,116,104,101,32,108,105,115,116,10,32,32,32, - 32,32,32,32,32,111,102,32,100,105,114,101,99,116,111,114, - 105,101,115,32,96,96,99,111,110,116,101,120,116,46,112,97, - 116,104,96,96,46,10,32,32,32,32,32,32,32,32,114,0, - 0,0,0,41,1,218,18,77,101,116,97,100,97,116,97,80, - 97,116,104,70,105,110,100,101,114,41,3,90,18,105,109,112, - 111,114,116,108,105,98,46,109,101,116,97,100,97,116,97,114, - 84,1,0,0,218,18,102,105,110,100,95,100,105,115,116,114, - 105,98,117,116,105,111,110,115,41,4,114,216,0,0,0,114, - 143,0,0,0,114,144,0,0,0,114,84,1,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,85,1, - 0,0,172,5,0,0,115,4,0,0,0,0,10,12,1,122, - 29,80,97,116,104,70,105,110,100,101,114,46,102,105,110,100, - 95,100,105,115,116,114,105,98,117,116,105,111,110,115,41,1, - 78,41,2,78,78,41,1,78,41,13,114,149,0,0,0,114, - 148,0,0,0,114,150,0,0,0,114,151,0,0,0,114,230, - 0,0,0,114,71,1,0,0,114,77,1,0,0,114,79,1, - 0,0,114,80,1,0,0,114,83,1,0,0,114,226,0,0, - 0,114,229,0,0,0,114,85,1,0,0,114,10,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 70,1,0,0,36,5,0,0,115,34,0,0,0,8,2,4, - 2,2,1,10,12,2,1,10,12,2,1,10,21,2,1,10, - 14,2,1,12,31,2,1,12,23,2,1,12,12,2,1,114, - 70,1,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 99,104,101,99,3,0,0,0,0,0,0,0,0,0,0,0, + 7,0,0,0,4,0,0,0,67,0,0,0,115,138,0,0, + 0,116,0,124,2,100,1,131,2,114,27,116,1,160,2,124, + 2,161,1,155,0,100,2,157,2,125,3,116,3,160,4,124, + 3,116,5,161,2,1,0,124,2,160,6,124,1,161,1,92, + 2,125,4,125,5,110,21,116,1,160,2,124,2,161,1,155, + 0,100,3,157,2,125,3,116,3,160,4,124,3,116,5,161, + 2,1,0,124,2,160,7,124,1,161,1,125,4,103,0,125, + 5,124,4,100,0,117,1,114,58,116,1,160,8,124,1,124, + 4,161,2,83,0,116,1,160,9,124,1,100,0,161,2,125, + 6,124,5,124,6,95,10,124,6,83,0,41,4,78,114,161, + 0,0,0,122,53,46,102,105,110,100,95,115,112,101,99,40, + 41,32,110,111,116,32,102,111,117,110,100,59,32,102,97,108, + 108,105,110,103,32,98,97,99,107,32,116,111,32,102,105,110, + 100,95,108,111,97,100,101,114,40,41,122,53,46,102,105,110, + 100,95,115,112,101,99,40,41,32,110,111,116,32,102,111,117, + 110,100,59,32,102,97,108,108,105,110,103,32,98,97,99,107, + 32,116,111,32,102,105,110,100,95,109,111,100,117,108,101,40, + 41,41,11,114,153,0,0,0,114,159,0,0,0,90,12,95, + 111,98,106,101,99,116,95,110,97,109,101,114,99,0,0,0, + 114,100,0,0,0,114,162,0,0,0,114,161,0,0,0,114, + 229,0,0,0,114,224,0,0,0,114,207,0,0,0,114,202, + 0,0,0,41,7,114,221,0,0,0,114,163,0,0,0,114, + 84,1,0,0,114,166,0,0,0,114,164,0,0,0,114,165, + 0,0,0,114,210,0,0,0,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,218,16,95,108,101,103,97,99,121, + 95,103,101,116,95,115,112,101,99,98,5,0,0,115,26,0, + 0,0,10,4,16,1,12,2,16,1,16,2,12,2,10,1, + 4,1,8,1,12,1,12,1,6,1,4,1,122,27,80,97, + 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, + 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, + 0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,67, + 0,0,0,115,166,0,0,0,103,0,125,4,124,2,68,0, + 93,67,125,5,116,0,124,5,116,1,116,2,102,2,131,2, + 115,14,113,4,124,0,160,3,124,5,161,1,125,6,124,6, + 100,1,117,1,114,71,116,4,124,6,100,2,131,2,114,35, + 124,6,160,5,124,1,124,3,161,2,125,7,110,6,124,0, + 160,6,124,1,124,6,161,2,125,7,124,7,100,1,117,0, + 114,46,113,4,124,7,106,7,100,1,117,1,114,55,124,7, + 2,0,1,0,83,0,124,7,106,8,125,8,124,8,100,1, + 117,0,114,66,116,9,100,3,131,1,130,1,124,4,160,10, + 124,8,161,1,1,0,113,4,116,11,160,12,124,1,100,1, + 161,2,125,7,124,4,124,7,95,8,124,7,83,0,41,4, + 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, + 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, + 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, + 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, + 46,78,114,226,0,0,0,122,19,115,112,101,99,32,109,105, + 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,185, + 0,0,0,114,109,0,0,0,218,5,98,121,116,101,115,114, + 89,1,0,0,114,153,0,0,0,114,226,0,0,0,114,90, + 1,0,0,114,164,0,0,0,114,202,0,0,0,114,142,0, + 0,0,114,191,0,0,0,114,159,0,0,0,114,207,0,0, + 0,41,9,114,221,0,0,0,114,163,0,0,0,114,65,0, + 0,0,114,225,0,0,0,218,14,110,97,109,101,115,112,97, + 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,84, + 1,0,0,114,210,0,0,0,114,165,0,0,0,114,7,0, + 0,0,114,7,0,0,0,114,8,0,0,0,218,9,95,103, + 101,116,95,115,112,101,99,119,5,0,0,115,42,0,0,0, + 4,5,8,1,14,1,2,1,10,1,8,1,10,1,14,1, + 12,2,8,1,2,1,10,1,8,1,6,1,8,1,8,1, + 10,5,2,128,12,2,6,1,4,1,122,20,80,97,116,104, + 70,105,110,100,101,114,46,95,103,101,116,95,115,112,101,99, + 99,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0, + 0,5,0,0,0,67,0,0,0,115,94,0,0,0,124,2, + 100,1,117,0,114,7,116,0,106,1,125,2,124,0,160,2, + 124,1,124,2,124,3,161,3,125,4,124,4,100,1,117,0, + 114,20,100,1,83,0,124,4,106,3,100,1,117,0,114,45, + 124,4,106,4,125,5,124,5,114,43,100,1,124,4,95,5, + 116,6,124,1,124,5,124,0,106,2,131,3,124,4,95,4, + 124,4,83,0,100,1,83,0,124,4,83,0,41,2,122,141, + 84,114,121,32,116,111,32,102,105,110,100,32,97,32,115,112, + 101,99,32,102,111,114,32,39,102,117,108,108,110,97,109,101, + 39,32,111,110,32,115,121,115,46,112,97,116,104,32,111,114, + 32,39,112,97,116,104,39,46,10,10,32,32,32,32,32,32, + 32,32,84,104,101,32,115,101,97,114,99,104,32,105,115,32, + 98,97,115,101,100,32,111,110,32,115,121,115,46,112,97,116, + 104,95,104,111,111,107,115,32,97,110,100,32,115,121,115,46, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,46,10,32,32,32,32,32,32,32,32,78,41,7, + 114,15,0,0,0,114,65,0,0,0,114,93,1,0,0,114, + 164,0,0,0,114,202,0,0,0,114,205,0,0,0,114,47, + 1,0,0,41,6,114,221,0,0,0,114,163,0,0,0,114, + 65,0,0,0,114,225,0,0,0,114,210,0,0,0,114,92, + 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,226,0,0,0,151,5,0,0,115,26,0,0,0, + 8,6,6,1,14,1,8,1,4,1,10,1,6,1,4,1, + 6,3,16,1,4,1,4,2,4,2,122,20,80,97,116,104, + 70,105,110,100,101,114,46,102,105,110,100,95,115,112,101,99, + 99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,4,0,0,0,67,0,0,0,115,42,0,0,0,116,0, + 160,1,100,1,116,2,161,2,1,0,124,0,160,3,124,1, + 124,2,161,2,125,3,124,3,100,2,117,0,114,18,100,2, + 83,0,124,3,106,4,83,0,41,3,122,170,102,105,110,100, + 32,116,104,101,32,109,111,100,117,108,101,32,111,110,32,115, + 121,115,46,112,97,116,104,32,111,114,32,39,112,97,116,104, + 39,32,98,97,115,101,100,32,111,110,32,115,121,115,46,112, + 97,116,104,95,104,111,111,107,115,32,97,110,100,10,32,32, + 32,32,32,32,32,32,115,121,115,46,112,97,116,104,95,105, + 109,112,111,114,116,101,114,95,99,97,99,104,101,46,10,10, + 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, + 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, + 100,46,32,32,85,115,101,32,102,105,110,100,95,115,112,101, + 99,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, + 32,32,32,32,32,32,122,101,80,97,116,104,70,105,110,100, + 101,114,46,102,105,110,100,95,109,111,100,117,108,101,40,41, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,32,97, + 110,100,32,115,108,97,116,101,100,32,102,111,114,32,114,101, + 109,111,118,97,108,32,105,110,32,80,121,116,104,111,110,32, + 51,46,49,50,59,32,117,115,101,32,102,105,110,100,95,115, + 112,101,99,40,41,32,105,110,115,116,101,97,100,78,114,227, + 0,0,0,114,228,0,0,0,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,114,229,0,0,0,175,5,0,0, + 115,14,0,0,0,6,8,2,2,4,254,12,3,8,1,4, + 1,6,1,122,22,80,97,116,104,70,105,110,100,101,114,46, + 102,105,110,100,95,109,111,100,117,108,101,99,0,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,0, + 79,0,0,0,115,28,0,0,0,100,1,100,2,108,0,109, + 1,125,2,1,0,124,2,106,2,124,0,105,0,124,1,164, + 1,142,1,83,0,41,3,97,32,1,0,0,10,32,32,32, + 32,32,32,32,32,70,105,110,100,32,100,105,115,116,114,105, + 98,117,116,105,111,110,115,46,10,10,32,32,32,32,32,32, + 32,32,82,101,116,117,114,110,32,97,110,32,105,116,101,114, + 97,98,108,101,32,111,102,32,97,108,108,32,68,105,115,116, + 114,105,98,117,116,105,111,110,32,105,110,115,116,97,110,99, + 101,115,32,99,97,112,97,98,108,101,32,111,102,10,32,32, + 32,32,32,32,32,32,108,111,97,100,105,110,103,32,116,104, + 101,32,109,101,116,97,100,97,116,97,32,102,111,114,32,112, + 97,99,107,97,103,101,115,32,109,97,116,99,104,105,110,103, + 32,96,96,99,111,110,116,101,120,116,46,110,97,109,101,96, + 96,10,32,32,32,32,32,32,32,32,40,111,114,32,97,108, + 108,32,110,97,109,101,115,32,105,102,32,96,96,78,111,110, + 101,96,96,32,105,110,100,105,99,97,116,101,100,41,32,97, + 108,111,110,103,32,116,104,101,32,112,97,116,104,115,32,105, + 110,32,116,104,101,32,108,105,115,116,10,32,32,32,32,32, + 32,32,32,111,102,32,100,105,114,101,99,116,111,114,105,101, + 115,32,96,96,99,111,110,116,101,120,116,46,112,97,116,104, + 96,96,46,10,32,32,32,32,32,32,32,32,114,0,0,0, + 0,41,1,218,18,77,101,116,97,100,97,116,97,80,97,116, + 104,70,105,110,100,101,114,41,3,90,18,105,109,112,111,114, + 116,108,105,98,46,109,101,116,97,100,97,116,97,114,94,1, + 0,0,218,18,102,105,110,100,95,100,105,115,116,114,105,98, + 117,116,105,111,110,115,41,3,114,144,0,0,0,114,145,0, + 0,0,114,94,1,0,0,114,7,0,0,0,114,7,0,0, + 0,114,8,0,0,0,114,95,1,0,0,191,5,0,0,115, + 4,0,0,0,12,10,16,1,122,29,80,97,116,104,70,105, + 110,100,101,114,46,102,105,110,100,95,100,105,115,116,114,105, + 98,117,116,105,111,110,115,114,69,0,0,0,114,230,0,0, + 0,41,14,114,150,0,0,0,114,149,0,0,0,114,151,0, + 0,0,114,152,0,0,0,114,233,0,0,0,114,80,1,0, + 0,114,86,1,0,0,114,234,0,0,0,114,89,1,0,0, + 114,90,1,0,0,114,93,1,0,0,114,226,0,0,0,114, + 229,0,0,0,114,95,1,0,0,114,7,0,0,0,114,7, + 0,0,0,114,7,0,0,0,114,8,0,0,0,114,79,1, + 0,0,46,5,0,0,115,36,0,0,0,8,0,4,2,2, + 2,10,1,2,12,10,1,2,12,10,1,2,21,10,1,2, + 20,12,1,2,31,12,1,2,23,12,1,2,15,14,1,114, + 79,1,0,0,99,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,3,0,0,0,64,0,0,0,115,90,0, 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, 100,3,132,0,90,4,100,4,100,5,132,0,90,5,101,6, @@ -2388,11 +2393,11 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 104,97,115,32,98,101,101,110,32,109,111,100,105,102,105,101, 100,46,10,10,32,32,32,32,99,2,0,0,0,0,0,0, 0,0,0,0,0,5,0,0,0,6,0,0,0,7,0,0, - 0,115,112,0,0,0,103,0,125,3,124,2,68,0,93,32, + 0,115,112,0,0,0,103,0,125,3,124,2,68,0,93,16, 92,2,137,0,125,4,124,3,160,0,135,0,102,1,100,1, - 100,2,132,8,124,4,68,0,131,1,161,1,1,0,113,8, - 124,3,124,0,95,1,124,1,112,54,100,3,124,0,95,2, - 116,3,124,0,106,2,131,1,115,86,116,4,116,5,160,6, + 100,2,132,8,124,4,68,0,131,1,161,1,1,0,113,4, + 124,3,124,0,95,1,124,1,112,27,100,3,124,0,95,2, + 116,3,124,0,106,2,131,1,115,43,116,4,116,5,160,6, 161,0,124,0,106,2,131,2,124,0,95,2,100,4,124,0, 95,7,116,8,131,0,124,0,95,9,116,8,131,0,124,0, 95,10,100,5,83,0,41,6,122,154,73,110,105,116,105,97, @@ -2406,42 +2411,43 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 102,105,120,101,115,32,116,104,101,32,108,111,97,100,101,114, 10,32,32,32,32,32,32,32,32,114,101,99,111,103,110,105, 122,101,115,46,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,3,0,0,0,51,0,0,0,115,22,0, - 0,0,124,0,93,14,125,1,124,1,136,0,102,2,86,0, - 1,0,113,2,100,0,83,0,114,69,0,0,0,114,10,0, - 0,0,114,40,1,0,0,169,1,114,164,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,12,0,0,0,201,5,0, - 0,114,13,0,0,0,122,38,70,105,108,101,70,105,110,100, - 101,114,46,95,95,105,110,105,116,95,95,46,60,108,111,99, - 97,108,115,62,46,60,103,101,110,101,120,112,114,62,114,96, - 0,0,0,114,129,0,0,0,78,41,11,114,191,0,0,0, - 218,8,95,108,111,97,100,101,114,115,114,65,0,0,0,114, - 85,0,0,0,114,67,0,0,0,114,24,0,0,0,114,81, - 0,0,0,218,11,95,112,97,116,104,95,109,116,105,109,101, - 218,3,115,101,116,218,11,95,112,97,116,104,95,99,97,99, - 104,101,218,19,95,114,101,108,97,120,101,100,95,112,97,116, - 104,95,99,97,99,104,101,41,5,114,142,0,0,0,114,65, - 0,0,0,218,14,108,111,97,100,101,114,95,100,101,116,97, - 105,108,115,90,7,108,111,97,100,101,114,115,114,212,0,0, - 0,114,10,0,0,0,114,87,1,0,0,114,11,0,0,0, - 114,232,0,0,0,195,5,0,0,115,20,0,0,0,0,4, - 4,1,12,1,26,1,6,2,10,1,10,1,18,1,6,1, - 8,1,122,19,70,105,108,101,70,105,110,100,101,114,46,95, - 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0, - 115,10,0,0,0,100,1,124,0,95,0,100,2,83,0,41, - 3,122,31,73,110,118,97,108,105,100,97,116,101,32,116,104, - 101,32,100,105,114,101,99,116,111,114,121,32,109,116,105,109, - 101,46,114,129,0,0,0,78,41,1,114,89,1,0,0,114, - 13,1,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,71,1,0,0,211,5,0,0,115,2,0,0, - 0,0,2,122,28,70,105,108,101,70,105,110,100,101,114,46, - 105,110,118,97,108,105,100,97,116,101,95,99,97,99,104,101, - 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,3,0,0,0,67,0,0,0,115,42,0,0,0,124, - 0,160,0,124,1,161,1,125,2,124,2,100,1,117,0,114, - 26,100,1,103,0,102,2,83,0,124,2,106,1,124,2,106, - 2,112,38,103,0,102,2,83,0,41,2,122,197,84,114,121, + 0,2,0,0,0,3,0,0,0,51,0,0,0,115,24,0, + 0,0,129,0,124,0,93,7,125,1,124,1,136,0,102,2, + 86,0,1,0,113,2,100,0,83,0,114,69,0,0,0,114, + 7,0,0,0,114,43,1,0,0,169,1,114,164,0,0,0, + 114,7,0,0,0,114,8,0,0,0,114,9,0,0,0,220, + 5,0,0,115,4,0,0,0,2,128,22,0,122,38,70,105, + 108,101,70,105,110,100,101,114,46,95,95,105,110,105,116,95, + 95,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, + 120,112,114,62,114,97,0,0,0,114,130,0,0,0,78,41, + 11,114,191,0,0,0,218,8,95,108,111,97,100,101,114,115, + 114,65,0,0,0,114,86,0,0,0,114,67,0,0,0,114, + 18,0,0,0,114,82,0,0,0,218,11,95,112,97,116,104, + 95,109,116,105,109,101,218,3,115,101,116,218,11,95,112,97, + 116,104,95,99,97,99,104,101,218,19,95,114,101,108,97,120, + 101,100,95,112,97,116,104,95,99,97,99,104,101,41,5,114, + 143,0,0,0,114,65,0,0,0,218,14,108,111,97,100,101, + 114,95,100,101,116,97,105,108,115,90,7,108,111,97,100,101, + 114,115,114,212,0,0,0,114,7,0,0,0,114,97,1,0, + 0,114,8,0,0,0,114,236,0,0,0,214,5,0,0,115, + 20,0,0,0,4,4,12,1,26,1,6,1,10,2,10,1, + 18,1,6,1,8,1,12,1,122,19,70,105,108,101,70,105, + 110,100,101,114,46,95,95,105,110,105,116,95,95,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0, + 0,0,67,0,0,0,115,10,0,0,0,100,1,124,0,95, + 0,100,2,83,0,41,3,122,31,73,110,118,97,108,105,100, + 97,116,101,32,116,104,101,32,100,105,114,101,99,116,111,114, + 121,32,109,116,105,109,101,46,114,130,0,0,0,78,41,1, + 114,99,1,0,0,114,21,1,0,0,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,114,80,1,0,0,230,5, + 0,0,114,81,0,0,0,122,28,70,105,108,101,70,105,110, + 100,101,114,46,105,110,118,97,108,105,100,97,116,101,95,99, + 97,99,104,101,115,99,2,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,54, + 0,0,0,116,0,160,1,100,1,116,2,161,2,1,0,124, + 0,160,3,124,1,161,1,125,2,124,2,100,2,117,0,114, + 19,100,2,103,0,102,2,83,0,124,2,106,4,124,2,106, + 5,112,25,103,0,102,2,83,0,41,3,122,197,84,114,121, 32,116,111,32,102,105,110,100,32,97,32,108,111,97,100,101, 114,32,102,111,114,32,116,104,101,32,115,112,101,99,105,102, 105,101,100,32,109,111,100,117,108,101,44,32,111,114,32,116, @@ -2454,379 +2460,312 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, 85,115,101,32,102,105,110,100,95,115,112,101,99,40,41,32, 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, - 32,32,78,41,3,114,226,0,0,0,114,164,0,0,0,114, - 202,0,0,0,41,3,114,142,0,0,0,114,163,0,0,0, - 114,210,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,161,0,0,0,217,5,0,0,115,8,0, - 0,0,0,7,10,1,8,1,8,1,122,22,70,105,108,101, - 70,105,110,100,101,114,46,102,105,110,100,95,108,111,97,100, - 101,114,99,6,0,0,0,0,0,0,0,0,0,0,0,7, - 0,0,0,6,0,0,0,67,0,0,0,115,26,0,0,0, - 124,1,124,2,124,3,131,2,125,6,116,0,124,2,124,3, - 124,6,124,4,100,1,141,4,83,0,41,2,78,114,201,0, - 0,0,41,1,114,213,0,0,0,41,7,114,142,0,0,0, - 114,211,0,0,0,114,163,0,0,0,114,65,0,0,0,90, - 4,115,109,115,108,114,225,0,0,0,114,164,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,83, - 1,0,0,229,5,0,0,115,8,0,0,0,0,1,10,1, - 8,1,2,255,122,20,70,105,108,101,70,105,110,100,101,114, - 46,95,103,101,116,95,115,112,101,99,78,99,3,0,0,0, - 0,0,0,0,0,0,0,0,14,0,0,0,9,0,0,0, - 67,0,0,0,115,126,1,0,0,100,1,125,3,124,1,160, - 0,100,2,161,1,100,3,25,0,125,4,122,24,116,1,124, - 0,106,2,112,34,116,3,160,4,161,0,131,1,106,5,125, - 5,87,0,110,22,4,0,116,6,121,64,1,0,1,0,1, - 0,100,4,125,5,89,0,110,2,48,0,124,5,124,0,106, - 7,107,3,114,90,124,0,160,8,161,0,1,0,124,5,124, - 0,95,7,116,9,131,0,114,112,124,0,106,10,125,6,124, - 4,160,11,161,0,125,7,110,10,124,0,106,12,125,6,124, - 4,125,7,124,7,124,6,118,0,114,216,116,13,124,0,106, - 2,124,4,131,2,125,8,124,0,106,14,68,0,93,58,92, - 2,125,9,125,10,100,5,124,9,23,0,125,11,116,13,124, - 8,124,11,131,2,125,12,116,15,124,12,131,1,114,148,124, - 0,160,16,124,10,124,1,124,12,124,8,103,1,124,2,161, - 5,2,0,1,0,83,0,113,148,116,17,124,8,131,1,125, - 3,124,0,106,14,68,0,93,112,92,2,125,9,125,10,122, - 20,116,13,124,0,106,2,124,4,124,9,23,0,131,2,125, - 12,87,0,110,24,4,0,116,18,144,1,121,18,1,0,1, - 0,1,0,89,0,1,0,100,6,83,0,48,0,116,19,106, - 20,100,7,124,12,100,3,100,8,141,3,1,0,124,7,124, - 9,23,0,124,6,118,0,114,222,116,15,124,12,131,1,114, - 222,124,0,160,16,124,10,124,1,124,12,100,6,124,2,161, - 5,2,0,1,0,83,0,113,222,124,3,144,1,114,122,116, - 19,160,20,100,9,124,8,161,2,1,0,116,19,160,21,124, - 1,100,6,161,2,125,13,124,8,103,1,124,13,95,22,124, - 13,83,0,100,6,83,0,41,10,122,111,84,114,121,32,116, - 111,32,102,105,110,100,32,97,32,115,112,101,99,32,102,111, - 114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, - 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, - 32,82,101,116,117,114,110,115,32,116,104,101,32,109,97,116, - 99,104,105,110,103,32,115,112,101,99,44,32,111,114,32,78, - 111,110,101,32,105,102,32,110,111,116,32,102,111,117,110,100, - 46,10,32,32,32,32,32,32,32,32,70,114,96,0,0,0, - 114,45,0,0,0,114,129,0,0,0,114,232,0,0,0,78, - 122,9,116,114,121,105,110,103,32,123,125,41,1,90,9,118, - 101,114,98,111,115,105,116,121,122,25,112,111,115,115,105,98, - 108,101,32,110,97,109,101,115,112,97,99,101,32,102,111,114, - 32,123,125,41,23,114,103,0,0,0,114,75,0,0,0,114, - 65,0,0,0,114,24,0,0,0,114,81,0,0,0,114,33, - 1,0,0,114,76,0,0,0,114,89,1,0,0,218,11,95, - 102,105,108,108,95,99,97,99,104,101,114,27,0,0,0,114, - 92,1,0,0,114,130,0,0,0,114,91,1,0,0,114,67, - 0,0,0,114,88,1,0,0,114,80,0,0,0,114,83,1, - 0,0,114,82,0,0,0,114,110,0,0,0,114,158,0,0, - 0,114,173,0,0,0,114,207,0,0,0,114,202,0,0,0, - 41,14,114,142,0,0,0,114,163,0,0,0,114,225,0,0, - 0,90,12,105,115,95,110,97,109,101,115,112,97,99,101,90, - 11,116,97,105,108,95,109,111,100,117,108,101,114,193,0,0, - 0,90,5,99,97,99,104,101,90,12,99,97,99,104,101,95, - 109,111,100,117,108,101,90,9,98,97,115,101,95,112,97,116, - 104,114,41,1,0,0,114,211,0,0,0,90,13,105,110,105, - 116,95,102,105,108,101,110,97,109,101,90,9,102,117,108,108, - 95,112,97,116,104,114,210,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,226,0,0,0,234,5, - 0,0,115,78,0,0,0,0,5,4,1,14,1,2,1,24, - 1,12,1,10,1,10,1,8,1,6,2,6,1,6,1,10, - 2,6,1,4,2,8,1,12,1,14,1,8,1,10,1,8, - 1,26,4,8,2,14,1,2,1,20,1,14,1,10,1,16, - 1,12,1,8,1,10,1,4,255,10,2,6,1,12,1,12, - 1,8,1,4,1,122,20,70,105,108,101,70,105,110,100,101, + 32,32,122,101,70,105,108,101,70,105,110,100,101,114,46,102, + 105,110,100,95,108,111,97,100,101,114,40,41,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,32,97,110,100,32,115, + 108,97,116,101,100,32,102,111,114,32,114,101,109,111,118,97, + 108,32,105,110,32,80,121,116,104,111,110,32,51,46,49,50, + 59,32,117,115,101,32,102,105,110,100,95,115,112,101,99,40, + 41,32,105,110,115,116,101,97,100,78,41,6,114,99,0,0, + 0,114,100,0,0,0,114,101,0,0,0,114,226,0,0,0, + 114,164,0,0,0,114,202,0,0,0,41,3,114,143,0,0, + 0,114,163,0,0,0,114,210,0,0,0,114,7,0,0,0, + 114,7,0,0,0,114,8,0,0,0,114,161,0,0,0,236, + 5,0,0,115,14,0,0,0,6,7,2,2,4,254,10,3, + 8,1,8,1,16,1,122,22,70,105,108,101,70,105,110,100, + 101,114,46,102,105,110,100,95,108,111,97,100,101,114,99,6, + 0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,6, + 0,0,0,67,0,0,0,115,26,0,0,0,124,1,124,2, + 124,3,131,2,125,6,116,0,124,2,124,3,124,6,124,4, + 100,1,141,4,83,0,41,2,78,114,201,0,0,0,41,1, + 114,213,0,0,0,41,7,114,143,0,0,0,114,211,0,0, + 0,114,163,0,0,0,114,65,0,0,0,90,4,115,109,115, + 108,114,225,0,0,0,114,164,0,0,0,114,7,0,0,0, + 114,7,0,0,0,114,8,0,0,0,114,93,1,0,0,251, + 5,0,0,115,8,0,0,0,10,1,8,1,2,1,6,255, + 122,20,70,105,108,101,70,105,110,100,101,114,46,95,103,101, + 116,95,115,112,101,99,78,99,3,0,0,0,0,0,0,0, + 0,0,0,0,14,0,0,0,9,0,0,0,67,0,0,0, + 115,122,1,0,0,100,1,125,3,124,1,160,0,100,2,161, + 1,100,3,25,0,125,4,122,12,116,1,124,0,106,2,112, + 17,116,3,160,4,161,0,131,1,106,5,125,5,87,0,110, + 11,4,0,116,6,121,32,1,0,1,0,1,0,100,4,125, + 5,89,0,110,1,119,0,124,5,124,0,106,7,107,3,114, + 45,124,0,160,8,161,0,1,0,124,5,124,0,95,7,116, + 9,131,0,114,56,124,0,106,10,125,6,124,4,160,11,161, + 0,125,7,110,5,124,0,106,12,125,6,124,4,125,7,124, + 7,124,6,118,0,114,108,116,13,124,0,106,2,124,4,131, + 2,125,8,124,0,106,14,68,0,93,29,92,2,125,9,125, + 10,100,5,124,9,23,0,125,11,116,13,124,8,124,11,131, + 2,125,12,116,15,124,12,131,1,114,103,124,0,160,16,124, + 10,124,1,124,12,124,8,103,1,124,2,161,5,2,0,1, + 0,83,0,113,74,116,17,124,8,131,1,125,3,124,0,106, + 14,68,0,93,55,92,2,125,9,125,10,122,10,116,13,124, + 0,106,2,124,4,124,9,23,0,131,2,125,12,87,0,110, + 11,4,0,116,18,121,136,1,0,1,0,1,0,89,0,1, + 0,100,6,83,0,119,0,116,19,106,20,100,7,124,12,100, + 3,100,8,141,3,1,0,124,7,124,9,23,0,124,6,118, + 0,114,166,116,15,124,12,131,1,114,166,124,0,160,16,124, + 10,124,1,124,12,100,6,124,2,161,5,2,0,1,0,83, + 0,113,111,124,3,114,187,116,19,160,20,100,9,124,8,161, + 2,1,0,116,19,160,21,124,1,100,6,161,2,125,13,124, + 8,103,1,124,13,95,22,124,13,83,0,100,6,83,0,41, + 10,122,111,84,114,121,32,116,111,32,102,105,110,100,32,97, + 32,115,112,101,99,32,102,111,114,32,116,104,101,32,115,112, + 101,99,105,102,105,101,100,32,109,111,100,117,108,101,46,10, + 10,32,32,32,32,32,32,32,32,82,101,116,117,114,110,115, + 32,116,104,101,32,109,97,116,99,104,105,110,103,32,115,112, + 101,99,44,32,111,114,32,78,111,110,101,32,105,102,32,110, + 111,116,32,102,111,117,110,100,46,10,32,32,32,32,32,32, + 32,32,70,114,97,0,0,0,114,44,0,0,0,114,130,0, + 0,0,114,236,0,0,0,78,122,9,116,114,121,105,110,103, + 32,123,125,41,1,90,9,118,101,114,98,111,115,105,116,121, + 122,25,112,111,115,115,105,98,108,101,32,110,97,109,101,115, + 112,97,99,101,32,102,111,114,32,123,125,41,23,114,104,0, + 0,0,114,75,0,0,0,114,65,0,0,0,114,18,0,0, + 0,114,82,0,0,0,114,35,1,0,0,114,76,0,0,0, + 114,99,1,0,0,218,11,95,102,105,108,108,95,99,97,99, + 104,101,114,21,0,0,0,114,102,1,0,0,114,131,0,0, + 0,114,101,1,0,0,114,67,0,0,0,114,98,1,0,0, + 114,80,0,0,0,114,93,1,0,0,114,83,0,0,0,114, + 111,0,0,0,114,159,0,0,0,114,173,0,0,0,114,207, + 0,0,0,114,202,0,0,0,41,14,114,143,0,0,0,114, + 163,0,0,0,114,225,0,0,0,90,12,105,115,95,110,97, + 109,101,115,112,97,99,101,90,11,116,97,105,108,95,109,111, + 100,117,108,101,114,193,0,0,0,90,5,99,97,99,104,101, + 90,12,99,97,99,104,101,95,109,111,100,117,108,101,90,9, + 98,97,115,101,95,112,97,116,104,114,44,1,0,0,114,211, + 0,0,0,90,13,105,110,105,116,95,102,105,108,101,110,97, + 109,101,90,9,102,117,108,108,95,112,97,116,104,114,210,0, + 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, + 0,114,226,0,0,0,0,6,0,0,115,86,0,0,0,4, + 5,14,1,2,1,24,1,12,1,8,1,2,255,10,2,8, + 1,6,1,6,2,6,1,10,1,6,2,4,1,8,2,12, + 1,14,1,8,1,10,1,8,1,24,1,2,255,8,5,14, + 2,2,1,20,1,12,1,8,1,2,255,16,2,12,1,8, + 1,10,1,4,1,8,255,2,128,4,2,12,1,12,1,8, + 1,4,1,4,1,122,20,70,105,108,101,70,105,110,100,101, 114,46,102,105,110,100,95,115,112,101,99,99,1,0,0,0, 0,0,0,0,0,0,0,0,9,0,0,0,10,0,0,0, - 67,0,0,0,115,188,0,0,0,124,0,106,0,125,1,122, - 22,116,1,160,2,124,1,112,22,116,1,160,3,161,0,161, - 1,125,2,87,0,110,28,4,0,116,4,116,5,116,6,102, - 3,121,56,1,0,1,0,1,0,103,0,125,2,89,0,110, - 2,48,0,116,7,106,8,160,9,100,1,161,1,115,82,116, - 10,124,2,131,1,124,0,95,11,110,74,116,10,131,0,125, - 3,124,2,68,0,93,56,125,4,124,4,160,12,100,2,161, - 1,92,3,125,5,125,6,125,7,124,6,114,134,100,3,160, - 13,124,5,124,7,160,14,161,0,161,2,125,8,110,4,124, - 5,125,8,124,3,160,15,124,8,161,1,1,0,113,92,124, + 67,0,0,0,115,192,0,0,0,124,0,106,0,125,1,122, + 11,116,1,160,2,124,1,112,11,116,1,160,3,161,0,161, + 1,125,2,87,0,110,14,4,0,116,4,116,5,116,6,102, + 3,121,28,1,0,1,0,1,0,103,0,125,2,89,0,110, + 1,119,0,116,7,106,8,160,9,100,1,161,1,115,41,116, + 10,124,2,131,1,124,0,95,11,110,37,116,10,131,0,125, + 3,124,2,68,0,93,28,125,4,124,4,160,12,100,2,161, + 1,92,3,125,5,125,6,125,7,124,6,114,67,100,3,160, + 13,124,5,124,7,160,14,161,0,161,2,125,8,110,2,124, + 5,125,8,124,3,160,15,124,8,161,1,1,0,113,46,124, 3,124,0,95,11,116,7,106,8,160,9,116,16,161,1,114, - 184,100,4,100,5,132,0,124,2,68,0,131,1,124,0,95, - 17,100,6,83,0,41,7,122,68,70,105,108,108,32,116,104, - 101,32,99,97,99,104,101,32,111,102,32,112,111,116,101,110, - 116,105,97,108,32,109,111,100,117,108,101,115,32,97,110,100, - 32,112,97,99,107,97,103,101,115,32,102,111,114,32,116,104, - 105,115,32,100,105,114,101,99,116,111,114,121,46,114,20,0, - 0,0,114,96,0,0,0,114,87,0,0,0,99,1,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,83,0,0,0,115,20,0,0,0,104,0,124,0,93,12, - 125,1,124,1,160,0,161,0,146,2,113,4,83,0,114,10, - 0,0,0,41,1,114,130,0,0,0,41,2,114,8,0,0, - 0,90,2,102,110,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,19,0,0,0,58,6,0,0,114,13,0, - 0,0,122,41,70,105,108,101,70,105,110,100,101,114,46,95, - 102,105,108,108,95,99,97,99,104,101,46,60,108,111,99,97, - 108,115,62,46,60,115,101,116,99,111,109,112,62,78,41,18, - 114,65,0,0,0,114,24,0,0,0,114,30,1,0,0,114, - 81,0,0,0,114,26,1,0,0,218,15,80,101,114,109,105, - 115,115,105,111,110,69,114,114,111,114,218,18,78,111,116,65, - 68,105,114,101,99,116,111,114,121,69,114,114,111,114,114,21, - 0,0,0,114,28,0,0,0,114,29,0,0,0,114,90,1, - 0,0,114,91,1,0,0,114,125,0,0,0,114,88,0,0, - 0,114,130,0,0,0,218,3,97,100,100,114,30,0,0,0, - 114,92,1,0,0,41,9,114,142,0,0,0,114,65,0,0, - 0,114,31,1,0,0,90,21,108,111,119,101,114,95,115,117, - 102,102,105,120,95,99,111,110,116,101,110,116,115,114,66,1, - 0,0,114,140,0,0,0,114,54,1,0,0,114,41,1,0, - 0,90,8,110,101,119,95,110,97,109,101,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,94,1,0,0,29, - 6,0,0,115,34,0,0,0,0,2,6,1,2,1,22,1, - 18,3,10,3,12,1,12,7,6,1,8,1,16,1,4,1, - 18,2,4,1,12,1,6,1,12,1,122,22,70,105,108,101, - 70,105,110,100,101,114,46,95,102,105,108,108,95,99,97,99, - 104,101,99,1,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,7,0,0,0,115,18,0,0,0, - 135,0,135,1,102,2,100,1,100,2,132,8,125,2,124,2, - 83,0,41,3,97,20,1,0,0,65,32,99,108,97,115,115, - 32,109,101,116,104,111,100,32,119,104,105,99,104,32,114,101, - 116,117,114,110,115,32,97,32,99,108,111,115,117,114,101,32, - 116,111,32,117,115,101,32,111,110,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,10,32,32,32,32,32,32,32,32, - 119,104,105,99,104,32,119,105,108,108,32,114,101,116,117,114, - 110,32,97,110,32,105,110,115,116,97,110,99,101,32,117,115, - 105,110,103,32,116,104,101,32,115,112,101,99,105,102,105,101, - 100,32,108,111,97,100,101,114,115,32,97,110,100,32,116,104, - 101,32,112,97,116,104,10,32,32,32,32,32,32,32,32,99, - 97,108,108,101,100,32,111,110,32,116,104,101,32,99,108,111, - 115,117,114,101,46,10,10,32,32,32,32,32,32,32,32,73, - 102,32,116,104,101,32,112,97,116,104,32,99,97,108,108,101, - 100,32,111,110,32,116,104,101,32,99,108,111,115,117,114,101, - 32,105,115,32,110,111,116,32,97,32,100,105,114,101,99,116, - 111,114,121,44,32,73,109,112,111,114,116,69,114,114,111,114, - 32,105,115,10,32,32,32,32,32,32,32,32,114,97,105,115, - 101,100,46,10,10,32,32,32,32,32,32,32,32,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,19,0,0,0,115,36,0,0,0,116,0,124,0,131, - 1,115,20,116,1,100,1,124,0,100,2,141,2,130,1,136, - 0,124,0,103,1,136,1,162,1,82,0,142,0,83,0,41, - 3,122,45,80,97,116,104,32,104,111,111,107,32,102,111,114, - 32,105,109,112,111,114,116,108,105,98,46,109,97,99,104,105, - 110,101,114,121,46,70,105,108,101,70,105,110,100,101,114,46, - 122,30,111,110,108,121,32,100,105,114,101,99,116,111,114,105, - 101,115,32,97,114,101,32,115,117,112,112,111,114,116,101,100, - 114,71,0,0,0,41,2,114,82,0,0,0,114,141,0,0, - 0,114,71,0,0,0,169,2,114,216,0,0,0,114,93,1, - 0,0,114,10,0,0,0,114,11,0,0,0,218,24,112,97, - 116,104,95,104,111,111,107,95,102,111,114,95,70,105,108,101, - 70,105,110,100,101,114,70,6,0,0,115,6,0,0,0,0, - 2,8,1,12,1,122,54,70,105,108,101,70,105,110,100,101, - 114,46,112,97,116,104,95,104,111,111,107,46,60,108,111,99, - 97,108,115,62,46,112,97,116,104,95,104,111,111,107,95,102, - 111,114,95,70,105,108,101,70,105,110,100,101,114,114,10,0, - 0,0,41,3,114,216,0,0,0,114,93,1,0,0,114,99, - 1,0,0,114,10,0,0,0,114,98,1,0,0,114,11,0, - 0,0,218,9,112,97,116,104,95,104,111,111,107,60,6,0, - 0,115,4,0,0,0,0,10,14,6,122,20,70,105,108,101, - 70,105,110,100,101,114,46,112,97,116,104,95,104,111,111,107, + 94,100,4,100,5,132,0,124,2,68,0,131,1,124,0,95, + 17,100,6,83,0,100,6,83,0,41,7,122,68,70,105,108, + 108,32,116,104,101,32,99,97,99,104,101,32,111,102,32,112, + 111,116,101,110,116,105,97,108,32,109,111,100,117,108,101,115, + 32,97,110,100,32,112,97,99,107,97,103,101,115,32,102,111, + 114,32,116,104,105,115,32,100,105,114,101,99,116,111,114,121, + 46,114,14,0,0,0,114,97,0,0,0,114,88,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,4,0,0,0,83,0,0,0,115,20,0,0,0,104,0, + 124,0,93,6,125,1,124,1,160,0,161,0,146,2,113,2, + 83,0,114,7,0,0,0,41,1,114,131,0,0,0,41,2, + 114,5,0,0,0,90,2,102,110,114,7,0,0,0,114,7, + 0,0,0,114,8,0,0,0,114,13,0,0,0,80,6,0, + 0,115,2,0,0,0,20,0,122,41,70,105,108,101,70,105, + 110,100,101,114,46,95,102,105,108,108,95,99,97,99,104,101, + 46,60,108,111,99,97,108,115,62,46,60,115,101,116,99,111, + 109,112,62,78,41,18,114,65,0,0,0,114,18,0,0,0, + 90,7,108,105,115,116,100,105,114,114,82,0,0,0,114,87, + 1,0,0,218,15,80,101,114,109,105,115,115,105,111,110,69, + 114,114,111,114,218,18,78,111,116,65,68,105,114,101,99,116, + 111,114,121,69,114,114,111,114,114,15,0,0,0,114,25,0, + 0,0,114,26,0,0,0,114,100,1,0,0,114,101,1,0, + 0,114,126,0,0,0,114,89,0,0,0,114,131,0,0,0, + 218,3,97,100,100,114,27,0,0,0,114,102,1,0,0,41, + 9,114,143,0,0,0,114,65,0,0,0,90,8,99,111,110, + 116,101,110,116,115,90,21,108,111,119,101,114,95,115,117,102, + 102,105,120,95,99,111,110,116,101,110,116,115,114,72,1,0, + 0,114,141,0,0,0,114,56,1,0,0,114,44,1,0,0, + 90,8,110,101,119,95,110,97,109,101,114,7,0,0,0,114, + 7,0,0,0,114,8,0,0,0,114,104,1,0,0,51,6, + 0,0,115,38,0,0,0,6,2,2,1,22,1,18,1,8, + 3,2,253,12,6,12,1,6,7,8,1,16,1,4,1,18, + 1,4,2,12,1,6,1,12,1,20,1,4,255,122,22,70, + 105,108,101,70,105,110,100,101,114,46,95,102,105,108,108,95, + 99,97,99,104,101,99,1,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,3,0,0,0,7,0,0,0,115,18, + 0,0,0,135,0,135,1,102,2,100,1,100,2,132,8,125, + 2,124,2,83,0,41,3,97,20,1,0,0,65,32,99,108, + 97,115,115,32,109,101,116,104,111,100,32,119,104,105,99,104, + 32,114,101,116,117,114,110,115,32,97,32,99,108,111,115,117, + 114,101,32,116,111,32,117,115,101,32,111,110,32,115,121,115, + 46,112,97,116,104,95,104,111,111,107,10,32,32,32,32,32, + 32,32,32,119,104,105,99,104,32,119,105,108,108,32,114,101, + 116,117,114,110,32,97,110,32,105,110,115,116,97,110,99,101, + 32,117,115,105,110,103,32,116,104,101,32,115,112,101,99,105, + 102,105,101,100,32,108,111,97,100,101,114,115,32,97,110,100, + 32,116,104,101,32,112,97,116,104,10,32,32,32,32,32,32, + 32,32,99,97,108,108,101,100,32,111,110,32,116,104,101,32, + 99,108,111,115,117,114,101,46,10,10,32,32,32,32,32,32, + 32,32,73,102,32,116,104,101,32,112,97,116,104,32,99,97, + 108,108,101,100,32,111,110,32,116,104,101,32,99,108,111,115, + 117,114,101,32,105,115,32,110,111,116,32,97,32,100,105,114, + 101,99,116,111,114,121,44,32,73,109,112,111,114,116,69,114, + 114,111,114,32,105,115,10,32,32,32,32,32,32,32,32,114, + 97,105,115,101,100,46,10,10,32,32,32,32,32,32,32,32, 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, - 160,0,124,0,106,1,161,1,83,0,41,2,78,122,16,70, - 105,108,101,70,105,110,100,101,114,40,123,33,114,125,41,41, - 2,114,88,0,0,0,114,65,0,0,0,114,13,1,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 64,1,0,0,78,6,0,0,115,2,0,0,0,0,1,122, - 19,70,105,108,101,70,105,110,100,101,114,46,95,95,114,101, - 112,114,95,95,41,1,78,41,15,114,149,0,0,0,114,148, - 0,0,0,114,150,0,0,0,114,151,0,0,0,114,232,0, - 0,0,114,71,1,0,0,114,167,0,0,0,114,229,0,0, - 0,114,161,0,0,0,114,83,1,0,0,114,226,0,0,0, - 114,94,1,0,0,114,230,0,0,0,114,100,1,0,0,114, - 64,1,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,86,1,0,0,186,5,0, - 0,115,22,0,0,0,8,2,4,7,8,16,8,4,4,2, - 8,12,8,5,10,51,8,31,2,1,10,17,114,86,1,0, - 0,99,4,0,0,0,0,0,0,0,0,0,0,0,6,0, - 0,0,8,0,0,0,67,0,0,0,115,144,0,0,0,124, - 0,160,0,100,1,161,1,125,4,124,0,160,0,100,2,161, - 1,125,5,124,4,115,66,124,5,114,36,124,5,106,1,125, - 4,110,30,124,2,124,3,107,2,114,56,116,2,124,1,124, - 2,131,2,125,4,110,10,116,3,124,1,124,2,131,2,125, - 4,124,5,115,84,116,4,124,1,124,2,124,4,100,3,141, - 3,125,5,122,36,124,5,124,0,100,2,60,0,124,4,124, - 0,100,1,60,0,124,2,124,0,100,4,60,0,124,3,124, - 0,100,5,60,0,87,0,110,18,4,0,116,5,121,138,1, - 0,1,0,1,0,89,0,110,2,48,0,100,0,83,0,41, - 6,78,218,10,95,95,108,111,97,100,101,114,95,95,218,8, - 95,95,115,112,101,99,95,95,114,87,1,0,0,90,8,95, - 95,102,105,108,101,95,95,90,10,95,95,99,97,99,104,101, - 100,95,95,41,6,218,3,103,101,116,114,164,0,0,0,114, - 39,1,0,0,114,32,1,0,0,114,213,0,0,0,218,9, - 69,120,99,101,112,116,105,111,110,41,6,90,2,110,115,114, - 140,0,0,0,90,8,112,97,116,104,110,97,109,101,90,9, - 99,112,97,116,104,110,97,109,101,114,164,0,0,0,114,210, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,14,95,102,105,120,95,117,112,95,109,111,100,117, - 108,101,84,6,0,0,115,34,0,0,0,0,2,10,1,10, - 1,4,1,4,1,8,1,8,1,12,2,10,1,4,1,14, - 1,2,1,8,1,8,1,8,1,12,1,12,2,114,105,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, - 116,0,116,1,160,2,161,0,102,2,125,0,116,3,116,4, - 102,2,125,1,116,5,116,6,102,2,125,2,124,0,124,1, - 124,2,103,3,83,0,41,1,122,95,82,101,116,117,114,110, - 115,32,97,32,108,105,115,116,32,111,102,32,102,105,108,101, - 45,98,97,115,101,100,32,109,111,100,117,108,101,32,108,111, - 97,100,101,114,115,46,10,10,32,32,32,32,69,97,99,104, - 32,105,116,101,109,32,105,115,32,97,32,116,117,112,108,101, - 32,40,108,111,97,100,101,114,44,32,115,117,102,102,105,120, - 101,115,41,46,10,32,32,32,32,41,7,114,19,1,0,0, - 114,187,0,0,0,218,18,101,120,116,101,110,115,105,111,110, - 95,115,117,102,102,105,120,101,115,114,32,1,0,0,114,126, - 0,0,0,114,39,1,0,0,114,112,0,0,0,41,3,90, - 10,101,120,116,101,110,115,105,111,110,115,90,6,115,111,117, - 114,99,101,90,8,98,121,116,101,99,111,100,101,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,208,0,0, - 0,107,6,0,0,115,8,0,0,0,0,5,12,1,8,1, - 8,1,114,208,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,10,0,0,0,9,0,0,0,67,0,0,0, - 115,132,1,0,0,124,0,97,0,116,0,106,1,97,1,116, - 0,106,2,97,2,116,1,106,3,116,4,25,0,125,1,100, - 1,100,2,103,1,102,2,100,3,100,4,100,2,103,2,102, - 2,102,2,125,2,124,2,68,0,93,108,92,2,125,3,125, - 4,116,5,100,5,100,6,132,0,124,4,68,0,131,1,131, - 1,115,82,74,0,130,1,124,4,100,7,25,0,125,5,124, - 3,116,1,106,3,118,0,114,116,116,1,106,3,124,3,25, - 0,125,6,1,0,113,170,113,52,122,20,116,0,160,6,124, - 3,161,1,125,6,87,0,1,0,113,170,87,0,113,52,4, - 0,116,7,121,158,1,0,1,0,1,0,89,0,113,52,89, - 0,113,52,48,0,113,52,116,7,100,8,131,1,130,1,116, - 8,124,1,100,9,124,6,131,3,1,0,116,8,124,1,100, - 10,124,5,131,3,1,0,116,8,124,1,100,11,100,12,160, - 9,124,4,161,1,131,3,1,0,116,8,124,1,100,13,100, - 14,100,15,132,0,124,4,68,0,131,1,131,3,1,0,103, - 0,100,16,162,1,125,7,124,3,100,3,107,2,144,1,114, - 6,124,7,160,10,100,17,161,1,1,0,124,7,68,0,93, - 52,125,8,124,8,116,1,106,3,118,1,144,1,114,38,116, - 0,160,6,124,8,161,1,125,9,110,10,116,1,106,3,124, - 8,25,0,125,9,116,8,124,1,124,8,124,9,131,3,1, - 0,144,1,113,10,116,8,124,1,100,18,116,11,131,0,131, - 3,1,0,116,12,160,13,116,2,160,14,161,0,161,1,1, - 0,124,3,100,3,107,2,144,1,114,128,116,15,160,10,100, - 19,161,1,1,0,100,20,116,12,118,0,144,1,114,128,100, - 21,116,16,95,17,100,22,83,0,41,23,122,205,83,101,116, - 117,112,32,116,104,101,32,112,97,116,104,45,98,97,115,101, - 100,32,105,109,112,111,114,116,101,114,115,32,102,111,114,32, - 105,109,112,111,114,116,108,105,98,32,98,121,32,105,109,112, - 111,114,116,105,110,103,32,110,101,101,100,101,100,10,32,32, - 32,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, - 101,115,32,97,110,100,32,105,110,106,101,99,116,105,110,103, - 32,116,104,101,109,32,105,110,116,111,32,116,104,101,32,103, - 108,111,98,97,108,32,110,97,109,101,115,112,97,99,101,46, - 10,10,32,32,32,32,79,116,104,101,114,32,99,111,109,112, - 111,110,101,110,116,115,32,97,114,101,32,101,120,116,114,97, - 99,116,101,100,32,102,114,111,109,32,116,104,101,32,99,111, - 114,101,32,98,111,111,116,115,116,114,97,112,32,109,111,100, - 117,108,101,46,10,10,32,32,32,32,218,5,112,111,115,105, - 120,114,2,0,0,0,218,2,110,116,114,1,0,0,0,99, + 0,4,0,0,0,19,0,0,0,115,36,0,0,0,116,0, + 124,0,131,1,115,10,116,1,100,1,124,0,100,2,141,2, + 130,1,136,0,124,0,103,1,136,1,162,1,82,0,142,0, + 83,0,41,3,122,45,80,97,116,104,32,104,111,111,107,32, + 102,111,114,32,105,109,112,111,114,116,108,105,98,46,109,97, + 99,104,105,110,101,114,121,46,70,105,108,101,70,105,110,100, + 101,114,46,122,30,111,110,108,121,32,100,105,114,101,99,116, + 111,114,105,101,115,32,97,114,101,32,115,117,112,112,111,114, + 116,101,100,114,71,0,0,0,41,2,114,83,0,0,0,114, + 142,0,0,0,114,71,0,0,0,169,2,114,221,0,0,0, + 114,103,1,0,0,114,7,0,0,0,114,8,0,0,0,218, + 24,112,97,116,104,95,104,111,111,107,95,102,111,114,95,70, + 105,108,101,70,105,110,100,101,114,92,6,0,0,115,6,0, + 0,0,8,2,12,1,16,1,122,54,70,105,108,101,70,105, + 110,100,101,114,46,112,97,116,104,95,104,111,111,107,46,60, + 108,111,99,97,108,115,62,46,112,97,116,104,95,104,111,111, + 107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,114, + 114,7,0,0,0,41,3,114,221,0,0,0,114,103,1,0, + 0,114,109,1,0,0,114,7,0,0,0,114,108,1,0,0, + 114,8,0,0,0,218,9,112,97,116,104,95,104,111,111,107, + 82,6,0,0,115,4,0,0,0,14,10,4,6,122,20,70, + 105,108,101,70,105,110,100,101,114,46,112,97,116,104,95,104, + 111,111,107,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,67,0,0,0,114,69,1,0, + 0,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, + 40,123,33,114,125,41,41,2,114,89,0,0,0,114,65,0, + 0,0,114,21,1,0,0,114,7,0,0,0,114,7,0,0, + 0,114,8,0,0,0,114,70,1,0,0,100,6,0,0,114, + 63,1,0,0,122,19,70,105,108,101,70,105,110,100,101,114, + 46,95,95,114,101,112,114,95,95,114,69,0,0,0,41,15, + 114,150,0,0,0,114,149,0,0,0,114,151,0,0,0,114, + 152,0,0,0,114,236,0,0,0,114,80,1,0,0,114,167, + 0,0,0,114,229,0,0,0,114,161,0,0,0,114,93,1, + 0,0,114,226,0,0,0,114,104,1,0,0,114,234,0,0, + 0,114,110,1,0,0,114,70,1,0,0,114,7,0,0,0, + 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,114, + 96,1,0,0,205,5,0,0,115,24,0,0,0,8,0,4, + 2,8,7,8,16,4,4,8,2,8,15,10,5,8,51,2, + 31,10,1,12,17,114,96,1,0,0,99,4,0,0,0,0, + 0,0,0,0,0,0,0,6,0,0,0,8,0,0,0,67, + 0,0,0,115,144,0,0,0,124,0,160,0,100,1,161,1, + 125,4,124,0,160,0,100,2,161,1,125,5,124,4,115,33, + 124,5,114,18,124,5,106,1,125,4,110,15,124,2,124,3, + 107,2,114,28,116,2,124,1,124,2,131,2,125,4,110,5, + 116,3,124,1,124,2,131,2,125,4,124,5,115,42,116,4, + 124,1,124,2,124,4,100,3,141,3,125,5,122,19,124,5, + 124,0,100,2,60,0,124,4,124,0,100,1,60,0,124,2, + 124,0,100,4,60,0,124,3,124,0,100,5,60,0,87,0, + 100,0,83,0,4,0,116,5,121,71,1,0,1,0,1,0, + 89,0,100,0,83,0,119,0,41,6,78,218,10,95,95,108, + 111,97,100,101,114,95,95,218,8,95,95,115,112,101,99,95, + 95,114,97,1,0,0,90,8,95,95,102,105,108,101,95,95, + 90,10,95,95,99,97,99,104,101,100,95,95,41,6,218,3, + 103,101,116,114,164,0,0,0,114,41,1,0,0,114,34,1, + 0,0,114,213,0,0,0,218,9,69,120,99,101,112,116,105, + 111,110,41,6,90,2,110,115,114,141,0,0,0,90,8,112, + 97,116,104,110,97,109,101,90,9,99,112,97,116,104,110,97, + 109,101,114,164,0,0,0,114,210,0,0,0,114,7,0,0, + 0,114,7,0,0,0,114,8,0,0,0,218,14,95,102,105, + 120,95,117,112,95,109,111,100,117,108,101,106,6,0,0,115, + 36,0,0,0,10,2,10,1,4,1,4,1,8,1,8,1, + 12,1,10,2,4,1,14,1,2,1,8,1,8,1,8,1, + 14,1,12,1,6,2,2,254,114,115,1,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,38,0,0,0,116,0,116,1,160, + 2,161,0,102,2,125,0,116,3,116,4,102,2,125,1,116, + 5,116,6,102,2,125,2,124,0,124,1,124,2,103,3,83, + 0,41,1,122,95,82,101,116,117,114,110,115,32,97,32,108, + 105,115,116,32,111,102,32,102,105,108,101,45,98,97,115,101, + 100,32,109,111,100,117,108,101,32,108,111,97,100,101,114,115, + 46,10,10,32,32,32,32,69,97,99,104,32,105,116,101,109, + 32,105,115,32,97,32,116,117,112,108,101,32,40,108,111,97, + 100,101,114,44,32,115,117,102,102,105,120,101,115,41,46,10, + 32,32,32,32,41,7,114,30,1,0,0,114,187,0,0,0, + 218,18,101,120,116,101,110,115,105,111,110,95,115,117,102,102, + 105,120,101,115,114,34,1,0,0,114,127,0,0,0,114,41, + 1,0,0,114,113,0,0,0,41,3,90,10,101,120,116,101, + 110,115,105,111,110,115,90,6,115,111,117,114,99,101,90,8, + 98,121,116,101,99,111,100,101,114,7,0,0,0,114,7,0, + 0,0,114,8,0,0,0,114,208,0,0,0,129,6,0,0, + 115,8,0,0,0,12,5,8,1,8,1,10,1,114,208,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,1,0,0,0,67,0,0,0,115,8,0,0,0, + 124,0,97,0,100,0,83,0,114,69,0,0,0,41,1,114, + 159,0,0,0,41,1,218,17,95,98,111,111,116,115,116,114, + 97,112,95,109,111,100,117,108,101,114,7,0,0,0,114,7, + 0,0,0,114,8,0,0,0,218,21,95,115,101,116,95,98, + 111,111,116,115,116,114,97,112,95,109,111,100,117,108,101,140, + 6,0,0,115,2,0,0,0,8,2,114,118,1,0,0,99, 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,115,0,0,0,115,26,0,0,0,124,0,93, - 18,125,1,116,0,124,1,131,1,100,0,107,2,86,0,1, - 0,113,2,100,1,83,0,114,3,0,0,0,114,5,0,0, - 0,114,7,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,12,0,0,0,136,6,0,0,114,13, - 0,0,0,122,25,95,115,101,116,117,112,46,60,108,111,99, - 97,108,115,62,46,60,103,101,110,101,120,112,114,62,114,0, - 0,0,0,122,30,105,109,112,111,114,116,108,105,98,32,114, - 101,113,117,105,114,101,115,32,112,111,115,105,120,32,111,114, - 32,110,116,114,24,0,0,0,114,59,0,0,0,114,50,0, - 0,0,114,14,0,0,0,218,20,95,112,97,116,104,115,101, - 112,115,95,119,105,116,104,95,99,111,108,111,110,99,1,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, - 0,0,83,0,0,0,115,22,0,0,0,104,0,124,0,93, - 14,125,1,100,0,124,1,155,0,157,2,146,2,113,4,83, - 0,114,15,0,0,0,114,10,0,0,0,114,17,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 19,0,0,0,153,6,0,0,114,13,0,0,0,122,25,95, - 115,101,116,117,112,46,60,108,111,99,97,108,115,62,46,60, - 115,101,116,99,111,109,112,62,41,3,114,90,0,0,0,114, - 98,0,0,0,114,184,0,0,0,114,215,0,0,0,114,27, - 0,0,0,122,4,46,112,121,119,122,6,95,100,46,112,121, - 100,84,78,41,18,114,158,0,0,0,114,21,0,0,0,114, - 187,0,0,0,114,56,1,0,0,114,149,0,0,0,218,3, - 97,108,108,90,18,95,98,117,105,108,116,105,110,95,102,114, - 111,109,95,110,97,109,101,114,141,0,0,0,114,153,0,0, - 0,114,62,0,0,0,114,61,0,0,0,114,32,0,0,0, - 114,44,1,0,0,114,191,0,0,0,114,106,1,0,0,114, - 126,0,0,0,114,214,0,0,0,114,218,0,0,0,41,10, - 218,17,95,98,111,111,116,115,116,114,97,112,95,109,111,100, - 117,108,101,90,11,115,101,108,102,95,109,111,100,117,108,101, - 90,10,111,115,95,100,101,116,97,105,108,115,90,10,98,117, - 105,108,116,105,110,95,111,115,114,50,0,0,0,114,59,0, - 0,0,90,9,111,115,95,109,111,100,117,108,101,90,13,98, - 117,105,108,116,105,110,95,110,97,109,101,115,90,12,98,117, - 105,108,116,105,110,95,110,97,109,101,90,14,98,117,105,108, - 116,105,110,95,109,111,100,117,108,101,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,6,95,115,101,116,117, - 112,118,6,0,0,115,70,0,0,0,0,8,4,1,6,1, - 6,2,10,3,22,1,12,2,22,1,8,1,10,1,10,1, - 6,2,2,1,10,1,10,1,12,1,12,2,8,2,12,1, - 12,1,18,1,22,3,8,1,10,1,10,1,8,1,12,1, - 12,2,10,1,16,3,14,1,14,1,10,1,10,1,10,1, - 114,112,1,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,50, - 0,0,0,116,0,124,0,131,1,1,0,116,1,131,0,125, - 1,116,2,106,3,160,4,116,5,106,6,124,1,142,0,103, - 1,161,1,1,0,116,2,106,7,160,8,116,9,161,1,1, - 0,100,1,83,0,41,2,122,41,73,110,115,116,97,108,108, - 32,116,104,101,32,112,97,116,104,45,98,97,115,101,100,32, - 105,109,112,111,114,116,32,99,111,109,112,111,110,101,110,116, - 115,46,78,41,10,114,112,1,0,0,114,208,0,0,0,114, - 21,0,0,0,114,76,1,0,0,114,191,0,0,0,114,86, - 1,0,0,114,100,1,0,0,218,9,109,101,116,97,95,112, - 97,116,104,114,61,0,0,0,114,70,1,0,0,41,2,114, - 111,1,0,0,90,17,115,117,112,112,111,114,116,101,100,95, - 108,111,97,100,101,114,115,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,8,95,105,110,115,116,97,108,108, - 175,6,0,0,115,8,0,0,0,0,2,8,1,6,1,20, - 1,114,114,1,0,0,41,1,114,86,0,0,0,41,1,78, - 41,3,78,78,78,41,2,114,0,0,0,0,114,0,0,0, - 0,41,1,84,41,1,78,41,1,78,41,81,114,151,0,0, - 0,114,187,0,0,0,114,90,0,0,0,114,21,0,0,0, - 114,98,0,0,0,114,184,0,0,0,114,28,0,0,0,90, - 11,95,77,83,95,87,73,78,68,79,87,83,114,108,1,0, - 0,114,24,0,0,0,114,215,0,0,0,114,107,1,0,0, - 114,50,0,0,0,114,110,1,0,0,114,59,0,0,0,114, - 135,0,0,0,114,57,0,0,0,114,62,0,0,0,114,109, - 1,0,0,114,31,0,0,0,90,37,95,67,65,83,69,95, - 73,78,83,69,78,83,73,84,73,86,69,95,80,76,65,84, - 70,79,82,77,83,95,66,89,84,69,83,95,75,69,89,114, - 30,0,0,0,114,32,0,0,0,114,39,0,0,0,114,44, - 0,0,0,114,46,0,0,0,114,67,0,0,0,114,74,0, - 0,0,114,75,0,0,0,114,79,0,0,0,114,80,0,0, - 0,114,82,0,0,0,114,85,0,0,0,114,94,0,0,0, - 218,4,116,121,112,101,218,8,95,95,99,111,100,101,95,95, - 114,186,0,0,0,114,37,0,0,0,114,172,0,0,0,114, - 36,0,0,0,114,41,0,0,0,114,3,1,0,0,114,115, - 0,0,0,114,111,0,0,0,114,126,0,0,0,114,112,0, - 0,0,90,23,68,69,66,85,71,95,66,89,84,69,67,79, - 68,69,95,83,85,70,70,73,88,69,83,90,27,79,80,84, - 73,77,73,90,69,68,95,66,89,84,69,67,79,68,69,95, - 83,85,70,70,73,88,69,83,114,120,0,0,0,114,127,0, - 0,0,114,134,0,0,0,114,136,0,0,0,114,138,0,0, - 0,114,160,0,0,0,114,167,0,0,0,114,176,0,0,0, - 114,180,0,0,0,114,182,0,0,0,114,189,0,0,0,114, - 194,0,0,0,114,195,0,0,0,114,200,0,0,0,218,6, - 111,98,106,101,99,116,114,209,0,0,0,114,213,0,0,0, - 114,214,0,0,0,114,231,0,0,0,114,244,0,0,0,114, - 6,1,0,0,114,32,1,0,0,114,39,1,0,0,114,44, - 1,0,0,114,19,1,0,0,114,45,1,0,0,114,68,1, - 0,0,114,70,1,0,0,114,86,1,0,0,114,105,1,0, - 0,114,208,0,0,0,114,112,1,0,0,114,114,1,0,0, - 114,10,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,8,60,109,111,100,117,108,101,62,1,0, - 0,0,115,170,0,0,0,4,22,8,1,8,1,8,1,8, - 1,8,3,10,1,4,1,8,1,10,2,8,3,4,1,10, - 2,6,2,22,1,8,1,8,1,10,1,14,4,4,1,4, - 1,2,1,2,255,4,4,8,17,8,5,8,5,8,6,4, - 1,10,30,8,6,8,8,8,10,8,9,8,5,8,7,6, - 1,10,8,8,5,10,22,10,127,0,20,16,1,12,2,4, - 1,4,2,6,2,6,2,8,2,16,71,8,40,8,19,8, - 12,8,12,8,28,8,17,8,33,8,28,8,24,10,13,10, - 10,10,11,8,14,6,3,4,1,2,255,12,68,14,64,14, - 29,16,127,0,17,14,72,18,45,18,26,4,3,18,58,14, - 69,14,42,14,127,0,23,14,127,0,27,10,23,8,11,8, - 57, + 4,0,0,0,67,0,0,0,115,50,0,0,0,116,0,124, + 0,131,1,1,0,116,1,131,0,125,1,116,2,106,3,160, + 4,116,5,106,6,124,1,142,0,103,1,161,1,1,0,116, + 2,106,7,160,8,116,9,161,1,1,0,100,1,83,0,41, + 2,122,41,73,110,115,116,97,108,108,32,116,104,101,32,112, + 97,116,104,45,98,97,115,101,100,32,105,109,112,111,114,116, + 32,99,111,109,112,111,110,101,110,116,115,46,78,41,10,114, + 118,1,0,0,114,208,0,0,0,114,15,0,0,0,114,85, + 1,0,0,114,191,0,0,0,114,96,1,0,0,114,110,1, + 0,0,218,9,109,101,116,97,95,112,97,116,104,114,61,0, + 0,0,114,79,1,0,0,41,2,114,117,1,0,0,90,17, + 115,117,112,112,111,114,116,101,100,95,108,111,97,100,101,114, + 115,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, + 218,8,95,105,110,115,116,97,108,108,145,6,0,0,115,8, + 0,0,0,8,2,6,1,20,1,16,1,114,120,1,0,0, + 41,1,114,87,0,0,0,114,69,0,0,0,41,3,78,78, + 78,41,2,114,0,0,0,0,114,0,0,0,0,41,1,84, + 41,85,114,152,0,0,0,114,159,0,0,0,114,187,0,0, + 0,114,91,0,0,0,114,15,0,0,0,114,99,0,0,0, + 114,184,0,0,0,114,25,0,0,0,114,231,0,0,0,90, + 2,110,116,114,18,0,0,0,114,215,0,0,0,90,5,112, + 111,115,105,120,114,50,0,0,0,218,3,97,108,108,114,59, + 0,0,0,114,136,0,0,0,114,57,0,0,0,114,62,0, + 0,0,90,20,95,112,97,116,104,115,101,112,115,95,119,105, + 116,104,95,99,111,108,111,110,114,28,0,0,0,90,37,95, + 67,65,83,69,95,73,78,83,69,78,83,73,84,73,86,69, + 95,80,76,65,84,70,79,82,77,83,95,66,89,84,69,83, + 95,75,69,89,114,27,0,0,0,114,29,0,0,0,114,21, + 0,0,0,114,36,0,0,0,114,42,0,0,0,114,45,0, + 0,0,114,67,0,0,0,114,74,0,0,0,114,75,0,0, + 0,114,79,0,0,0,114,80,0,0,0,114,83,0,0,0, + 114,86,0,0,0,114,95,0,0,0,218,4,116,121,112,101, + 218,8,95,95,99,111,100,101,95,95,114,186,0,0,0,114, + 34,0,0,0,114,172,0,0,0,114,33,0,0,0,114,39, + 0,0,0,114,8,1,0,0,114,116,0,0,0,114,112,0, + 0,0,114,127,0,0,0,114,61,0,0,0,114,116,1,0, + 0,114,232,0,0,0,114,113,0,0,0,90,23,68,69,66, + 85,71,95,66,89,84,69,67,79,68,69,95,83,85,70,70, + 73,88,69,83,90,27,79,80,84,73,77,73,90,69,68,95, + 66,89,84,69,67,79,68,69,95,83,85,70,70,73,88,69, + 83,114,121,0,0,0,114,128,0,0,0,114,135,0,0,0, + 114,137,0,0,0,114,139,0,0,0,114,160,0,0,0,114, + 167,0,0,0,114,176,0,0,0,114,180,0,0,0,114,182, + 0,0,0,114,189,0,0,0,114,194,0,0,0,114,195,0, + 0,0,114,200,0,0,0,218,6,111,98,106,101,99,116,114, + 209,0,0,0,114,213,0,0,0,114,214,0,0,0,114,235, + 0,0,0,114,249,0,0,0,114,11,1,0,0,114,34,1, + 0,0,114,41,1,0,0,114,30,1,0,0,114,47,1,0, + 0,114,75,1,0,0,114,79,1,0,0,114,96,1,0,0, + 114,115,1,0,0,114,208,0,0,0,114,118,1,0,0,114, + 120,1,0,0,114,7,0,0,0,114,7,0,0,0,114,7, + 0,0,0,114,8,0,0,0,218,8,60,109,111,100,117,108, + 101,62,1,0,0,0,115,180,0,0,0,4,0,4,22,8, + 3,8,1,8,1,8,1,8,1,10,3,4,1,8,1,10, + 1,8,2,4,3,10,1,6,2,22,2,8,1,8,1,10, + 1,14,1,4,4,4,1,2,1,2,1,4,255,8,4,6, + 16,8,3,8,5,8,5,4,6,10,1,8,30,8,6,8, + 8,8,10,8,9,8,5,4,7,10,1,8,8,10,5,10, + 22,0,127,16,30,12,1,4,2,4,1,6,2,4,1,10, + 1,8,2,6,2,8,2,16,2,8,71,8,40,8,19,8, + 12,8,12,8,31,8,20,8,33,8,28,10,24,10,13,10, + 10,8,11,6,14,4,3,2,1,12,255,14,73,14,67,16, + 30,0,127,14,17,18,50,18,45,18,25,14,53,14,69,14, + 49,0,127,14,32,0,127,10,30,8,23,8,11,12,5, }; diff --git a/contrib/tools/python3/src/Python/importlib_zipimport.h b/contrib/tools/python3/src/Python/importlib_zipimport.h index 373b1366bde..3c476841a8c 100644 --- a/contrib/tools/python3/src/Python/importlib_zipimport.h +++ b/contrib/tools/python3/src/Python/importlib_zipimport.h @@ -1,257 +1,318 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__zipimport[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,64,0,0,0,115,82,1,0,0,100,0, + 0,4,0,0,0,64,0,0,0,115,80,1,0,0,100,0, 90,0,100,1,100,2,108,1,90,2,100,1,100,3,108,1, 109,3,90,3,109,4,90,4,1,0,100,1,100,2,108,5, 90,6,100,1,100,2,108,7,90,7,100,1,100,2,108,8, 90,8,100,1,100,2,108,9,90,9,100,1,100,2,108,10, - 90,10,100,1,100,2,108,11,90,11,100,4,100,5,103,2, - 90,12,101,2,106,13,90,13,101,2,106,14,100,6,100,2, - 133,2,25,0,90,15,71,0,100,7,100,4,132,0,100,4, - 101,16,131,3,90,17,105,0,90,18,101,19,101,10,131,1, - 90,20,100,8,90,21,100,9,90,22,100,10,90,23,71,0, - 100,11,100,5,132,0,100,5,131,2,90,24,101,13,100,12, - 23,0,100,13,100,13,102,3,101,13,100,14,23,0,100,15, - 100,13,102,3,100,16,100,17,102,4,90,25,100,18,100,19, - 132,0,90,26,100,20,100,21,132,0,90,27,100,22,100,23, - 132,0,90,28,100,24,100,25,132,0,90,29,100,26,90,30, - 100,15,97,31,100,27,100,28,132,0,90,32,100,29,100,30, - 132,0,90,33,100,31,100,32,132,0,90,34,100,33,100,34, - 132,0,90,35,101,19,101,35,106,36,131,1,90,37,100,35, - 100,36,132,0,90,38,100,37,100,38,132,0,90,39,100,39, - 100,40,132,0,90,40,100,41,100,42,132,0,90,41,100,43, - 100,44,132,0,90,42,100,45,100,46,132,0,90,43,71,0, - 100,47,100,48,132,0,100,48,131,2,90,44,100,2,83,0, - 41,49,97,80,2,0,0,122,105,112,105,109,112,111,114,116, - 32,112,114,111,118,105,100,101,115,32,115,117,112,112,111,114, - 116,32,102,111,114,32,105,109,112,111,114,116,105,110,103,32, - 80,121,116,104,111,110,32,109,111,100,117,108,101,115,32,102, - 114,111,109,32,90,105,112,32,97,114,99,104,105,118,101,115, - 46,10,10,84,104,105,115,32,109,111,100,117,108,101,32,101, - 120,112,111,114,116,115,32,116,104,114,101,101,32,111,98,106, - 101,99,116,115,58,10,45,32,122,105,112,105,109,112,111,114, - 116,101,114,58,32,97,32,99,108,97,115,115,59,32,105,116, - 115,32,99,111,110,115,116,114,117,99,116,111,114,32,116,97, - 107,101,115,32,97,32,112,97,116,104,32,116,111,32,97,32, - 90,105,112,32,97,114,99,104,105,118,101,46,10,45,32,90, - 105,112,73,109,112,111,114,116,69,114,114,111,114,58,32,101, - 120,99,101,112,116,105,111,110,32,114,97,105,115,101,100,32, - 98,121,32,122,105,112,105,109,112,111,114,116,101,114,32,111, - 98,106,101,99,116,115,46,32,73,116,39,115,32,97,10,32, - 32,115,117,98,99,108,97,115,115,32,111,102,32,73,109,112, - 111,114,116,69,114,114,111,114,44,32,115,111,32,105,116,32, - 99,97,110,32,98,101,32,99,97,117,103,104,116,32,97,115, - 32,73,109,112,111,114,116,69,114,114,111,114,44,32,116,111, - 111,46,10,45,32,95,122,105,112,95,100,105,114,101,99,116, - 111,114,121,95,99,97,99,104,101,58,32,97,32,100,105,99, - 116,44,32,109,97,112,112,105,110,103,32,97,114,99,104,105, - 118,101,32,112,97,116,104,115,32,116,111,32,122,105,112,32, - 100,105,114,101,99,116,111,114,121,10,32,32,105,110,102,111, - 32,100,105,99,116,115,44,32,97,115,32,117,115,101,100,32, - 105,110,32,122,105,112,105,109,112,111,114,116,101,114,46,95, - 102,105,108,101,115,46,10,10,73,116,32,105,115,32,117,115, - 117,97,108,108,121,32,110,111,116,32,110,101,101,100,101,100, - 32,116,111,32,117,115,101,32,116,104,101,32,122,105,112,105, - 109,112,111,114,116,32,109,111,100,117,108,101,32,101,120,112, - 108,105,99,105,116,108,121,59,32,105,116,32,105,115,10,117, - 115,101,100,32,98,121,32,116,104,101,32,98,117,105,108,116, - 105,110,32,105,109,112,111,114,116,32,109,101,99,104,97,110, - 105,115,109,32,102,111,114,32,115,121,115,46,112,97,116,104, - 32,105,116,101,109,115,32,116,104,97,116,32,97,114,101,32, - 112,97,116,104,115,10,116,111,32,90,105,112,32,97,114,99, - 104,105,118,101,115,46,10,233,0,0,0,0,78,41,2,218, - 14,95,117,110,112,97,99,107,95,117,105,110,116,49,54,218, - 14,95,117,110,112,97,99,107,95,117,105,110,116,51,50,218, - 14,90,105,112,73,109,112,111,114,116,69,114,114,111,114,218, - 11,122,105,112,105,109,112,111,114,116,101,114,233,1,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,64,0,0,0,115,12,0,0,0,101, - 0,90,1,100,0,90,2,100,1,83,0,41,2,114,3,0, - 0,0,78,41,3,218,8,95,95,110,97,109,101,95,95,218, - 10,95,95,109,111,100,117,108,101,95,95,218,12,95,95,113, - 117,97,108,110,97,109,101,95,95,169,0,114,9,0,0,0, - 114,9,0,0,0,250,18,60,102,114,111,122,101,110,32,122, - 105,112,105,109,112,111,114,116,62,114,3,0,0,0,33,0, - 0,0,115,2,0,0,0,8,1,233,22,0,0,0,115,4, + 90,10,100,1,100,2,108,11,90,11,100,1,100,2,108,12, + 90,12,100,4,100,5,103,2,90,13,101,2,106,14,90,14, + 101,2,106,15,100,6,100,2,133,2,25,0,90,16,71,0, + 100,7,100,4,132,0,100,4,101,17,131,3,90,18,105,0, + 90,19,101,20,101,10,131,1,90,21,100,8,90,22,100,9, + 90,23,100,10,90,24,71,0,100,11,100,5,132,0,100,5, + 101,2,106,25,131,3,90,26,101,14,100,12,23,0,100,13, + 100,13,102,3,101,14,100,14,23,0,100,15,100,13,102,3, + 100,16,100,17,102,4,90,27,100,18,100,19,132,0,90,28, + 100,20,100,21,132,0,90,29,100,22,100,23,132,0,90,30, + 100,24,100,25,132,0,90,31,100,26,90,32,100,15,97,33, + 100,27,100,28,132,0,90,34,100,29,100,30,132,0,90,35, + 100,31,100,32,132,0,90,36,100,33,100,34,132,0,90,37, + 101,20,101,37,106,38,131,1,90,39,100,35,100,36,132,0, + 90,40,100,37,100,38,132,0,90,41,100,39,100,40,132,0, + 90,42,100,41,100,42,132,0,90,43,100,43,100,44,132,0, + 90,44,100,45,100,46,132,0,90,45,100,2,83,0,41,47, + 97,80,2,0,0,122,105,112,105,109,112,111,114,116,32,112, + 114,111,118,105,100,101,115,32,115,117,112,112,111,114,116,32, + 102,111,114,32,105,109,112,111,114,116,105,110,103,32,80,121, + 116,104,111,110,32,109,111,100,117,108,101,115,32,102,114,111, + 109,32,90,105,112,32,97,114,99,104,105,118,101,115,46,10, + 10,84,104,105,115,32,109,111,100,117,108,101,32,101,120,112, + 111,114,116,115,32,116,104,114,101,101,32,111,98,106,101,99, + 116,115,58,10,45,32,122,105,112,105,109,112,111,114,116,101, + 114,58,32,97,32,99,108,97,115,115,59,32,105,116,115,32, + 99,111,110,115,116,114,117,99,116,111,114,32,116,97,107,101, + 115,32,97,32,112,97,116,104,32,116,111,32,97,32,90,105, + 112,32,97,114,99,104,105,118,101,46,10,45,32,90,105,112, + 73,109,112,111,114,116,69,114,114,111,114,58,32,101,120,99, + 101,112,116,105,111,110,32,114,97,105,115,101,100,32,98,121, + 32,122,105,112,105,109,112,111,114,116,101,114,32,111,98,106, + 101,99,116,115,46,32,73,116,39,115,32,97,10,32,32,115, + 117,98,99,108,97,115,115,32,111,102,32,73,109,112,111,114, + 116,69,114,114,111,114,44,32,115,111,32,105,116,32,99,97, + 110,32,98,101,32,99,97,117,103,104,116,32,97,115,32,73, + 109,112,111,114,116,69,114,114,111,114,44,32,116,111,111,46, + 10,45,32,95,122,105,112,95,100,105,114,101,99,116,111,114, + 121,95,99,97,99,104,101,58,32,97,32,100,105,99,116,44, + 32,109,97,112,112,105,110,103,32,97,114,99,104,105,118,101, + 32,112,97,116,104,115,32,116,111,32,122,105,112,32,100,105, + 114,101,99,116,111,114,121,10,32,32,105,110,102,111,32,100, + 105,99,116,115,44,32,97,115,32,117,115,101,100,32,105,110, + 32,122,105,112,105,109,112,111,114,116,101,114,46,95,102,105, + 108,101,115,46,10,10,73,116,32,105,115,32,117,115,117,97, + 108,108,121,32,110,111,116,32,110,101,101,100,101,100,32,116, + 111,32,117,115,101,32,116,104,101,32,122,105,112,105,109,112, + 111,114,116,32,109,111,100,117,108,101,32,101,120,112,108,105, + 99,105,116,108,121,59,32,105,116,32,105,115,10,117,115,101, + 100,32,98,121,32,116,104,101,32,98,117,105,108,116,105,110, + 32,105,109,112,111,114,116,32,109,101,99,104,97,110,105,115, + 109,32,102,111,114,32,115,121,115,46,112,97,116,104,32,105, + 116,101,109,115,32,116,104,97,116,32,97,114,101,32,112,97, + 116,104,115,10,116,111,32,90,105,112,32,97,114,99,104,105, + 118,101,115,46,10,233,0,0,0,0,78,41,2,218,14,95, + 117,110,112,97,99,107,95,117,105,110,116,49,54,218,14,95, + 117,110,112,97,99,107,95,117,105,110,116,51,50,218,14,90, + 105,112,73,109,112,111,114,116,69,114,114,111,114,218,11,122, + 105,112,105,109,112,111,114,116,101,114,233,1,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,64,0,0,0,115,12,0,0,0,101,0,90, + 1,100,0,90,2,100,1,83,0,41,2,114,3,0,0,0, + 78,41,3,218,8,95,95,110,97,109,101,95,95,218,10,95, + 95,109,111,100,117,108,101,95,95,218,12,95,95,113,117,97, + 108,110,97,109,101,95,95,169,0,114,9,0,0,0,114,9, + 0,0,0,250,18,60,102,114,111,122,101,110,32,122,105,112, + 105,109,112,111,114,116,62,114,3,0,0,0,34,0,0,0, + 115,4,0,0,0,8,0,4,1,233,22,0,0,0,115,4, 0,0,0,80,75,5,6,105,255,255,0,0,99,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,64,0,0,0,115,108,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,25, - 100,5,100,6,132,1,90,5,100,26,100,7,100,8,132,1, - 90,6,100,9,100,10,132,0,90,7,100,11,100,12,132,0, - 90,8,100,13,100,14,132,0,90,9,100,15,100,16,132,0, - 90,10,100,17,100,18,132,0,90,11,100,19,100,20,132,0, - 90,12,100,21,100,22,132,0,90,13,100,23,100,24,132,0, - 90,14,100,4,83,0,41,27,114,4,0,0,0,97,255,1, - 0,0,122,105,112,105,109,112,111,114,116,101,114,40,97,114, - 99,104,105,118,101,112,97,116,104,41,32,45,62,32,122,105, - 112,105,109,112,111,114,116,101,114,32,111,98,106,101,99,116, - 10,10,32,32,32,32,67,114,101,97,116,101,32,97,32,110, - 101,119,32,122,105,112,105,109,112,111,114,116,101,114,32,105, - 110,115,116,97,110,99,101,46,32,39,97,114,99,104,105,118, - 101,112,97,116,104,39,32,109,117,115,116,32,98,101,32,97, - 32,112,97,116,104,32,116,111,10,32,32,32,32,97,32,122, - 105,112,102,105,108,101,44,32,111,114,32,116,111,32,97,32, - 115,112,101,99,105,102,105,99,32,112,97,116,104,32,105,110, - 115,105,100,101,32,97,32,122,105,112,102,105,108,101,46,32, - 70,111,114,32,101,120,97,109,112,108,101,44,32,105,116,32, - 99,97,110,32,98,101,10,32,32,32,32,39,47,116,109,112, - 47,109,121,105,109,112,111,114,116,46,122,105,112,39,44,32, - 111,114,32,39,47,116,109,112,47,109,121,105,109,112,111,114, - 116,46,122,105,112,47,109,121,100,105,114,101,99,116,111,114, - 121,39,44,32,105,102,32,109,121,100,105,114,101,99,116,111, - 114,121,32,105,115,32,97,10,32,32,32,32,118,97,108,105, - 100,32,100,105,114,101,99,116,111,114,121,32,105,110,115,105, - 100,101,32,116,104,101,32,97,114,99,104,105,118,101,46,10, - 10,32,32,32,32,39,90,105,112,73,109,112,111,114,116,69, - 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105, - 102,32,39,97,114,99,104,105,118,101,112,97,116,104,39,32, - 100,111,101,115,110,39,116,32,112,111,105,110,116,32,116,111, - 32,97,32,118,97,108,105,100,32,90,105,112,10,32,32,32, - 32,97,114,99,104,105,118,101,46,10,10,32,32,32,32,84, - 104,101,32,39,97,114,99,104,105,118,101,39,32,97,116,116, - 114,105,98,117,116,101,32,111,102,32,122,105,112,105,109,112, - 111,114,116,101,114,32,111,98,106,101,99,116,115,32,99,111, - 110,116,97,105,110,115,32,116,104,101,32,110,97,109,101,32, - 111,102,32,116,104,101,10,32,32,32,32,122,105,112,102,105, - 108,101,32,116,97,114,103,101,116,101,100,46,10,32,32,32, - 32,99,2,0,0,0,0,0,0,0,0,0,0,0,8,0, - 0,0,9,0,0,0,67,0,0,0,115,32,1,0,0,116, - 0,124,1,116,1,131,2,115,28,100,1,100,0,108,2,125, - 2,124,2,160,3,124,1,161,1,125,1,124,1,115,44,116, - 4,100,2,124,1,100,3,141,2,130,1,116,5,114,60,124, - 1,160,6,116,5,116,7,161,2,125,1,103,0,125,3,122, - 14,116,8,160,9,124,1,161,1,125,4,87,0,110,70,4, - 0,116,10,116,11,102,2,121,148,1,0,1,0,1,0,116, - 8,160,12,124,1,161,1,92,2,125,5,125,6,124,5,124, - 1,107,2,114,130,116,4,100,4,124,1,100,3,141,2,130, - 1,124,5,125,1,124,3,160,13,124,6,161,1,1,0,89, - 0,113,64,48,0,124,4,106,14,100,5,64,0,100,6,107, - 3,114,180,116,4,100,4,124,1,100,3,141,2,130,1,113, - 180,113,64,122,12,116,15,124,1,25,0,125,7,87,0,110, - 34,4,0,116,16,121,226,1,0,1,0,1,0,116,17,124, - 1,131,1,125,7,124,7,116,15,124,1,60,0,89,0,110, - 2,48,0,124,7,124,0,95,18,124,1,124,0,95,19,116, - 8,106,20,124,3,100,0,100,0,100,7,133,3,25,0,142, - 0,124,0,95,21,124,0,106,21,144,1,114,28,124,0,4, - 0,106,21,116,7,55,0,2,0,95,21,100,0,83,0,41, - 8,78,114,0,0,0,0,122,21,97,114,99,104,105,118,101, - 32,112,97,116,104,32,105,115,32,101,109,112,116,121,169,1, - 218,4,112,97,116,104,122,14,110,111,116,32,97,32,90,105, - 112,32,102,105,108,101,105,0,240,0,0,105,0,128,0,0, - 233,255,255,255,255,41,22,218,10,105,115,105,110,115,116,97, - 110,99,101,218,3,115,116,114,218,2,111,115,90,8,102,115, - 100,101,99,111,100,101,114,3,0,0,0,218,12,97,108,116, - 95,112,97,116,104,95,115,101,112,218,7,114,101,112,108,97, - 99,101,218,8,112,97,116,104,95,115,101,112,218,19,95,98, - 111,111,116,115,116,114,97,112,95,101,120,116,101,114,110,97, - 108,90,10,95,112,97,116,104,95,115,116,97,116,218,7,79, - 83,69,114,114,111,114,218,10,86,97,108,117,101,69,114,114, - 111,114,90,11,95,112,97,116,104,95,115,112,108,105,116,218, - 6,97,112,112,101,110,100,90,7,115,116,95,109,111,100,101, - 218,20,95,122,105,112,95,100,105,114,101,99,116,111,114,121, - 95,99,97,99,104,101,218,8,75,101,121,69,114,114,111,114, - 218,15,95,114,101,97,100,95,100,105,114,101,99,116,111,114, - 121,218,6,95,102,105,108,101,115,218,7,97,114,99,104,105, - 118,101,218,10,95,112,97,116,104,95,106,111,105,110,218,6, - 112,114,101,102,105,120,41,8,218,4,115,101,108,102,114,13, - 0,0,0,114,17,0,0,0,114,31,0,0,0,90,2,115, - 116,90,7,100,105,114,110,97,109,101,90,8,98,97,115,101, - 110,97,109,101,218,5,102,105,108,101,115,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,8,95,95,105,110, - 105,116,95,95,63,0,0,0,115,58,0,0,0,0,1,10, - 1,8,1,10,1,4,1,12,1,4,1,12,2,4,2,2, - 1,14,1,16,3,14,1,8,1,12,1,4,1,16,3,14, - 2,12,1,4,2,2,1,12,1,12,1,8,1,14,1,6, - 1,6,2,22,1,8,1,122,20,122,105,112,105,109,112,111, - 114,116,101,114,46,95,95,105,110,105,116,95,95,78,99,3, - 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4, - 0,0,0,67,0,0,0,115,78,0,0,0,116,0,124,0, - 124,1,131,2,125,3,124,3,100,1,117,1,114,26,124,0, - 103,0,102,2,83,0,116,1,124,0,124,1,131,2,125,4, - 116,2,124,0,124,4,131,2,114,70,100,1,124,0,106,3, - 155,0,116,4,155,0,124,4,155,0,157,3,103,1,102,2, - 83,0,100,1,103,0,102,2,83,0,41,2,97,239,1,0, - 0,102,105,110,100,95,108,111,97,100,101,114,40,102,117,108, - 108,110,97,109,101,44,32,112,97,116,104,61,78,111,110,101, - 41,32,45,62,32,115,101,108,102,44,32,115,116,114,32,111, - 114,32,78,111,110,101,46,10,10,32,32,32,32,32,32,32, - 32,83,101,97,114,99,104,32,102,111,114,32,97,32,109,111, - 100,117,108,101,32,115,112,101,99,105,102,105,101,100,32,98, - 121,32,39,102,117,108,108,110,97,109,101,39,46,32,39,102, - 117,108,108,110,97,109,101,39,32,109,117,115,116,32,98,101, - 32,116,104,101,10,32,32,32,32,32,32,32,32,102,117,108, - 108,121,32,113,117,97,108,105,102,105,101,100,32,40,100,111, - 116,116,101,100,41,32,109,111,100,117,108,101,32,110,97,109, - 101,46,32,73,116,32,114,101,116,117,114,110,115,32,116,104, - 101,32,122,105,112,105,109,112,111,114,116,101,114,10,32,32, - 32,32,32,32,32,32,105,110,115,116,97,110,99,101,32,105, - 116,115,101,108,102,32,105,102,32,116,104,101,32,109,111,100, - 117,108,101,32,119,97,115,32,102,111,117,110,100,44,32,97, - 32,115,116,114,105,110,103,32,99,111,110,116,97,105,110,105, - 110,103,32,116,104,101,10,32,32,32,32,32,32,32,32,102, - 117,108,108,32,112,97,116,104,32,110,97,109,101,32,105,102, - 32,105,116,39,115,32,112,111,115,115,105,98,108,121,32,97, - 32,112,111,114,116,105,111,110,32,111,102,32,97,32,110,97, - 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,44, - 10,32,32,32,32,32,32,32,32,111,114,32,78,111,110,101, - 32,111,116,104,101,114,119,105,115,101,46,32,84,104,101,32, - 111,112,116,105,111,110,97,108,32,39,112,97,116,104,39,32, - 97,114,103,117,109,101,110,116,32,105,115,32,105,103,110,111, - 114,101,100,32,45,45,32,105,116,39,115,10,32,32,32,32, - 32,32,32,32,116,104,101,114,101,32,102,111,114,32,99,111, - 109,112,97,116,105,98,105,108,105,116,121,32,119,105,116,104, - 32,116,104,101,32,105,109,112,111,114,116,101,114,32,112,114, - 111,116,111,99,111,108,46,10,32,32,32,32,32,32,32,32, - 78,41,5,218,16,95,103,101,116,95,109,111,100,117,108,101, - 95,105,110,102,111,218,16,95,103,101,116,95,109,111,100,117, - 108,101,95,112,97,116,104,218,7,95,105,115,95,100,105,114, - 114,29,0,0,0,114,20,0,0,0,41,5,114,32,0,0, - 0,218,8,102,117,108,108,110,97,109,101,114,13,0,0,0, - 218,2,109,105,218,7,109,111,100,112,97,116,104,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,11,102,105, - 110,100,95,108,111,97,100,101,114,109,0,0,0,115,14,0, - 0,0,0,10,10,1,8,2,8,7,10,1,10,4,24,2, + 0,64,0,0,0,115,126,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,29, + 100,5,100,6,132,1,90,5,100,29,100,7,100,8,132,1, + 90,6,100,29,100,9,100,10,132,1,90,7,100,11,100,12, + 132,0,90,8,100,13,100,14,132,0,90,9,100,15,100,16, + 132,0,90,10,100,17,100,18,132,0,90,11,100,19,100,20, + 132,0,90,12,100,21,100,22,132,0,90,13,100,23,100,24, + 132,0,90,14,100,25,100,26,132,0,90,15,100,27,100,28, + 132,0,90,16,100,4,83,0,41,30,114,4,0,0,0,97, + 255,1,0,0,122,105,112,105,109,112,111,114,116,101,114,40, + 97,114,99,104,105,118,101,112,97,116,104,41,32,45,62,32, + 122,105,112,105,109,112,111,114,116,101,114,32,111,98,106,101, + 99,116,10,10,32,32,32,32,67,114,101,97,116,101,32,97, + 32,110,101,119,32,122,105,112,105,109,112,111,114,116,101,114, + 32,105,110,115,116,97,110,99,101,46,32,39,97,114,99,104, + 105,118,101,112,97,116,104,39,32,109,117,115,116,32,98,101, + 32,97,32,112,97,116,104,32,116,111,10,32,32,32,32,97, + 32,122,105,112,102,105,108,101,44,32,111,114,32,116,111,32, + 97,32,115,112,101,99,105,102,105,99,32,112,97,116,104,32, + 105,110,115,105,100,101,32,97,32,122,105,112,102,105,108,101, + 46,32,70,111,114,32,101,120,97,109,112,108,101,44,32,105, + 116,32,99,97,110,32,98,101,10,32,32,32,32,39,47,116, + 109,112,47,109,121,105,109,112,111,114,116,46,122,105,112,39, + 44,32,111,114,32,39,47,116,109,112,47,109,121,105,109,112, + 111,114,116,46,122,105,112,47,109,121,100,105,114,101,99,116, + 111,114,121,39,44,32,105,102,32,109,121,100,105,114,101,99, + 116,111,114,121,32,105,115,32,97,10,32,32,32,32,118,97, + 108,105,100,32,100,105,114,101,99,116,111,114,121,32,105,110, + 115,105,100,101,32,116,104,101,32,97,114,99,104,105,118,101, + 46,10,10,32,32,32,32,39,90,105,112,73,109,112,111,114, + 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 32,105,102,32,39,97,114,99,104,105,118,101,112,97,116,104, + 39,32,100,111,101,115,110,39,116,32,112,111,105,110,116,32, + 116,111,32,97,32,118,97,108,105,100,32,90,105,112,10,32, + 32,32,32,97,114,99,104,105,118,101,46,10,10,32,32,32, + 32,84,104,101,32,39,97,114,99,104,105,118,101,39,32,97, + 116,116,114,105,98,117,116,101,32,111,102,32,122,105,112,105, + 109,112,111,114,116,101,114,32,111,98,106,101,99,116,115,32, + 99,111,110,116,97,105,110,115,32,116,104,101,32,110,97,109, + 101,32,111,102,32,116,104,101,10,32,32,32,32,122,105,112, + 102,105,108,101,32,116,97,114,103,101,116,101,100,46,10,32, + 32,32,32,99,2,0,0,0,0,0,0,0,0,0,0,0, + 8,0,0,0,9,0,0,0,67,0,0,0,115,36,1,0, + 0,116,0,124,1,116,1,131,2,115,14,100,1,100,0,108, + 2,125,2,124,2,160,3,124,1,161,1,125,1,124,1,115, + 22,116,4,100,2,124,1,100,3,141,2,130,1,116,5,114, + 30,124,1,160,6,116,5,116,7,161,2,125,1,103,0,125, + 3,9,0,122,7,116,8,160,9,124,1,161,1,125,4,87, + 0,110,35,4,0,116,10,116,11,102,2,121,75,1,0,1, + 0,1,0,116,8,160,12,124,1,161,1,92,2,125,5,125, + 6,124,5,124,1,107,2,114,66,116,4,100,5,124,1,100, + 3,141,2,130,1,124,5,125,1,124,3,160,13,124,6,161, + 1,1,0,89,0,110,15,119,0,124,4,106,14,100,6,64, + 0,100,7,107,3,114,89,116,4,100,5,124,1,100,3,141, + 2,130,1,110,1,113,33,122,6,116,15,124,1,25,0,125, + 7,87,0,110,17,4,0,116,16,121,114,1,0,1,0,1, + 0,116,17,124,1,131,1,125,7,124,7,116,15,124,1,60, + 0,89,0,110,1,119,0,124,7,124,0,95,18,124,1,124, + 0,95,19,116,8,106,20,124,3,100,0,100,0,100,8,133, + 3,25,0,142,0,124,0,95,21,124,0,106,21,114,144,124, + 0,4,0,106,21,116,7,55,0,2,0,95,21,100,0,83, + 0,100,0,83,0,41,9,78,114,0,0,0,0,122,21,97, + 114,99,104,105,118,101,32,112,97,116,104,32,105,115,32,101, + 109,112,116,121,169,1,218,4,112,97,116,104,84,122,14,110, + 111,116,32,97,32,90,105,112,32,102,105,108,101,105,0,240, + 0,0,105,0,128,0,0,233,255,255,255,255,41,22,218,10, + 105,115,105,110,115,116,97,110,99,101,218,3,115,116,114,218, + 2,111,115,90,8,102,115,100,101,99,111,100,101,114,3,0, + 0,0,218,12,97,108,116,95,112,97,116,104,95,115,101,112, + 218,7,114,101,112,108,97,99,101,218,8,112,97,116,104,95, + 115,101,112,218,19,95,98,111,111,116,115,116,114,97,112,95, + 101,120,116,101,114,110,97,108,90,10,95,112,97,116,104,95, + 115,116,97,116,218,7,79,83,69,114,114,111,114,218,10,86, + 97,108,117,101,69,114,114,111,114,90,11,95,112,97,116,104, + 95,115,112,108,105,116,218,6,97,112,112,101,110,100,90,7, + 115,116,95,109,111,100,101,218,20,95,122,105,112,95,100,105, + 114,101,99,116,111,114,121,95,99,97,99,104,101,218,8,75, + 101,121,69,114,114,111,114,218,15,95,114,101,97,100,95,100, + 105,114,101,99,116,111,114,121,218,6,95,102,105,108,101,115, + 218,7,97,114,99,104,105,118,101,218,10,95,112,97,116,104, + 95,106,111,105,110,218,6,112,114,101,102,105,120,41,8,218, + 4,115,101,108,102,114,13,0,0,0,114,17,0,0,0,114, + 31,0,0,0,90,2,115,116,90,7,100,105,114,110,97,109, + 101,90,8,98,97,115,101,110,97,109,101,218,5,102,105,108, + 101,115,114,9,0,0,0,114,9,0,0,0,114,10,0,0, + 0,218,8,95,95,105,110,105,116,95,95,64,0,0,0,115, + 68,0,0,0,10,1,8,1,10,1,4,1,12,1,4,1, + 12,1,4,2,2,1,2,1,14,1,16,1,14,3,8,1, + 12,1,4,1,14,1,2,249,14,10,12,2,2,1,2,240, + 2,18,12,1,12,1,8,1,12,1,2,254,6,3,6,1, + 22,2,6,1,18,1,4,255,122,20,122,105,112,105,109,112, + 111,114,116,101,114,46,95,95,105,110,105,116,95,95,78,99, + 3,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, + 4,0,0,0,67,0,0,0,115,90,0,0,0,116,0,160, + 1,100,1,116,2,161,2,1,0,116,3,124,0,124,1,131, + 2,125,3,124,3,100,2,117,1,114,19,124,0,103,0,102, + 2,83,0,116,4,124,0,124,1,131,2,125,4,116,5,124, + 0,124,4,131,2,114,41,100,2,124,0,106,6,155,0,116, + 7,155,0,124,4,155,0,157,3,103,1,102,2,83,0,100, + 2,103,0,102,2,83,0,41,3,97,47,2,0,0,102,105, + 110,100,95,108,111,97,100,101,114,40,102,117,108,108,110,97, + 109,101,44,32,112,97,116,104,61,78,111,110,101,41,32,45, + 62,32,115,101,108,102,44,32,115,116,114,32,111,114,32,78, + 111,110,101,46,10,10,32,32,32,32,32,32,32,32,83,101, + 97,114,99,104,32,102,111,114,32,97,32,109,111,100,117,108, + 101,32,115,112,101,99,105,102,105,101,100,32,98,121,32,39, + 102,117,108,108,110,97,109,101,39,46,32,39,102,117,108,108, + 110,97,109,101,39,32,109,117,115,116,32,98,101,32,116,104, + 101,10,32,32,32,32,32,32,32,32,102,117,108,108,121,32, + 113,117,97,108,105,102,105,101,100,32,40,100,111,116,116,101, + 100,41,32,109,111,100,117,108,101,32,110,97,109,101,46,32, + 73,116,32,114,101,116,117,114,110,115,32,116,104,101,32,122, + 105,112,105,109,112,111,114,116,101,114,10,32,32,32,32,32, + 32,32,32,105,110,115,116,97,110,99,101,32,105,116,115,101, + 108,102,32,105,102,32,116,104,101,32,109,111,100,117,108,101, + 32,119,97,115,32,102,111,117,110,100,44,32,97,32,115,116, + 114,105,110,103,32,99,111,110,116,97,105,110,105,110,103,32, + 116,104,101,10,32,32,32,32,32,32,32,32,102,117,108,108, + 32,112,97,116,104,32,110,97,109,101,32,105,102,32,105,116, + 39,115,32,112,111,115,115,105,98,108,121,32,97,32,112,111, + 114,116,105,111,110,32,111,102,32,97,32,110,97,109,101,115, + 112,97,99,101,32,112,97,99,107,97,103,101,44,10,32,32, + 32,32,32,32,32,32,111,114,32,78,111,110,101,32,111,116, + 104,101,114,119,105,115,101,46,32,84,104,101,32,111,112,116, + 105,111,110,97,108,32,39,112,97,116,104,39,32,97,114,103, + 117,109,101,110,116,32,105,115,32,105,103,110,111,114,101,100, + 32,45,45,32,105,116,39,115,10,32,32,32,32,32,32,32, + 32,116,104,101,114,101,32,102,111,114,32,99,111,109,112,97, + 116,105,98,105,108,105,116,121,32,119,105,116,104,32,116,104, + 101,32,105,109,112,111,114,116,101,114,32,112,114,111,116,111, + 99,111,108,46,10,10,32,32,32,32,32,32,32,32,68,101, + 112,114,101,99,97,116,101,100,32,115,105,110,99,101,32,80, + 121,116,104,111,110,32,51,46,49,48,46,32,85,115,101,32, + 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, + 101,97,100,46,10,32,32,32,32,32,32,32,32,122,102,122, + 105,112,105,109,112,111,114,116,101,114,46,102,105,110,100,95, + 108,111,97,100,101,114,40,41,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,32,97,110,100,32,115,108,97,116,101, + 100,32,102,111,114,32,114,101,109,111,118,97,108,32,105,110, + 32,80,121,116,104,111,110,32,51,46,49,50,59,32,117,115, + 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, + 115,116,101,97,100,78,41,8,218,9,95,119,97,114,110,105, + 110,103,115,218,4,119,97,114,110,218,18,68,101,112,114,101, + 99,97,116,105,111,110,87,97,114,110,105,110,103,218,16,95, + 103,101,116,95,109,111,100,117,108,101,95,105,110,102,111,218, + 16,95,103,101,116,95,109,111,100,117,108,101,95,112,97,116, + 104,218,7,95,105,115,95,100,105,114,114,29,0,0,0,114, + 20,0,0,0,41,5,114,32,0,0,0,218,8,102,117,108, + 108,110,97,109,101,114,13,0,0,0,218,2,109,105,218,7, + 109,111,100,112,97,116,104,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,11,102,105,110,100,95,108,111,97, + 100,101,114,110,0,0,0,115,20,0,0,0,6,12,2,2, + 4,254,10,3,8,1,8,2,10,7,10,1,24,4,8,2, 122,23,122,105,112,105,109,112,111,114,116,101,114,46,102,105, 110,100,95,108,111,97,100,101,114,99,3,0,0,0,0,0, 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, - 0,0,115,16,0,0,0,124,0,160,0,124,1,124,2,161, - 2,100,1,25,0,83,0,41,2,97,139,1,0,0,102,105, - 110,100,95,109,111,100,117,108,101,40,102,117,108,108,110,97, - 109,101,44,32,112,97,116,104,61,78,111,110,101,41,32,45, - 62,32,115,101,108,102,32,111,114,32,78,111,110,101,46,10, - 10,32,32,32,32,32,32,32,32,83,101,97,114,99,104,32, - 102,111,114,32,97,32,109,111,100,117,108,101,32,115,112,101, - 99,105,102,105,101,100,32,98,121,32,39,102,117,108,108,110, - 97,109,101,39,46,32,39,102,117,108,108,110,97,109,101,39, - 32,109,117,115,116,32,98,101,32,116,104,101,10,32,32,32, - 32,32,32,32,32,102,117,108,108,121,32,113,117,97,108,105, - 102,105,101,100,32,40,100,111,116,116,101,100,41,32,109,111, - 100,117,108,101,32,110,97,109,101,46,32,73,116,32,114,101, - 116,117,114,110,115,32,116,104,101,32,122,105,112,105,109,112, - 111,114,116,101,114,10,32,32,32,32,32,32,32,32,105,110, - 115,116,97,110,99,101,32,105,116,115,101,108,102,32,105,102, - 32,116,104,101,32,109,111,100,117,108,101,32,119,97,115,32, - 102,111,117,110,100,44,32,111,114,32,78,111,110,101,32,105, - 102,32,105,116,32,119,97,115,110,39,116,46,10,32,32,32, - 32,32,32,32,32,84,104,101,32,111,112,116,105,111,110,97, - 108,32,39,112,97,116,104,39,32,97,114,103,117,109,101,110, - 116,32,105,115,32,105,103,110,111,114,101,100,32,45,45,32, - 105,116,39,115,32,116,104,101,114,101,32,102,111,114,32,99, - 111,109,112,97,116,105,98,105,108,105,116,121,10,32,32,32, - 32,32,32,32,32,119,105,116,104,32,116,104,101,32,105,109, - 112,111,114,116,101,114,32,112,114,111,116,111,99,111,108,46, - 10,32,32,32,32,32,32,32,32,114,0,0,0,0,41,1, - 114,41,0,0,0,41,3,114,32,0,0,0,114,38,0,0, - 0,114,13,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,11,102,105,110,100,95,109,111,100,117, - 108,101,141,0,0,0,115,2,0,0,0,0,9,122,23,122, - 105,112,105,109,112,111,114,116,101,114,46,102,105,110,100,95, - 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, + 0,0,115,28,0,0,0,116,0,160,1,100,1,116,2,161, + 2,1,0,124,0,160,3,124,1,124,2,161,2,100,2,25, + 0,83,0,41,3,97,203,1,0,0,102,105,110,100,95,109, + 111,100,117,108,101,40,102,117,108,108,110,97,109,101,44,32, + 112,97,116,104,61,78,111,110,101,41,32,45,62,32,115,101, + 108,102,32,111,114,32,78,111,110,101,46,10,10,32,32,32, + 32,32,32,32,32,83,101,97,114,99,104,32,102,111,114,32, + 97,32,109,111,100,117,108,101,32,115,112,101,99,105,102,105, + 101,100,32,98,121,32,39,102,117,108,108,110,97,109,101,39, + 46,32,39,102,117,108,108,110,97,109,101,39,32,109,117,115, + 116,32,98,101,32,116,104,101,10,32,32,32,32,32,32,32, + 32,102,117,108,108,121,32,113,117,97,108,105,102,105,101,100, + 32,40,100,111,116,116,101,100,41,32,109,111,100,117,108,101, + 32,110,97,109,101,46,32,73,116,32,114,101,116,117,114,110, + 115,32,116,104,101,32,122,105,112,105,109,112,111,114,116,101, + 114,10,32,32,32,32,32,32,32,32,105,110,115,116,97,110, + 99,101,32,105,116,115,101,108,102,32,105,102,32,116,104,101, + 32,109,111,100,117,108,101,32,119,97,115,32,102,111,117,110, + 100,44,32,111,114,32,78,111,110,101,32,105,102,32,105,116, + 32,119,97,115,110,39,116,46,10,32,32,32,32,32,32,32, + 32,84,104,101,32,111,112,116,105,111,110,97,108,32,39,112, + 97,116,104,39,32,97,114,103,117,109,101,110,116,32,105,115, + 32,105,103,110,111,114,101,100,32,45,45,32,105,116,39,115, + 32,116,104,101,114,101,32,102,111,114,32,99,111,109,112,97, + 116,105,98,105,108,105,116,121,10,32,32,32,32,32,32,32, + 32,119,105,116,104,32,116,104,101,32,105,109,112,111,114,116, + 101,114,32,112,114,111,116,111,99,111,108,46,10,10,32,32, + 32,32,32,32,32,32,68,101,112,114,101,99,97,116,101,100, + 32,115,105,110,99,101,32,80,121,116,104,111,110,32,51,46, + 49,48,46,32,85,115,101,32,102,105,110,100,95,115,112,101, + 99,40,41,32,105,110,115,116,101,97,100,46,10,32,32,32, + 32,32,32,32,32,122,102,122,105,112,105,109,112,111,114,116, + 101,114,46,102,105,110,100,95,109,111,100,117,108,101,40,41, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,32,97, + 110,100,32,115,108,97,116,101,100,32,102,111,114,32,114,101, + 109,111,118,97,108,32,105,110,32,80,121,116,104,111,110,32, + 51,46,49,50,59,32,117,115,101,32,102,105,110,100,95,115, + 112,101,99,40,41,32,105,110,115,116,101,97,100,114,0,0, + 0,0,41,4,114,35,0,0,0,114,36,0,0,0,114,37, + 0,0,0,114,44,0,0,0,41,3,114,32,0,0,0,114, + 41,0,0,0,114,13,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,11,102,105,110,100,95,109, + 111,100,117,108,101,147,0,0,0,115,8,0,0,0,6,11, + 2,2,4,254,16,3,122,23,122,105,112,105,109,112,111,114, + 116,101,114,46,102,105,110,100,95,109,111,100,117,108,101,99, + 3,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, + 5,0,0,0,67,0,0,0,115,108,0,0,0,116,0,124, + 0,124,1,131,2,125,3,124,3,100,1,117,1,114,17,116, + 1,106,2,124,1,124,0,124,3,100,2,141,3,83,0,116, + 3,124,0,124,1,131,2,125,4,116,4,124,0,124,4,131, + 2,114,52,124,0,106,5,155,0,116,6,155,0,124,4,155, + 0,157,3,125,5,116,1,106,7,124,1,100,1,100,3,100, + 4,141,3,125,6,124,6,106,8,160,9,124,5,161,1,1, + 0,124,6,83,0,100,1,83,0,41,5,122,107,67,114,101, + 97,116,101,32,97,32,77,111,100,117,108,101,83,112,101,99, + 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, + 101,100,32,109,111,100,117,108,101,46,10,10,32,32,32,32, + 32,32,32,32,82,101,116,117,114,110,115,32,78,111,110,101, + 32,105,102,32,116,104,101,32,109,111,100,117,108,101,32,99, + 97,110,110,111,116,32,98,101,32,102,111,117,110,100,46,10, + 32,32,32,32,32,32,32,32,78,41,1,218,10,105,115,95, + 112,97,99,107,97,103,101,84,41,3,218,4,110,97,109,101, + 90,6,108,111,97,100,101,114,114,46,0,0,0,41,10,114, + 38,0,0,0,218,10,95,98,111,111,116,115,116,114,97,112, + 90,16,115,112,101,99,95,102,114,111,109,95,108,111,97,100, + 101,114,114,39,0,0,0,114,40,0,0,0,114,29,0,0, + 0,114,20,0,0,0,90,10,77,111,100,117,108,101,83,112, + 101,99,90,26,115,117,98,109,111,100,117,108,101,95,115,101, + 97,114,99,104,95,108,111,99,97,116,105,111,110,115,114,24, + 0,0,0,41,7,114,32,0,0,0,114,41,0,0,0,90, + 6,116,97,114,103,101,116,90,11,109,111,100,117,108,101,95, + 105,110,102,111,114,43,0,0,0,114,13,0,0,0,90,4, + 115,112,101,99,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,9,102,105,110,100,95,115,112,101,99,163,0, + 0,0,115,24,0,0,0,10,5,8,1,16,1,10,7,10, + 1,18,4,8,1,2,1,6,255,12,2,4,1,4,2,122, + 21,122,105,112,105,109,112,111,114,116,101,114,46,102,105,110, + 100,95,115,112,101,99,99,2,0,0,0,0,0,0,0,0, 0,0,0,5,0,0,0,3,0,0,0,67,0,0,0,115, 20,0,0,0,116,0,124,0,124,1,131,2,92,3,125,2, - 125,3,125,4,124,2,83,0,41,1,122,163,103,101,116,95, + 125,3,125,4,124,2,83,0,41,1,122,166,103,101,116,95, 99,111,100,101,40,102,117,108,108,110,97,109,101,41,32,45, 62,32,99,111,100,101,32,111,98,106,101,99,116,46,10,10, 32,32,32,32,32,32,32,32,82,101,116,117,114,110,32,116, @@ -261,559 +322,584 @@ const unsigned char _Py_M__zipimport[] = { 105,112,73,109,112,111,114,116,69,114,114,111,114,10,32,32, 32,32,32,32,32,32,105,102,32,116,104,101,32,109,111,100, 117,108,101,32,99,111,117,108,100,110,39,116,32,98,101,32, - 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,169, - 1,218,16,95,103,101,116,95,109,111,100,117,108,101,95,99, - 111,100,101,169,5,114,32,0,0,0,114,38,0,0,0,218, - 4,99,111,100,101,218,9,105,115,112,97,99,107,97,103,101, - 114,40,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,218,8,103,101,116,95,99,111,100,101,153,0, - 0,0,115,4,0,0,0,0,6,16,1,122,20,122,105,112, - 105,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,8,0,0,0,67,0,0,0,115,116,0,0,0,116, - 0,114,16,124,1,160,1,116,0,116,2,161,2,125,1,124, - 1,125,2,124,1,160,3,124,0,106,4,116,2,23,0,161, - 1,114,58,124,1,116,5,124,0,106,4,116,2,23,0,131, - 1,100,1,133,2,25,0,125,2,122,14,124,0,106,6,124, - 2,25,0,125,3,87,0,110,30,4,0,116,7,121,102,1, - 0,1,0,1,0,116,8,100,2,100,3,124,2,131,3,130, - 1,89,0,110,2,48,0,116,9,124,0,106,4,124,3,131, - 2,83,0,41,4,122,154,103,101,116,95,100,97,116,97,40, - 112,97,116,104,110,97,109,101,41,32,45,62,32,115,116,114, - 105,110,103,32,119,105,116,104,32,102,105,108,101,32,100,97, - 116,97,46,10,10,32,32,32,32,32,32,32,32,82,101,116, - 117,114,110,32,116,104,101,32,100,97,116,97,32,97,115,115, - 111,99,105,97,116,101,100,32,119,105,116,104,32,39,112,97, - 116,104,110,97,109,101,39,46,32,82,97,105,115,101,32,79, - 83,69,114,114,111,114,32,105,102,10,32,32,32,32,32,32, - 32,32,116,104,101,32,102,105,108,101,32,119,97,115,110,39, - 116,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32, - 32,78,114,0,0,0,0,218,0,41,10,114,18,0,0,0, - 114,19,0,0,0,114,20,0,0,0,218,10,115,116,97,114, - 116,115,119,105,116,104,114,29,0,0,0,218,3,108,101,110, - 114,28,0,0,0,114,26,0,0,0,114,22,0,0,0,218, - 9,95,103,101,116,95,100,97,116,97,41,4,114,32,0,0, - 0,218,8,112,97,116,104,110,97,109,101,90,3,107,101,121, - 218,9,116,111,99,95,101,110,116,114,121,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,8,103,101,116,95, - 100,97,116,97,163,0,0,0,115,20,0,0,0,0,6,4, - 1,12,2,4,1,16,1,22,2,2,1,14,1,12,1,18, - 1,122,20,122,105,112,105,109,112,111,114,116,101,114,46,103, - 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,3,0,0,0,67,0,0,0, - 115,20,0,0,0,116,0,124,0,124,1,131,2,92,3,125, - 2,125,3,125,4,124,4,83,0,41,1,122,106,103,101,116, - 95,102,105,108,101,110,97,109,101,40,102,117,108,108,110,97, - 109,101,41,32,45,62,32,102,105,108,101,110,97,109,101,32, - 115,116,114,105,110,103,46,10,10,32,32,32,32,32,32,32, - 32,82,101,116,117,114,110,32,116,104,101,32,102,105,108,101, - 110,97,109,101,32,102,111,114,32,116,104,101,32,115,112,101, - 99,105,102,105,101,100,32,109,111,100,117,108,101,46,10,32, - 32,32,32,32,32,32,32,114,43,0,0,0,114,45,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,12,103,101,116,95,102,105,108,101,110,97,109,101,184,0, - 0,0,115,4,0,0,0,0,7,16,1,122,24,122,105,112, - 105,109,112,111,114,116,101,114,46,103,101,116,95,102,105,108, - 101,110,97,109,101,99,2,0,0,0,0,0,0,0,0,0, - 0,0,6,0,0,0,8,0,0,0,67,0,0,0,115,126, - 0,0,0,116,0,124,0,124,1,131,2,125,2,124,2,100, - 1,117,0,114,36,116,1,100,2,124,1,155,2,157,2,124, - 1,100,3,141,2,130,1,116,2,124,0,124,1,131,2,125, - 3,124,2,114,64,116,3,160,4,124,3,100,4,161,2,125, - 4,110,10,124,3,155,0,100,5,157,2,125,4,122,14,124, - 0,106,5,124,4,25,0,125,5,87,0,110,20,4,0,116, - 6,121,108,1,0,1,0,1,0,89,0,100,1,83,0,48, - 0,116,7,124,0,106,8,124,5,131,2,160,9,161,0,83, - 0,41,6,122,253,103,101,116,95,115,111,117,114,99,101,40, - 102,117,108,108,110,97,109,101,41,32,45,62,32,115,111,117, - 114,99,101,32,115,116,114,105,110,103,46,10,10,32,32,32, - 32,32,32,32,32,82,101,116,117,114,110,32,116,104,101,32, - 115,111,117,114,99,101,32,99,111,100,101,32,102,111,114,32, - 116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,117,108,101,46,32,82,97,105,115,101,32,90,105,112,73, - 109,112,111,114,116,69,114,114,111,114,10,32,32,32,32,32, - 32,32,32,105,102,32,116,104,101,32,109,111,100,117,108,101, - 32,99,111,117,108,100,110,39,116,32,98,101,32,102,111,117, - 110,100,44,32,114,101,116,117,114,110,32,78,111,110,101,32, - 105,102,32,116,104,101,32,97,114,99,104,105,118,101,32,100, - 111,101,115,10,32,32,32,32,32,32,32,32,99,111,110,116, - 97,105,110,32,116,104,101,32,109,111,100,117,108,101,44,32, - 98,117,116,32,104,97,115,32,110,111,32,115,111,117,114,99, - 101,32,102,111,114,32,105,116,46,10,32,32,32,32,32,32, - 32,32,78,250,18,99,97,110,39,116,32,102,105,110,100,32, - 109,111,100,117,108,101,32,169,1,218,4,110,97,109,101,250, - 11,95,95,105,110,105,116,95,95,46,112,121,250,3,46,112, - 121,41,10,114,35,0,0,0,114,3,0,0,0,114,36,0, - 0,0,114,21,0,0,0,114,30,0,0,0,114,28,0,0, - 0,114,26,0,0,0,114,52,0,0,0,114,29,0,0,0, - 218,6,100,101,99,111,100,101,41,6,114,32,0,0,0,114, - 38,0,0,0,114,39,0,0,0,114,13,0,0,0,218,8, - 102,117,108,108,112,97,116,104,114,54,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,10,103,101, - 116,95,115,111,117,114,99,101,195,0,0,0,115,24,0,0, - 0,0,7,10,1,8,1,18,2,10,1,4,1,14,2,10, - 2,2,1,14,1,12,2,8,1,122,22,122,105,112,105,109, - 112,111,114,116,101,114,46,103,101,116,95,115,111,117,114,99, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,4,0,0,0,67,0,0,0,115,40,0,0,0,116, + 105,109,112,111,114,116,101,100,46,10,32,32,32,32,32,32, + 32,32,169,1,218,16,95,103,101,116,95,109,111,100,117,108, + 101,95,99,111,100,101,169,5,114,32,0,0,0,114,41,0, + 0,0,218,4,99,111,100,101,218,9,105,115,112,97,99,107, + 97,103,101,114,43,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,8,103,101,116,95,99,111,100, + 101,190,0,0,0,115,4,0,0,0,16,6,4,1,122,20, + 122,105,112,105,109,112,111,114,116,101,114,46,103,101,116,95, + 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,8,0,0,0,67,0,0,0,115,112,0, + 0,0,116,0,114,8,124,1,160,1,116,0,116,2,161,2, + 125,1,124,1,125,2,124,1,160,3,124,0,106,4,116,2, + 23,0,161,1,114,29,124,1,116,5,124,0,106,4,116,2, + 23,0,131,1,100,1,133,2,25,0,125,2,122,7,124,0, + 106,6,124,2,25,0,125,3,87,0,110,13,4,0,116,7, + 121,49,1,0,1,0,1,0,116,8,100,2,100,3,124,2, + 131,3,130,1,119,0,116,9,124,0,106,4,124,3,131,2, + 83,0,41,4,122,154,103,101,116,95,100,97,116,97,40,112, + 97,116,104,110,97,109,101,41,32,45,62,32,115,116,114,105, + 110,103,32,119,105,116,104,32,102,105,108,101,32,100,97,116, + 97,46,10,10,32,32,32,32,32,32,32,32,82,101,116,117, + 114,110,32,116,104,101,32,100,97,116,97,32,97,115,115,111, + 99,105,97,116,101,100,32,119,105,116,104,32,39,112,97,116, + 104,110,97,109,101,39,46,32,82,97,105,115,101,32,79,83, + 69,114,114,111,114,32,105,102,10,32,32,32,32,32,32,32, + 32,116,104,101,32,102,105,108,101,32,119,97,115,110,39,116, + 32,102,111,117,110,100,46,10,32,32,32,32,32,32,32,32, + 78,114,0,0,0,0,218,0,41,10,114,18,0,0,0,114, + 19,0,0,0,114,20,0,0,0,218,10,115,116,97,114,116, + 115,119,105,116,104,114,29,0,0,0,218,3,108,101,110,114, + 28,0,0,0,114,26,0,0,0,114,22,0,0,0,218,9, + 95,103,101,116,95,100,97,116,97,41,4,114,32,0,0,0, + 218,8,112,97,116,104,110,97,109,101,90,3,107,101,121,218, + 9,116,111,99,95,101,110,116,114,121,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,8,103,101,116,95,100, + 97,116,97,200,0,0,0,115,22,0,0,0,4,6,12,1, + 4,2,16,1,22,1,2,2,14,1,12,1,12,1,2,255, + 12,2,122,20,122,105,112,105,109,112,111,114,116,101,114,46, + 103,101,116,95,100,97,116,97,99,2,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,3,0,0,0,67,0,0, + 0,115,20,0,0,0,116,0,124,0,124,1,131,2,92,3, + 125,2,125,3,125,4,124,4,83,0,41,1,122,165,103,101, + 116,95,102,105,108,101,110,97,109,101,40,102,117,108,108,110, + 97,109,101,41,32,45,62,32,102,105,108,101,110,97,109,101, + 32,115,116,114,105,110,103,46,10,10,32,32,32,32,32,32, + 32,32,82,101,116,117,114,110,32,116,104,101,32,102,105,108, + 101,110,97,109,101,32,102,111,114,32,116,104,101,32,115,112, + 101,99,105,102,105,101,100,32,109,111,100,117,108,101,32,111, + 114,32,114,97,105,115,101,32,90,105,112,73,109,112,111,114, + 116,69,114,114,111,114,10,32,32,32,32,32,32,32,32,105, + 102,32,105,116,32,99,111,117,108,100,110,39,116,32,98,101, + 32,105,109,112,111,114,116,101,100,46,10,32,32,32,32,32, + 32,32,32,114,50,0,0,0,114,52,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,218,12,103,101, + 116,95,102,105,108,101,110,97,109,101,221,0,0,0,115,4, + 0,0,0,16,8,4,1,122,24,122,105,112,105,109,112,111, + 114,116,101,114,46,103,101,116,95,102,105,108,101,110,97,109, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,6,0, + 0,0,8,0,0,0,67,0,0,0,115,126,0,0,0,116, 0,124,0,124,1,131,2,125,2,124,2,100,1,117,0,114, - 36,116,1,100,2,124,1,155,2,157,2,124,1,100,3,141, - 2,130,1,124,2,83,0,41,4,122,171,105,115,95,112,97, - 99,107,97,103,101,40,102,117,108,108,110,97,109,101,41,32, - 45,62,32,98,111,111,108,46,10,10,32,32,32,32,32,32, - 32,32,82,101,116,117,114,110,32,84,114,117,101,32,105,102, - 32,116,104,101,32,109,111,100,117,108,101,32,115,112,101,99, - 105,102,105,101,100,32,98,121,32,102,117,108,108,110,97,109, - 101,32,105,115,32,97,32,112,97,99,107,97,103,101,46,10, - 32,32,32,32,32,32,32,32,82,97,105,115,101,32,90,105, - 112,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32, - 116,104,101,32,109,111,100,117,108,101,32,99,111,117,108,100, - 110,39,116,32,98,101,32,102,111,117,110,100,46,10,32,32, - 32,32,32,32,32,32,78,114,57,0,0,0,114,58,0,0, - 0,41,2,114,35,0,0,0,114,3,0,0,0,41,3,114, - 32,0,0,0,114,38,0,0,0,114,39,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,218,10,105, - 115,95,112,97,99,107,97,103,101,221,0,0,0,115,8,0, - 0,0,0,6,10,1,8,1,18,1,122,22,122,105,112,105, - 109,112,111,114,116,101,114,46,105,115,95,112,97,99,107,97, - 103,101,99,2,0,0,0,0,0,0,0,0,0,0,0,8, - 0,0,0,8,0,0,0,67,0,0,0,115,246,0,0,0, - 116,0,124,0,124,1,131,2,92,3,125,2,125,3,125,4, - 116,1,106,2,160,3,124,1,161,1,125,5,124,5,100,1, - 117,0,115,46,116,4,124,5,116,5,131,2,115,64,116,5, - 124,1,131,1,125,5,124,5,116,1,106,2,124,1,60,0, - 124,0,124,5,95,6,122,84,124,3,114,108,116,7,124,0, - 124,1,131,2,125,6,116,8,160,9,124,0,106,10,124,6, - 161,2,125,7,124,7,103,1,124,5,95,11,116,12,124,5, - 100,2,131,2,115,124,116,13,124,5,95,13,116,8,160,14, - 124,5,106,15,124,1,124,4,161,3,1,0,116,16,124,2, - 124,5,106,15,131,2,1,0,87,0,110,22,1,0,1,0, - 1,0,116,1,106,2,124,1,61,0,130,0,89,0,110,2, - 48,0,122,14,116,1,106,2,124,1,25,0,125,5,87,0, - 110,34,4,0,116,17,121,226,1,0,1,0,1,0,116,18, - 100,3,124,1,155,2,100,4,157,3,131,1,130,1,89,0, - 110,2,48,0,116,19,160,20,100,5,124,1,124,4,161,3, - 1,0,124,5,83,0,41,6,122,245,108,111,97,100,95,109, - 111,100,117,108,101,40,102,117,108,108,110,97,109,101,41,32, - 45,62,32,109,111,100,117,108,101,46,10,10,32,32,32,32, - 32,32,32,32,76,111,97,100,32,116,104,101,32,109,111,100, - 117,108,101,32,115,112,101,99,105,102,105,101,100,32,98,121, - 32,39,102,117,108,108,110,97,109,101,39,46,32,39,102,117, - 108,108,110,97,109,101,39,32,109,117,115,116,32,98,101,32, - 116,104,101,10,32,32,32,32,32,32,32,32,102,117,108,108, - 121,32,113,117,97,108,105,102,105,101,100,32,40,100,111,116, - 116,101,100,41,32,109,111,100,117,108,101,32,110,97,109,101, - 46,32,73,116,32,114,101,116,117,114,110,115,32,116,104,101, - 32,105,109,112,111,114,116,101,100,10,32,32,32,32,32,32, - 32,32,109,111,100,117,108,101,44,32,111,114,32,114,97,105, - 115,101,115,32,90,105,112,73,109,112,111,114,116,69,114,114, - 111,114,32,105,102,32,105,116,32,119,97,115,110,39,116,32, - 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,78, - 218,12,95,95,98,117,105,108,116,105,110,115,95,95,122,14, - 76,111,97,100,101,100,32,109,111,100,117,108,101,32,122,25, - 32,110,111,116,32,102,111,117,110,100,32,105,110,32,115,121, - 115,46,109,111,100,117,108,101,115,122,30,105,109,112,111,114, - 116,32,123,125,32,35,32,108,111,97,100,101,100,32,102,114, - 111,109,32,90,105,112,32,123,125,41,21,114,44,0,0,0, - 218,3,115,121,115,218,7,109,111,100,117,108,101,115,218,3, - 103,101,116,114,15,0,0,0,218,12,95,109,111,100,117,108, - 101,95,116,121,112,101,218,10,95,95,108,111,97,100,101,114, - 95,95,114,36,0,0,0,114,21,0,0,0,114,30,0,0, - 0,114,29,0,0,0,90,8,95,95,112,97,116,104,95,95, - 218,7,104,97,115,97,116,116,114,114,66,0,0,0,90,14, - 95,102,105,120,95,117,112,95,109,111,100,117,108,101,218,8, - 95,95,100,105,99,116,95,95,218,4,101,120,101,99,114,26, - 0,0,0,218,11,73,109,112,111,114,116,69,114,114,111,114, - 218,10,95,98,111,111,116,115,116,114,97,112,218,16,95,118, - 101,114,98,111,115,101,95,109,101,115,115,97,103,101,41,8, - 114,32,0,0,0,114,38,0,0,0,114,46,0,0,0,114, - 47,0,0,0,114,40,0,0,0,90,3,109,111,100,114,13, - 0,0,0,114,63,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,11,108,111,97,100,95,109,111, - 100,117,108,101,234,0,0,0,115,48,0,0,0,0,7,16, - 1,12,1,18,1,8,1,10,1,6,2,2,1,4,3,10, - 1,14,1,8,2,10,1,6,1,16,1,16,1,6,1,8, - 1,8,2,2,1,14,1,12,1,22,1,14,1,122,23,122, - 105,112,105,109,112,111,114,116,101,114,46,108,111,97,100,95, - 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,8,0,0,0,67,0,0,0,115, - 86,0,0,0,122,20,124,0,160,0,124,1,161,1,115,18, - 87,0,100,1,83,0,87,0,110,20,4,0,116,1,121,40, - 1,0,1,0,1,0,89,0,100,1,83,0,48,0,116,2, - 106,3,115,76,100,2,100,3,108,4,109,5,125,2,1,0, - 124,2,160,6,116,2,161,1,1,0,100,4,116,2,95,3, - 116,2,124,0,124,1,131,2,83,0,41,5,122,204,82,101, - 116,117,114,110,32,116,104,101,32,82,101,115,111,117,114,99, - 101,82,101,97,100,101,114,32,102,111,114,32,97,32,112,97, - 99,107,97,103,101,32,105,110,32,97,32,122,105,112,32,102, - 105,108,101,46,10,10,32,32,32,32,32,32,32,32,73,102, - 32,39,102,117,108,108,110,97,109,101,39,32,105,115,32,97, - 32,112,97,99,107,97,103,101,32,119,105,116,104,105,110,32, - 116,104,101,32,122,105,112,32,102,105,108,101,44,32,114,101, - 116,117,114,110,32,116,104,101,10,32,32,32,32,32,32,32, - 32,39,82,101,115,111,117,114,99,101,82,101,97,100,101,114, - 39,32,111,98,106,101,99,116,32,102,111,114,32,116,104,101, - 32,112,97,99,107,97,103,101,46,32,32,79,116,104,101,114, - 119,105,115,101,32,114,101,116,117,114,110,32,78,111,110,101, - 46,10,32,32,32,32,32,32,32,32,78,114,0,0,0,0, - 41,1,218,14,82,101,115,111,117,114,99,101,82,101,97,100, - 101,114,84,41,7,114,65,0,0,0,114,3,0,0,0,218, - 24,95,90,105,112,73,109,112,111,114,116,82,101,115,111,117, - 114,99,101,82,101,97,100,101,114,218,11,95,114,101,103,105, - 115,116,101,114,101,100,90,13,105,109,112,111,114,116,108,105, - 98,46,97,98,99,114,79,0,0,0,90,8,114,101,103,105, - 115,116,101,114,41,3,114,32,0,0,0,114,38,0,0,0, - 114,79,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,218,19,103,101,116,95,114,101,115,111,117,114, - 99,101,95,114,101,97,100,101,114,16,1,0,0,115,20,0, - 0,0,0,6,2,1,10,1,10,1,12,1,8,1,6,1, - 12,1,10,1,6,1,122,31,122,105,112,105,109,112,111,114, - 116,101,114,46,103,101,116,95,114,101,115,111,117,114,99,101, - 95,114,101,97,100,101,114,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,5,0,0,0,67,0,0,0, - 115,24,0,0,0,100,1,124,0,106,0,155,0,116,1,155, - 0,124,0,106,2,155,0,100,2,157,5,83,0,41,3,78, - 122,21,60,122,105,112,105,109,112,111,114,116,101,114,32,111, - 98,106,101,99,116,32,34,122,2,34,62,41,3,114,29,0, - 0,0,114,20,0,0,0,114,31,0,0,0,41,1,114,32, + 18,116,1,100,2,124,1,155,2,157,2,124,1,100,3,141, + 2,130,1,116,2,124,0,124,1,131,2,125,3,124,2,114, + 32,116,3,160,4,124,3,100,4,161,2,125,4,110,5,124, + 3,155,0,100,5,157,2,125,4,122,7,124,0,106,5,124, + 4,25,0,125,5,87,0,110,10,4,0,116,6,121,54,1, + 0,1,0,1,0,89,0,100,1,83,0,119,0,116,7,124, + 0,106,8,124,5,131,2,160,9,161,0,83,0,41,6,122, + 253,103,101,116,95,115,111,117,114,99,101,40,102,117,108,108, + 110,97,109,101,41,32,45,62,32,115,111,117,114,99,101,32, + 115,116,114,105,110,103,46,10,10,32,32,32,32,32,32,32, + 32,82,101,116,117,114,110,32,116,104,101,32,115,111,117,114, + 99,101,32,99,111,100,101,32,102,111,114,32,116,104,101,32, + 115,112,101,99,105,102,105,101,100,32,109,111,100,117,108,101, + 46,32,82,97,105,115,101,32,90,105,112,73,109,112,111,114, + 116,69,114,114,111,114,10,32,32,32,32,32,32,32,32,105, + 102,32,116,104,101,32,109,111,100,117,108,101,32,99,111,117, + 108,100,110,39,116,32,98,101,32,102,111,117,110,100,44,32, + 114,101,116,117,114,110,32,78,111,110,101,32,105,102,32,116, + 104,101,32,97,114,99,104,105,118,101,32,100,111,101,115,10, + 32,32,32,32,32,32,32,32,99,111,110,116,97,105,110,32, + 116,104,101,32,109,111,100,117,108,101,44,32,98,117,116,32, + 104,97,115,32,110,111,32,115,111,117,114,99,101,32,102,111, + 114,32,105,116,46,10,32,32,32,32,32,32,32,32,78,250, + 18,99,97,110,39,116,32,102,105,110,100,32,109,111,100,117, + 108,101,32,169,1,114,47,0,0,0,250,11,95,95,105,110, + 105,116,95,95,46,112,121,250,3,46,112,121,41,10,114,38, + 0,0,0,114,3,0,0,0,114,39,0,0,0,114,21,0, + 0,0,114,30,0,0,0,114,28,0,0,0,114,26,0,0, + 0,114,59,0,0,0,114,29,0,0,0,218,6,100,101,99, + 111,100,101,41,6,114,32,0,0,0,114,41,0,0,0,114, + 42,0,0,0,114,13,0,0,0,218,8,102,117,108,108,112, + 97,116,104,114,61,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,10,103,101,116,95,115,111,117, + 114,99,101,233,0,0,0,115,26,0,0,0,10,7,8,1, + 18,1,10,2,4,1,14,1,10,2,2,2,14,1,12,1, + 6,2,2,254,16,3,122,22,122,105,112,105,109,112,111,114, + 116,101,114,46,103,101,116,95,115,111,117,114,99,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, + 0,0,0,67,0,0,0,115,40,0,0,0,116,0,124,0, + 124,1,131,2,125,2,124,2,100,1,117,0,114,18,116,1, + 100,2,124,1,155,2,157,2,124,1,100,3,141,2,130,1, + 124,2,83,0,41,4,122,171,105,115,95,112,97,99,107,97, + 103,101,40,102,117,108,108,110,97,109,101,41,32,45,62,32, + 98,111,111,108,46,10,10,32,32,32,32,32,32,32,32,82, + 101,116,117,114,110,32,84,114,117,101,32,105,102,32,116,104, + 101,32,109,111,100,117,108,101,32,115,112,101,99,105,102,105, + 101,100,32,98,121,32,102,117,108,108,110,97,109,101,32,105, + 115,32,97,32,112,97,99,107,97,103,101,46,10,32,32,32, + 32,32,32,32,32,82,97,105,115,101,32,90,105,112,73,109, + 112,111,114,116,69,114,114,111,114,32,105,102,32,116,104,101, + 32,109,111,100,117,108,101,32,99,111,117,108,100,110,39,116, + 32,98,101,32,102,111,117,110,100,46,10,32,32,32,32,32, + 32,32,32,78,114,64,0,0,0,114,65,0,0,0,41,2, + 114,38,0,0,0,114,3,0,0,0,41,3,114,32,0,0, + 0,114,41,0,0,0,114,42,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,114,46,0,0,0,3, + 1,0,0,115,8,0,0,0,10,6,8,1,18,1,4,1, + 122,22,122,105,112,105,109,112,111,114,116,101,114,46,105,115, + 95,112,97,99,107,97,103,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,9,0,0,0,8,0,0,0,67,0,0, + 0,115,252,0,0,0,100,1,125,2,116,0,160,1,124,2, + 116,2,161,2,1,0,116,3,124,0,124,1,131,2,92,3, + 125,3,125,4,125,5,116,4,106,5,160,6,124,1,161,1, + 125,6,124,6,100,2,117,0,115,31,116,7,124,6,116,8, + 131,2,115,40,116,8,124,1,131,1,125,6,124,6,116,4, + 106,5,124,1,60,0,124,0,124,6,95,9,122,42,124,4, + 114,62,116,10,124,0,124,1,131,2,125,7,116,11,160,12, + 124,0,106,13,124,7,161,2,125,8,124,8,103,1,124,6, + 95,14,116,15,124,6,100,3,131,2,115,70,116,16,124,6, + 95,16,116,11,160,17,124,6,106,18,124,1,124,5,161,3, + 1,0,116,19,124,3,124,6,106,18,131,2,1,0,87,0, + 110,8,1,0,1,0,1,0,116,4,106,5,124,1,61,0, + 130,0,122,7,116,4,106,5,124,1,25,0,125,6,87,0, + 110,15,4,0,116,20,121,116,1,0,1,0,1,0,116,21, + 100,4,124,1,155,2,100,5,157,3,131,1,130,1,119,0, + 116,22,160,23,100,6,124,1,124,5,161,3,1,0,124,6, + 83,0,41,7,97,64,1,0,0,108,111,97,100,95,109,111, + 100,117,108,101,40,102,117,108,108,110,97,109,101,41,32,45, + 62,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, + 32,32,32,76,111,97,100,32,116,104,101,32,109,111,100,117, + 108,101,32,115,112,101,99,105,102,105,101,100,32,98,121,32, + 39,102,117,108,108,110,97,109,101,39,46,32,39,102,117,108, + 108,110,97,109,101,39,32,109,117,115,116,32,98,101,32,116, + 104,101,10,32,32,32,32,32,32,32,32,102,117,108,108,121, + 32,113,117,97,108,105,102,105,101,100,32,40,100,111,116,116, + 101,100,41,32,109,111,100,117,108,101,32,110,97,109,101,46, + 32,73,116,32,114,101,116,117,114,110,115,32,116,104,101,32, + 105,109,112,111,114,116,101,100,10,32,32,32,32,32,32,32, + 32,109,111,100,117,108,101,44,32,111,114,32,114,97,105,115, + 101,115,32,90,105,112,73,109,112,111,114,116,69,114,114,111, + 114,32,105,102,32,105,116,32,99,111,117,108,100,32,110,111, + 116,32,98,101,32,105,109,112,111,114,116,101,100,46,10,10, + 32,32,32,32,32,32,32,32,68,101,112,114,101,99,97,116, + 101,100,32,115,105,110,99,101,32,80,121,116,104,111,110,32, + 51,46,49,48,46,32,85,115,101,32,101,120,101,99,95,109, + 111,100,117,108,101,40,41,32,105,110,115,116,101,97,100,46, + 10,32,32,32,32,32,32,32,32,122,114,122,105,112,105,109, + 112,111,114,116,46,122,105,112,105,109,112,111,114,116,101,114, + 46,108,111,97,100,95,109,111,100,117,108,101,40,41,32,105, + 115,32,100,101,112,114,101,99,97,116,101,100,32,97,110,100, + 32,115,108,97,116,101,100,32,102,111,114,32,114,101,109,111, + 118,97,108,32,105,110,32,80,121,116,104,111,110,32,51,46, + 49,50,59,32,117,115,101,32,101,120,101,99,95,109,111,100, + 117,108,101,40,41,32,105,110,115,116,101,97,100,78,218,12, + 95,95,98,117,105,108,116,105,110,115,95,95,122,14,76,111, + 97,100,101,100,32,109,111,100,117,108,101,32,122,25,32,110, + 111,116,32,102,111,117,110,100,32,105,110,32,115,121,115,46, + 109,111,100,117,108,101,115,122,30,105,109,112,111,114,116,32, + 123,125,32,35,32,108,111,97,100,101,100,32,102,114,111,109, + 32,90,105,112,32,123,125,41,24,114,35,0,0,0,114,36, + 0,0,0,114,37,0,0,0,114,51,0,0,0,218,3,115, + 121,115,218,7,109,111,100,117,108,101,115,218,3,103,101,116, + 114,15,0,0,0,218,12,95,109,111,100,117,108,101,95,116, + 121,112,101,218,10,95,95,108,111,97,100,101,114,95,95,114, + 39,0,0,0,114,21,0,0,0,114,30,0,0,0,114,29, + 0,0,0,90,8,95,95,112,97,116,104,95,95,218,7,104, + 97,115,97,116,116,114,114,71,0,0,0,90,14,95,102,105, + 120,95,117,112,95,109,111,100,117,108,101,218,8,95,95,100, + 105,99,116,95,95,218,4,101,120,101,99,114,26,0,0,0, + 218,11,73,109,112,111,114,116,69,114,114,111,114,114,48,0, + 0,0,218,16,95,118,101,114,98,111,115,101,95,109,101,115, + 115,97,103,101,41,9,114,32,0,0,0,114,41,0,0,0, + 218,3,109,115,103,114,53,0,0,0,114,54,0,0,0,114, + 43,0,0,0,90,3,109,111,100,114,13,0,0,0,114,69, 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,8,95,95,114,101,112,114,95,95,34,1,0,0, - 115,2,0,0,0,0,1,122,20,122,105,112,105,109,112,111, - 114,116,101,114,46,95,95,114,101,112,114,95,95,41,1,78, - 41,1,78,41,15,114,6,0,0,0,114,7,0,0,0,114, - 8,0,0,0,218,7,95,95,100,111,99,95,95,114,34,0, - 0,0,114,41,0,0,0,114,42,0,0,0,114,48,0,0, - 0,114,55,0,0,0,114,56,0,0,0,114,64,0,0,0, - 114,65,0,0,0,114,78,0,0,0,114,82,0,0,0,114, - 83,0,0,0,114,9,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,4,0,0,0,45,0,0, - 0,115,24,0,0,0,8,1,4,17,8,46,10,32,10,12, - 8,10,8,21,8,11,8,26,8,13,8,38,8,18,122,12, - 95,95,105,110,105,116,95,95,46,112,121,99,84,114,60,0, - 0,0,70,41,3,122,4,46,112,121,99,84,70,41,3,114, - 61,0,0,0,70,70,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, - 20,0,0,0,124,0,106,0,124,1,160,1,100,1,161,1, - 100,2,25,0,23,0,83,0,41,3,78,218,1,46,233,2, - 0,0,0,41,2,114,31,0,0,0,218,10,114,112,97,114, - 116,105,116,105,111,110,41,2,114,32,0,0,0,114,38,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,36,0,0,0,52,1,0,0,115,2,0,0,0,0, - 1,114,36,0,0,0,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,2,0,0,0,67,0,0,0,115, - 18,0,0,0,124,1,116,0,23,0,125,2,124,2,124,0, - 106,1,118,0,83,0,169,1,78,41,2,114,20,0,0,0, - 114,28,0,0,0,41,3,114,32,0,0,0,114,13,0,0, - 0,90,7,100,105,114,112,97,116,104,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,114,37,0,0,0,56,1, - 0,0,115,4,0,0,0,0,4,8,2,114,37,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,7,0,0, - 0,4,0,0,0,67,0,0,0,115,56,0,0,0,116,0, - 124,0,124,1,131,2,125,2,116,1,68,0,93,36,92,3, - 125,3,125,4,125,5,124,2,124,3,23,0,125,6,124,6, - 124,0,106,2,118,0,114,14,124,5,2,0,1,0,83,0, - 113,14,100,0,83,0,114,88,0,0,0,41,3,114,36,0, - 0,0,218,16,95,122,105,112,95,115,101,97,114,99,104,111, - 114,100,101,114,114,28,0,0,0,41,7,114,32,0,0,0, - 114,38,0,0,0,114,13,0,0,0,218,6,115,117,102,102, - 105,120,218,10,105,115,98,121,116,101,99,111,100,101,114,47, - 0,0,0,114,63,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,114,35,0,0,0,65,1,0,0, - 115,12,0,0,0,0,1,10,1,14,1,8,1,10,1,10, - 1,114,35,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,26,0,0,0,9,0,0,0,67,0,0,0,115, - 2,5,0,0,122,14,116,0,160,1,124,0,161,1,125,1, - 87,0,110,36,4,0,116,2,121,50,1,0,1,0,1,0, - 116,3,100,1,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,89,0,110,2,48,0,124,1,144,4,143,164,1,0, - 122,36,124,1,160,4,116,5,11,0,100,3,161,2,1,0, - 124,1,160,6,161,0,125,2,124,1,160,7,116,5,161,1, - 125,3,87,0,110,36,4,0,116,2,121,132,1,0,1,0, - 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, - 141,2,130,1,89,0,110,2,48,0,116,8,124,3,131,1, - 116,5,107,3,114,164,116,3,100,4,124,0,155,2,157,2, + 0,0,218,11,108,111,97,100,95,109,111,100,117,108,101,16, + 1,0,0,115,54,0,0,0,4,9,12,2,16,1,12,1, + 18,1,8,1,10,1,6,1,2,2,4,1,10,3,14,1, + 8,1,10,2,6,1,16,1,16,1,6,1,8,1,2,1, + 2,2,14,1,12,1,16,1,2,255,14,2,4,1,122,23, + 122,105,112,105,109,112,111,114,116,101,114,46,108,111,97,100, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,8,0,0,0,67,0,0,0, + 115,64,0,0,0,122,10,124,0,160,0,124,1,161,1,115, + 9,87,0,100,1,83,0,87,0,110,10,4,0,116,1,121, + 20,1,0,1,0,1,0,89,0,100,1,83,0,119,0,100, + 2,100,3,108,2,109,3,125,2,1,0,124,2,124,0,124, + 1,131,2,83,0,41,4,122,204,82,101,116,117,114,110,32, + 116,104,101,32,82,101,115,111,117,114,99,101,82,101,97,100, + 101,114,32,102,111,114,32,97,32,112,97,99,107,97,103,101, + 32,105,110,32,97,32,122,105,112,32,102,105,108,101,46,10, + 10,32,32,32,32,32,32,32,32,73,102,32,39,102,117,108, + 108,110,97,109,101,39,32,105,115,32,97,32,112,97,99,107, + 97,103,101,32,119,105,116,104,105,110,32,116,104,101,32,122, + 105,112,32,102,105,108,101,44,32,114,101,116,117,114,110,32, + 116,104,101,10,32,32,32,32,32,32,32,32,39,82,101,115, + 111,117,114,99,101,82,101,97,100,101,114,39,32,111,98,106, + 101,99,116,32,102,111,114,32,116,104,101,32,112,97,99,107, + 97,103,101,46,32,32,79,116,104,101,114,119,105,115,101,32, + 114,101,116,117,114,110,32,78,111,110,101,46,10,32,32,32, + 32,32,32,32,32,78,114,0,0,0,0,41,1,218,9,90, + 105,112,82,101,97,100,101,114,41,4,114,46,0,0,0,114, + 3,0,0,0,90,17,105,109,112,111,114,116,108,105,98,46, + 114,101,97,100,101,114,115,114,84,0,0,0,41,3,114,32, + 0,0,0,114,41,0,0,0,114,84,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,218,19,103,101, + 116,95,114,101,115,111,117,114,99,101,95,114,101,97,100,101, + 114,59,1,0,0,115,18,0,0,0,2,6,10,1,6,1, + 4,255,12,2,6,1,2,255,12,2,10,1,122,31,122,105, + 112,105,109,112,111,114,116,101,114,46,103,101,116,95,114,101, + 115,111,117,114,99,101,95,114,101,97,100,101,114,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0, + 0,0,67,0,0,0,115,72,0,0,0,122,15,116,0,124, + 0,106,1,131,1,124,0,95,2,124,0,106,2,116,3,124, + 0,106,1,60,0,87,0,100,1,83,0,4,0,116,4,121, + 35,1,0,1,0,1,0,116,3,160,5,124,0,106,1,100, + 1,161,2,1,0,105,0,124,0,95,2,89,0,100,1,83, + 0,119,0,41,2,122,41,82,101,108,111,97,100,32,116,104, + 101,32,102,105,108,101,32,100,97,116,97,32,111,102,32,116, + 104,101,32,97,114,99,104,105,118,101,32,112,97,116,104,46, + 78,41,6,114,27,0,0,0,114,29,0,0,0,114,28,0, + 0,0,114,25,0,0,0,114,3,0,0,0,218,3,112,111, + 112,169,1,114,32,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,17,105,110,118,97,108,105,100, + 97,116,101,95,99,97,99,104,101,115,74,1,0,0,115,14, + 0,0,0,2,2,12,1,18,1,12,1,14,1,12,1,2, + 254,122,29,122,105,112,105,109,112,111,114,116,101,114,46,105, + 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,5,0,0,0,67,0,0,0,115,24,0,0,0,100,1, + 124,0,106,0,155,0,116,1,155,0,124,0,106,2,155,0, + 100,2,157,5,83,0,41,3,78,122,21,60,122,105,112,105, + 109,112,111,114,116,101,114,32,111,98,106,101,99,116,32,34, + 122,2,34,62,41,3,114,29,0,0,0,114,20,0,0,0, + 114,31,0,0,0,114,87,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,8,95,95,114,101,112, + 114,95,95,84,1,0,0,115,2,0,0,0,24,1,122,20, + 122,105,112,105,109,112,111,114,116,101,114,46,95,95,114,101, + 112,114,95,95,169,1,78,41,17,114,6,0,0,0,114,7, + 0,0,0,114,8,0,0,0,218,7,95,95,100,111,99,95, + 95,114,34,0,0,0,114,44,0,0,0,114,45,0,0,0, + 114,49,0,0,0,114,55,0,0,0,114,62,0,0,0,114, + 63,0,0,0,114,70,0,0,0,114,46,0,0,0,114,83, + 0,0,0,114,85,0,0,0,114,88,0,0,0,114,89,0, + 0,0,114,9,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,114,4,0,0,0,46,0,0,0,115, + 30,0,0,0,8,0,4,1,8,17,10,46,10,37,10,16, + 8,27,8,10,8,21,8,12,8,26,8,13,8,43,8,15, + 12,10,122,12,95,95,105,110,105,116,95,95,46,112,121,99, + 84,114,66,0,0,0,70,41,3,122,4,46,112,121,99,84, + 70,41,3,114,67,0,0,0,70,70,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, + 0,0,0,115,20,0,0,0,124,0,106,0,124,1,160,1, + 100,1,161,1,100,2,25,0,23,0,83,0,41,3,78,218, + 1,46,233,2,0,0,0,41,2,114,31,0,0,0,218,10, + 114,112,97,114,116,105,116,105,111,110,41,2,114,32,0,0, + 0,114,41,0,0,0,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,114,39,0,0,0,102,1,0,0,115,2, + 0,0,0,20,1,114,39,0,0,0,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,67, + 0,0,0,115,18,0,0,0,124,1,116,0,23,0,125,2, + 124,2,124,0,106,1,118,0,83,0,114,90,0,0,0,41, + 2,114,20,0,0,0,114,28,0,0,0,41,3,114,32,0, + 0,0,114,13,0,0,0,90,7,100,105,114,112,97,116,104, + 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,114, + 40,0,0,0,106,1,0,0,115,4,0,0,0,8,4,10, + 2,114,40,0,0,0,99,2,0,0,0,0,0,0,0,0, + 0,0,0,7,0,0,0,4,0,0,0,67,0,0,0,115, + 56,0,0,0,116,0,124,0,124,1,131,2,125,2,116,1, + 68,0,93,18,92,3,125,3,125,4,125,5,124,2,124,3, + 23,0,125,6,124,6,124,0,106,2,118,0,114,25,124,5, + 2,0,1,0,83,0,113,7,100,0,83,0,114,90,0,0, + 0,41,3,114,39,0,0,0,218,16,95,122,105,112,95,115, + 101,97,114,99,104,111,114,100,101,114,114,28,0,0,0,41, + 7,114,32,0,0,0,114,41,0,0,0,114,13,0,0,0, + 218,6,115,117,102,102,105,120,218,10,105,115,98,121,116,101, + 99,111,100,101,114,54,0,0,0,114,69,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,114,38,0, + 0,0,115,1,0,0,115,14,0,0,0,10,1,14,1,8, + 1,10,1,8,1,2,255,4,2,114,38,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,9, + 0,0,0,67,0,0,0,115,220,4,0,0,122,7,116,0, + 160,1,124,0,161,1,125,1,87,0,110,16,4,0,116,2, + 121,23,1,0,1,0,1,0,116,3,100,1,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,119,0,124,1,144,2, + 143,65,1,0,122,18,124,1,160,4,116,5,11,0,100,3, + 161,2,1,0,124,1,160,6,161,0,125,2,124,1,160,7, + 116,5,161,1,125,3,87,0,110,16,4,0,116,2,121,62, + 1,0,1,0,1,0,116,3,100,4,124,0,155,2,157,2, + 124,0,100,2,141,2,130,1,119,0,116,8,124,3,131,1, + 116,5,107,3,114,78,116,3,100,4,124,0,155,2,157,2, 124,0,100,2,141,2,130,1,124,3,100,0,100,5,133,2, - 25,0,116,9,107,3,144,1,114,170,122,24,124,1,160,4, - 100,6,100,3,161,2,1,0,124,1,160,6,161,0,125,4, - 87,0,110,36,4,0,116,2,121,242,1,0,1,0,1,0, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,89,0,110,2,48,0,116,10,124,4,116,11,24,0, - 116,5,24,0,100,6,131,2,125,5,122,22,124,1,160,4, - 124,5,161,1,1,0,124,1,160,7,161,0,125,6,87,0, - 110,38,4,0,116,2,144,1,121,66,1,0,1,0,1,0, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,89,0,110,2,48,0,124,6,160,12,116,9,161,1, - 125,7,124,7,100,6,107,0,144,1,114,106,116,3,100,7, - 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,6, - 124,7,124,7,116,5,23,0,133,2,25,0,125,3,116,8, - 124,3,131,1,116,5,107,3,144,1,114,154,116,3,100,8, + 25,0,116,9,107,3,114,201,122,12,124,1,160,4,100,6, + 100,3,161,2,1,0,124,1,160,6,161,0,125,4,87,0, + 110,16,4,0,116,2,121,114,1,0,1,0,1,0,116,3, + 100,4,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 119,0,116,10,124,4,116,11,24,0,116,5,24,0,100,6, + 131,2,125,5,122,11,124,1,160,4,124,5,161,1,1,0, + 124,1,160,7,161,0,125,6,87,0,110,16,4,0,116,2, + 121,151,1,0,1,0,1,0,116,3,100,4,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,119,0,124,6,160,12, + 116,9,161,1,125,7,124,7,100,6,107,0,114,170,116,3, + 100,7,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 124,6,124,7,124,7,116,5,23,0,133,2,25,0,125,3, + 116,8,124,3,131,1,116,5,107,3,114,193,116,3,100,8, 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,4, 116,8,124,6,131,1,24,0,124,7,23,0,125,2,116,13, 124,3,100,9,100,10,133,2,25,0,131,1,125,8,116,13, 124,3,100,10,100,11,133,2,25,0,131,1,125,9,124,2, - 124,8,107,0,144,1,114,230,116,3,100,12,124,0,155,2, - 157,2,124,0,100,2,141,2,130,1,124,2,124,9,107,0, - 144,2,114,2,116,3,100,13,124,0,155,2,157,2,124,0, - 100,2,141,2,130,1,124,2,124,8,56,0,125,2,124,2, - 124,9,24,0,125,10,124,10,100,6,107,0,144,2,114,46, - 116,3,100,14,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,105,0,125,11,100,6,125,12,122,14,124,1,160,4, - 124,2,161,1,1,0,87,0,110,38,4,0,116,2,144,2, - 121,106,1,0,1,0,1,0,116,3,100,4,124,0,155,2, - 157,2,124,0,100,2,141,2,130,1,89,0,110,2,48,0, - 124,1,160,7,100,15,161,1,125,3,116,8,124,3,131,1, - 100,5,107,0,144,2,114,140,116,14,100,16,131,1,130,1, - 124,3,100,0,100,5,133,2,25,0,100,17,107,3,144,2, - 114,162,144,4,113,208,116,8,124,3,131,1,100,15,107,3, - 144,2,114,184,116,14,100,16,131,1,130,1,116,15,124,3, - 100,18,100,19,133,2,25,0,131,1,125,13,116,15,124,3, - 100,19,100,9,133,2,25,0,131,1,125,14,116,15,124,3, - 100,9,100,20,133,2,25,0,131,1,125,15,116,15,124,3, - 100,20,100,10,133,2,25,0,131,1,125,16,116,13,124,3, - 100,10,100,11,133,2,25,0,131,1,125,17,116,13,124,3, - 100,11,100,21,133,2,25,0,131,1,125,18,116,13,124,3, - 100,21,100,22,133,2,25,0,131,1,125,4,116,15,124,3, - 100,22,100,23,133,2,25,0,131,1,125,19,116,15,124,3, - 100,23,100,24,133,2,25,0,131,1,125,20,116,15,124,3, - 100,24,100,25,133,2,25,0,131,1,125,21,116,13,124,3, - 100,26,100,15,133,2,25,0,131,1,125,22,124,19,124,20, - 23,0,124,21,23,0,125,8,124,22,124,9,107,4,144,3, - 114,144,116,3,100,27,124,0,155,2,157,2,124,0,100,2, - 141,2,130,1,124,22,124,10,55,0,125,22,122,14,124,1, - 160,7,124,19,161,1,125,23,87,0,110,38,4,0,116,2, - 144,3,121,204,1,0,1,0,1,0,116,3,100,4,124,0, - 155,2,157,2,124,0,100,2,141,2,130,1,89,0,110,2, - 48,0,116,8,124,23,131,1,124,19,107,3,144,3,114,238, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,122,50,116,8,124,1,160,7,124,8,124,19,24,0, - 161,1,131,1,124,8,124,19,24,0,107,3,144,4,114,30, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,87,0,110,38,4,0,116,2,144,4,121,70,1,0, + 124,8,107,0,114,230,116,3,100,12,124,0,155,2,157,2, + 124,0,100,2,141,2,130,1,124,2,124,9,107,0,114,243, + 116,3,100,13,124,0,155,2,157,2,124,0,100,2,141,2, + 130,1,124,2,124,8,56,0,125,2,124,2,124,9,24,0, + 125,10,124,10,100,6,107,0,144,1,114,9,116,3,100,14, + 124,0,155,2,157,2,124,0,100,2,141,2,130,1,105,0, + 125,11,100,6,125,12,122,7,124,1,160,4,124,2,161,1, + 1,0,87,0,110,17,4,0,116,2,144,1,121,37,1,0, 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0, - 100,2,141,2,130,1,89,0,110,2,48,0,124,13,100,28, - 64,0,144,4,114,92,124,23,160,16,161,0,125,23,110,52, - 122,14,124,23,160,16,100,29,161,1,125,23,87,0,110,36, - 4,0,116,17,144,4,121,142,1,0,1,0,1,0,124,23, - 160,16,100,30,161,1,160,18,116,19,161,1,125,23,89,0, - 110,2,48,0,124,23,160,20,100,31,116,21,161,2,125,23, - 116,22,160,23,124,0,124,23,161,2,125,24,124,24,124,14, - 124,18,124,4,124,22,124,15,124,16,124,17,102,8,125,25, - 124,25,124,11,124,23,60,0,124,12,100,32,55,0,125,12, - 144,2,113,108,87,0,100,0,4,0,4,0,131,3,1,0, - 110,18,49,0,144,4,115,230,48,0,1,0,1,0,1,0, - 89,0,1,0,116,24,160,25,100,33,124,12,124,0,161,3, - 1,0,124,11,83,0,41,34,78,122,21,99,97,110,39,116, - 32,111,112,101,110,32,90,105,112,32,102,105,108,101,58,32, - 114,12,0,0,0,114,86,0,0,0,250,21,99,97,110,39, - 116,32,114,101,97,100,32,90,105,112,32,102,105,108,101,58, - 32,233,4,0,0,0,114,0,0,0,0,122,16,110,111,116, - 32,97,32,90,105,112,32,102,105,108,101,58,32,122,18,99, - 111,114,114,117,112,116,32,90,105,112,32,102,105,108,101,58, - 32,233,12,0,0,0,233,16,0,0,0,233,20,0,0,0, - 122,28,98,97,100,32,99,101,110,116,114,97,108,32,100,105, - 114,101,99,116,111,114,121,32,115,105,122,101,58,32,122,30, - 98,97,100,32,99,101,110,116,114,97,108,32,100,105,114,101, - 99,116,111,114,121,32,111,102,102,115,101,116,58,32,122,38, - 98,97,100,32,99,101,110,116,114,97,108,32,100,105,114,101, - 99,116,111,114,121,32,115,105,122,101,32,111,114,32,111,102, - 102,115,101,116,58,32,233,46,0,0,0,250,27,69,79,70, - 32,114,101,97,100,32,119,104,101,114,101,32,110,111,116,32, - 101,120,112,101,99,116,101,100,115,4,0,0,0,80,75,1, - 2,233,8,0,0,0,233,10,0,0,0,233,14,0,0,0, - 233,24,0,0,0,233,28,0,0,0,233,30,0,0,0,233, - 32,0,0,0,233,34,0,0,0,233,42,0,0,0,122,25, - 98,97,100,32,108,111,99,97,108,32,104,101,97,100,101,114, - 32,111,102,102,115,101,116,58,32,105,0,8,0,0,218,5, - 97,115,99,105,105,90,6,108,97,116,105,110,49,250,1,47, - 114,5,0,0,0,122,33,122,105,112,105,109,112,111,114,116, - 58,32,102,111,117,110,100,32,123,125,32,110,97,109,101,115, - 32,105,110,32,123,33,114,125,41,26,218,3,95,105,111,218, - 9,111,112,101,110,95,99,111,100,101,114,22,0,0,0,114, - 3,0,0,0,218,4,115,101,101,107,218,20,69,78,68,95, - 67,69,78,84,82,65,76,95,68,73,82,95,83,73,90,69, - 90,4,116,101,108,108,218,4,114,101,97,100,114,51,0,0, - 0,218,18,83,84,82,73,78,71,95,69,78,68,95,65,82, - 67,72,73,86,69,218,3,109,97,120,218,15,77,65,88,95, - 67,79,77,77,69,78,84,95,76,69,78,218,5,114,102,105, - 110,100,114,2,0,0,0,218,8,69,79,70,69,114,114,111, - 114,114,1,0,0,0,114,62,0,0,0,218,18,85,110,105, - 99,111,100,101,68,101,99,111,100,101,69,114,114,111,114,218, - 9,116,114,97,110,115,108,97,116,101,218,11,99,112,52,51, - 55,95,116,97,98,108,101,114,19,0,0,0,114,20,0,0, - 0,114,21,0,0,0,114,30,0,0,0,114,76,0,0,0, - 114,77,0,0,0,41,26,114,29,0,0,0,218,2,102,112, - 90,15,104,101,97,100,101,114,95,112,111,115,105,116,105,111, - 110,218,6,98,117,102,102,101,114,218,9,102,105,108,101,95, - 115,105,122,101,90,17,109,97,120,95,99,111,109,109,101,110, - 116,95,115,116,97,114,116,218,4,100,97,116,97,90,3,112, - 111,115,218,11,104,101,97,100,101,114,95,115,105,122,101,90, - 13,104,101,97,100,101,114,95,111,102,102,115,101,116,90,10, - 97,114,99,95,111,102,102,115,101,116,114,33,0,0,0,218, - 5,99,111,117,110,116,218,5,102,108,97,103,115,218,8,99, - 111,109,112,114,101,115,115,218,4,116,105,109,101,218,4,100, - 97,116,101,218,3,99,114,99,218,9,100,97,116,97,95,115, - 105,122,101,218,9,110,97,109,101,95,115,105,122,101,218,10, - 101,120,116,114,97,95,115,105,122,101,90,12,99,111,109,109, - 101,110,116,95,115,105,122,101,218,11,102,105,108,101,95,111, - 102,102,115,101,116,114,59,0,0,0,114,13,0,0,0,218, - 1,116,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,27,0,0,0,96,1,0,0,115,212,0,0,0,0, - 1,2,1,14,1,12,1,24,2,8,1,2,1,14,1,8, - 1,14,1,12,1,24,1,12,1,18,1,18,3,2,1,12, - 1,12,1,12,1,10,1,2,255,12,2,8,1,2,255,2, - 1,2,255,4,2,2,1,10,1,12,1,14,1,10,1,2, - 255,12,2,10,1,10,1,10,1,2,255,6,2,16,1,14, - 1,10,1,2,255,6,2,16,2,16,1,16,1,10,1,18, - 1,10,1,18,1,8,1,8,1,10,1,18,2,4,2,4, - 1,2,1,14,1,14,1,24,2,10,1,14,1,8,2,18, - 1,4,1,14,1,8,1,16,1,16,1,16,1,16,1,16, - 1,16,1,16,1,16,1,16,1,16,1,16,1,12,1,10, - 1,18,1,8,2,2,1,14,1,14,1,24,1,14,1,18, - 4,2,1,28,1,22,1,14,1,24,2,10,2,10,3,2, - 1,14,1,14,1,22,2,12,1,12,1,20,1,8,1,44, - 1,14,1,114,27,0,0,0,117,190,1,0,0,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,195,135,195, - 188,195,169,195,162,195,164,195,160,195,165,195,167,195,170,195, - 171,195,168,195,175,195,174,195,172,195,132,195,133,195,137,195, - 166,195,134,195,180,195,182,195,178,195,187,195,185,195,191,195, - 150,195,156,194,162,194,163,194,165,226,130,167,198,146,195,161, - 195,173,195,179,195,186,195,177,195,145,194,170,194,186,194,191, - 226,140,144,194,172,194,189,194,188,194,161,194,171,194,187,226, - 150,145,226,150,146,226,150,147,226,148,130,226,148,164,226,149, - 161,226,149,162,226,149,150,226,149,149,226,149,163,226,149,145, - 226,149,151,226,149,157,226,149,156,226,149,155,226,148,144,226, - 148,148,226,148,180,226,148,172,226,148,156,226,148,128,226,148, - 188,226,149,158,226,149,159,226,149,154,226,149,148,226,149,169, - 226,149,166,226,149,160,226,149,144,226,149,172,226,149,167,226, - 149,168,226,149,164,226,149,165,226,149,153,226,149,152,226,149, - 146,226,149,147,226,149,171,226,149,170,226,148,152,226,148,140, - 226,150,136,226,150,132,226,150,140,226,150,144,226,150,128,206, - 177,195,159,206,147,207,128,206,163,207,131,194,181,207,132,206, - 166,206,152,206,169,206,180,226,136,158,207,134,206,181,226,136, - 169,226,137,161,194,177,226,137,165,226,137,164,226,140,160,226, - 140,161,195,183,226,137,136,194,176,226,136,153,194,183,226,136, - 154,226,129,191,194,178,226,150,160,194,160,99,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0, - 67,0,0,0,115,110,0,0,0,116,0,114,22,116,1,160, - 2,100,1,161,1,1,0,116,3,100,2,131,1,130,1,100, - 3,97,0,122,62,122,16,100,4,100,5,108,4,109,5,125, - 0,1,0,87,0,110,36,4,0,116,6,121,80,1,0,1, - 0,1,0,116,1,160,2,100,1,161,1,1,0,116,3,100, - 2,131,1,130,1,89,0,110,2,48,0,87,0,100,6,97, - 0,110,6,100,6,97,0,48,0,116,1,160,2,100,7,161, - 1,1,0,124,0,83,0,41,8,78,122,27,122,105,112,105, - 109,112,111,114,116,58,32,122,108,105,98,32,85,78,65,86, - 65,73,76,65,66,76,69,250,41,99,97,110,39,116,32,100, - 101,99,111,109,112,114,101,115,115,32,100,97,116,97,59,32, - 122,108,105,98,32,110,111,116,32,97,118,97,105,108,97,98, - 108,101,84,114,0,0,0,0,169,1,218,10,100,101,99,111, - 109,112,114,101,115,115,70,122,25,122,105,112,105,109,112,111, - 114,116,58,32,122,108,105,98,32,97,118,97,105,108,97,98, - 108,101,41,7,218,15,95,105,109,112,111,114,116,105,110,103, - 95,122,108,105,98,114,76,0,0,0,114,77,0,0,0,114, - 3,0,0,0,90,4,122,108,105,98,114,141,0,0,0,218, - 9,69,120,99,101,112,116,105,111,110,114,140,0,0,0,114, - 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,20, - 95,103,101,116,95,100,101,99,111,109,112,114,101,115,115,95, - 102,117,110,99,254,1,0,0,115,24,0,0,0,0,2,4, - 3,10,1,8,2,4,1,4,1,16,1,12,1,10,1,16, - 2,12,2,10,1,114,144,0,0,0,99,2,0,0,0,0, - 0,0,0,0,0,0,0,17,0,0,0,9,0,0,0,67, - 0,0,0,115,144,1,0,0,124,1,92,8,125,2,125,3, - 125,4,125,5,125,6,125,7,125,8,125,9,124,4,100,1, - 107,0,114,36,116,0,100,2,131,1,130,1,116,1,160,2, - 124,0,161,1,144,1,143,14,125,10,122,14,124,10,160,3, - 124,6,161,1,1,0,87,0,110,36,4,0,116,4,121,100, - 1,0,1,0,1,0,116,0,100,3,124,0,155,2,157,2, - 124,0,100,4,141,2,130,1,89,0,110,2,48,0,124,10, - 160,5,100,5,161,1,125,11,116,6,124,11,131,1,100,5, - 107,3,114,132,116,7,100,6,131,1,130,1,124,11,100,0, - 100,7,133,2,25,0,100,8,107,3,114,166,116,0,100,9, - 124,0,155,2,157,2,124,0,100,4,141,2,130,1,116,8, - 124,11,100,10,100,11,133,2,25,0,131,1,125,12,116,8, - 124,11,100,11,100,5,133,2,25,0,131,1,125,13,100,5, - 124,12,23,0,124,13,23,0,125,14,124,6,124,14,55,0, - 125,6,122,14,124,10,160,3,124,6,161,1,1,0,87,0, - 110,38,4,0,116,4,144,1,121,14,1,0,1,0,1,0, - 116,0,100,3,124,0,155,2,157,2,124,0,100,4,141,2, - 130,1,89,0,110,2,48,0,124,10,160,5,124,4,161,1, - 125,15,116,6,124,15,131,1,124,4,107,3,144,1,114,48, - 116,4,100,12,131,1,130,1,87,0,100,0,4,0,4,0, - 131,3,1,0,110,18,49,0,144,1,115,70,48,0,1,0, - 1,0,1,0,89,0,1,0,124,3,100,1,107,2,144,1, - 114,94,124,15,83,0,122,10,116,9,131,0,125,16,87,0, - 110,28,4,0,116,10,144,1,121,132,1,0,1,0,1,0, - 116,0,100,13,131,1,130,1,89,0,110,2,48,0,124,16, - 124,15,100,14,131,2,83,0,41,15,78,114,0,0,0,0, - 122,18,110,101,103,97,116,105,118,101,32,100,97,116,97,32, - 115,105,122,101,114,92,0,0,0,114,12,0,0,0,114,104, - 0,0,0,114,98,0,0,0,114,93,0,0,0,115,4,0, - 0,0,80,75,3,4,122,23,98,97,100,32,108,111,99,97, - 108,32,102,105,108,101,32,104,101,97,100,101,114,58,32,233, - 26,0,0,0,114,103,0,0,0,122,26,122,105,112,105,109, - 112,111,114,116,58,32,99,97,110,39,116,32,114,101,97,100, - 32,100,97,116,97,114,139,0,0,0,105,241,255,255,255,41, - 11,114,3,0,0,0,114,110,0,0,0,114,111,0,0,0, - 114,112,0,0,0,114,22,0,0,0,114,114,0,0,0,114, - 51,0,0,0,114,119,0,0,0,114,1,0,0,0,114,144, - 0,0,0,114,143,0,0,0,41,17,114,29,0,0,0,114, - 54,0,0,0,90,8,100,97,116,97,112,97,116,104,114,130, - 0,0,0,114,134,0,0,0,114,125,0,0,0,114,137,0, - 0,0,114,131,0,0,0,114,132,0,0,0,114,133,0,0, - 0,114,123,0,0,0,114,124,0,0,0,114,135,0,0,0, - 114,136,0,0,0,114,127,0,0,0,90,8,114,97,119,95, - 100,97,116,97,114,141,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,52,0,0,0,19,2,0, - 0,115,62,0,0,0,0,1,20,1,8,1,8,2,14,2, - 2,1,14,1,12,1,24,1,10,1,12,1,8,2,16,2, - 18,2,16,1,16,1,12,1,8,1,2,1,14,1,14,1, - 24,1,10,1,14,1,40,2,10,2,4,3,2,1,10,1, - 14,1,14,1,114,52,0,0,0,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,0, - 0,0,115,16,0,0,0,116,0,124,0,124,1,24,0,131, - 1,100,1,107,1,83,0,41,2,78,114,5,0,0,0,41, - 1,218,3,97,98,115,41,2,90,2,116,49,90,2,116,50, - 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, - 9,95,101,113,95,109,116,105,109,101,65,2,0,0,115,2, - 0,0,0,0,2,114,147,0,0,0,99,5,0,0,0,0, - 0,0,0,0,0,0,0,14,0,0,0,8,0,0,0,67, - 0,0,0,115,56,1,0,0,124,3,124,2,100,1,156,2, - 125,5,122,18,116,0,160,1,124,4,124,3,124,5,161,3, - 125,6,87,0,110,20,4,0,116,2,121,48,1,0,1,0, - 1,0,89,0,100,0,83,0,48,0,124,6,100,2,64,0, - 100,3,107,3,125,7,124,7,114,178,124,6,100,4,64,0, - 100,3,107,3,125,8,116,3,106,4,100,5,107,3,114,176, - 124,8,115,102,116,3,106,4,100,6,107,2,114,176,116,5, - 124,0,124,2,131,2,125,9,124,9,100,0,117,1,114,176, - 116,3,160,6,116,0,106,7,124,9,161,2,125,10,122,20, - 116,0,160,8,124,4,124,10,124,3,124,5,161,4,1,0, - 87,0,110,20,4,0,116,2,121,174,1,0,1,0,1,0, - 89,0,100,0,83,0,48,0,110,84,116,9,124,0,124,2, - 131,2,92,2,125,11,125,12,124,11,144,1,114,6,116,10, - 116,11,124,4,100,7,100,8,133,2,25,0,131,1,124,11, - 131,2,114,242,116,11,124,4,100,8,100,9,133,2,25,0, - 131,1,124,12,107,3,144,1,114,6,116,12,160,13,100,10, - 124,3,155,2,157,2,161,1,1,0,100,0,83,0,116,14, - 160,15,124,4,100,9,100,0,133,2,25,0,161,1,125,13, - 116,16,124,13,116,17,131,2,144,1,115,52,116,18,100,11, - 124,1,155,2,100,12,157,3,131,1,130,1,124,13,83,0, - 41,13,78,41,2,114,59,0,0,0,114,13,0,0,0,114, - 5,0,0,0,114,0,0,0,0,114,86,0,0,0,90,5, - 110,101,118,101,114,90,6,97,108,119,97,121,115,114,99,0, - 0,0,114,94,0,0,0,114,95,0,0,0,122,22,98,121, - 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, - 102,111,114,32,122,16,99,111,109,112,105,108,101,100,32,109, - 111,100,117,108,101,32,122,21,32,105,115,32,110,111,116,32, - 97,32,99,111,100,101,32,111,98,106,101,99,116,41,19,114, - 21,0,0,0,90,13,95,99,108,97,115,115,105,102,121,95, - 112,121,99,114,75,0,0,0,218,4,95,105,109,112,90,21, + 100,2,141,2,130,1,119,0,9,0,124,1,160,7,100,16, + 161,1,125,3,116,8,124,3,131,1,100,5,107,0,144,1, + 114,55,116,14,100,17,131,1,130,1,124,3,100,0,100,5, + 133,2,25,0,100,18,107,3,144,1,114,66,144,1,110,19, + 116,8,124,3,131,1,100,16,107,3,144,1,114,77,116,14, + 100,17,131,1,130,1,116,15,124,3,100,19,100,20,133,2, + 25,0,131,1,125,13,116,15,124,3,100,20,100,9,133,2, + 25,0,131,1,125,14,116,15,124,3,100,9,100,21,133,2, + 25,0,131,1,125,15,116,15,124,3,100,21,100,10,133,2, + 25,0,131,1,125,16,116,13,124,3,100,10,100,11,133,2, + 25,0,131,1,125,17,116,13,124,3,100,11,100,22,133,2, + 25,0,131,1,125,18,116,13,124,3,100,22,100,23,133,2, + 25,0,131,1,125,4,116,15,124,3,100,23,100,24,133,2, + 25,0,131,1,125,19,116,15,124,3,100,24,100,25,133,2, + 25,0,131,1,125,20,116,15,124,3,100,25,100,26,133,2, + 25,0,131,1,125,21,116,13,124,3,100,27,100,16,133,2, + 25,0,131,1,125,22,124,19,124,20,23,0,124,21,23,0, + 125,8,124,22,124,9,107,4,144,1,114,185,116,3,100,28, + 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,22, + 124,10,55,0,125,22,122,7,124,1,160,7,124,19,161,1, + 125,23,87,0,110,17,4,0,116,2,144,1,121,213,1,0, + 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0, + 100,2,141,2,130,1,119,0,116,8,124,23,131,1,124,19, + 107,3,144,1,114,230,116,3,100,4,124,0,155,2,157,2, + 124,0,100,2,141,2,130,1,122,25,116,8,124,1,160,7, + 124,8,124,19,24,0,161,1,131,1,124,8,124,19,24,0, + 107,3,144,1,114,254,116,3,100,4,124,0,155,2,157,2, + 124,0,100,2,141,2,130,1,87,0,110,17,4,0,116,2, + 144,2,121,16,1,0,1,0,1,0,116,3,100,4,124,0, + 155,2,157,2,124,0,100,2,141,2,130,1,119,0,124,13, + 100,29,64,0,144,2,114,27,124,23,160,16,161,0,125,23, + 110,26,122,7,124,23,160,16,100,30,161,1,125,23,87,0, + 110,18,4,0,116,17,144,2,121,52,1,0,1,0,1,0, + 124,23,160,16,100,31,161,1,160,18,116,19,161,1,125,23, + 89,0,110,1,119,0,124,23,160,20,100,32,116,21,161,2, + 125,23,116,22,160,23,124,0,124,23,161,2,125,24,124,24, + 124,14,124,18,124,4,124,22,124,15,124,16,124,17,102,8, + 125,25,124,25,124,11,124,23,60,0,124,12,100,33,55,0, + 125,12,144,1,113,39,87,0,100,0,4,0,4,0,131,3, + 1,0,110,9,49,0,144,2,115,96,119,1,1,0,1,0, + 1,0,89,0,1,0,116,24,160,25,100,34,124,12,124,0, + 161,3,1,0,124,11,83,0,41,35,78,122,21,99,97,110, + 39,116,32,111,112,101,110,32,90,105,112,32,102,105,108,101, + 58,32,114,12,0,0,0,114,93,0,0,0,250,21,99,97, + 110,39,116,32,114,101,97,100,32,90,105,112,32,102,105,108, + 101,58,32,233,4,0,0,0,114,0,0,0,0,122,16,110, + 111,116,32,97,32,90,105,112,32,102,105,108,101,58,32,122, + 18,99,111,114,114,117,112,116,32,90,105,112,32,102,105,108, + 101,58,32,233,12,0,0,0,233,16,0,0,0,233,20,0, + 0,0,122,28,98,97,100,32,99,101,110,116,114,97,108,32, + 100,105,114,101,99,116,111,114,121,32,115,105,122,101,58,32, + 122,30,98,97,100,32,99,101,110,116,114,97,108,32,100,105, + 114,101,99,116,111,114,121,32,111,102,102,115,101,116,58,32, + 122,38,98,97,100,32,99,101,110,116,114,97,108,32,100,105, + 114,101,99,116,111,114,121,32,115,105,122,101,32,111,114,32, + 111,102,102,115,101,116,58,32,84,233,46,0,0,0,250,27, + 69,79,70,32,114,101,97,100,32,119,104,101,114,101,32,110, + 111,116,32,101,120,112,101,99,116,101,100,115,4,0,0,0, + 80,75,1,2,233,8,0,0,0,233,10,0,0,0,233,14, + 0,0,0,233,24,0,0,0,233,28,0,0,0,233,30,0, + 0,0,233,32,0,0,0,233,34,0,0,0,233,42,0,0, + 0,122,25,98,97,100,32,108,111,99,97,108,32,104,101,97, + 100,101,114,32,111,102,102,115,101,116,58,32,105,0,8,0, + 0,218,5,97,115,99,105,105,90,6,108,97,116,105,110,49, + 250,1,47,114,5,0,0,0,122,33,122,105,112,105,109,112, + 111,114,116,58,32,102,111,117,110,100,32,123,125,32,110,97, + 109,101,115,32,105,110,32,123,33,114,125,41,26,218,3,95, + 105,111,218,9,111,112,101,110,95,99,111,100,101,114,22,0, + 0,0,114,3,0,0,0,218,4,115,101,101,107,218,20,69, + 78,68,95,67,69,78,84,82,65,76,95,68,73,82,95,83, + 73,90,69,90,4,116,101,108,108,218,4,114,101,97,100,114, + 58,0,0,0,218,18,83,84,82,73,78,71,95,69,78,68, + 95,65,82,67,72,73,86,69,218,3,109,97,120,218,15,77, + 65,88,95,67,79,77,77,69,78,84,95,76,69,78,218,5, + 114,102,105,110,100,114,2,0,0,0,218,8,69,79,70,69, + 114,114,111,114,114,1,0,0,0,114,68,0,0,0,218,18, + 85,110,105,99,111,100,101,68,101,99,111,100,101,69,114,114, + 111,114,218,9,116,114,97,110,115,108,97,116,101,218,11,99, + 112,52,51,55,95,116,97,98,108,101,114,19,0,0,0,114, + 20,0,0,0,114,21,0,0,0,114,30,0,0,0,114,48, + 0,0,0,114,81,0,0,0,41,26,114,29,0,0,0,218, + 2,102,112,90,15,104,101,97,100,101,114,95,112,111,115,105, + 116,105,111,110,218,6,98,117,102,102,101,114,218,9,102,105, + 108,101,95,115,105,122,101,90,17,109,97,120,95,99,111,109, + 109,101,110,116,95,115,116,97,114,116,218,4,100,97,116,97, + 90,3,112,111,115,218,11,104,101,97,100,101,114,95,115,105, + 122,101,90,13,104,101,97,100,101,114,95,111,102,102,115,101, + 116,90,10,97,114,99,95,111,102,102,115,101,116,114,33,0, + 0,0,218,5,99,111,117,110,116,218,5,102,108,97,103,115, + 218,8,99,111,109,112,114,101,115,115,218,4,116,105,109,101, + 218,4,100,97,116,101,218,3,99,114,99,218,9,100,97,116, + 97,95,115,105,122,101,218,9,110,97,109,101,95,115,105,122, + 101,218,10,101,120,116,114,97,95,115,105,122,101,90,12,99, + 111,109,109,101,110,116,95,115,105,122,101,218,11,102,105,108, + 101,95,111,102,102,115,101,116,114,47,0,0,0,114,13,0, + 0,0,218,1,116,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,27,0,0,0,146,1,0,0,115,238,0, + 0,0,2,1,14,1,12,1,18,1,2,255,8,3,2,1, + 14,1,8,1,14,1,12,1,18,1,2,255,12,2,18,1, + 16,1,2,3,12,1,12,1,12,1,10,1,2,1,6,255, + 2,255,8,3,2,1,2,255,2,1,4,255,2,2,10,1, + 12,1,12,1,10,1,2,1,6,255,2,255,10,3,8,1, + 10,1,2,1,6,255,16,2,12,1,10,1,2,1,6,255, + 16,2,16,2,16,1,8,1,18,1,8,1,18,1,8,1, + 8,1,10,1,18,1,4,2,4,2,2,1,14,1,14,1, + 18,1,2,255,2,2,10,1,14,1,8,1,18,2,4,1, + 14,1,8,1,16,1,16,1,16,1,16,1,16,1,16,1, + 16,1,16,1,16,1,16,1,16,1,12,1,10,1,18,1, + 8,1,2,2,14,1,14,1,18,1,2,255,14,2,18,1, + 2,4,28,1,18,1,4,255,14,2,18,1,2,255,10,3, + 10,2,2,3,14,1,14,1,20,1,2,255,12,3,12,1, + 20,1,8,1,8,1,4,202,2,6,30,196,14,109,4,1, + 114,27,0,0,0,117,190,1,0,0,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,195,135,195,188,195,169, + 195,162,195,164,195,160,195,165,195,167,195,170,195,171,195,168, + 195,175,195,174,195,172,195,132,195,133,195,137,195,166,195,134, + 195,180,195,182,195,178,195,187,195,185,195,191,195,150,195,156, + 194,162,194,163,194,165,226,130,167,198,146,195,161,195,173,195, + 179,195,186,195,177,195,145,194,170,194,186,194,191,226,140,144, + 194,172,194,189,194,188,194,161,194,171,194,187,226,150,145,226, + 150,146,226,150,147,226,148,130,226,148,164,226,149,161,226,149, + 162,226,149,150,226,149,149,226,149,163,226,149,145,226,149,151, + 226,149,157,226,149,156,226,149,155,226,148,144,226,148,148,226, + 148,180,226,148,172,226,148,156,226,148,128,226,148,188,226,149, + 158,226,149,159,226,149,154,226,149,148,226,149,169,226,149,166, + 226,149,160,226,149,144,226,149,172,226,149,167,226,149,168,226, + 149,164,226,149,165,226,149,153,226,149,152,226,149,146,226,149, + 147,226,149,171,226,149,170,226,148,152,226,148,140,226,150,136, + 226,150,132,226,150,140,226,150,144,226,150,128,206,177,195,159, + 206,147,207,128,206,163,207,131,194,181,207,132,206,166,206,152, + 206,169,206,180,226,136,158,207,134,206,181,226,136,169,226,137, + 161,194,177,226,137,165,226,137,164,226,140,160,226,140,161,195, + 183,226,137,136,194,176,226,136,153,194,183,226,136,154,226,129, + 191,194,178,226,150,160,194,160,99,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,8,0,0,0,67,0,0, + 0,115,106,0,0,0,116,0,114,11,116,1,160,2,100,1, + 161,1,1,0,116,3,100,2,131,1,130,1,100,3,97,0, + 122,29,122,8,100,4,100,5,108,4,109,5,125,0,1,0, + 87,0,110,16,4,0,116,6,121,38,1,0,1,0,1,0, + 116,1,160,2,100,1,161,1,1,0,116,3,100,2,131,1, + 130,1,119,0,87,0,100,6,97,0,110,3,100,6,97,0, + 119,0,116,1,160,2,100,7,161,1,1,0,124,0,83,0, + 41,8,78,122,27,122,105,112,105,109,112,111,114,116,58,32, + 122,108,105,98,32,85,78,65,86,65,73,76,65,66,76,69, + 250,41,99,97,110,39,116,32,100,101,99,111,109,112,114,101, + 115,115,32,100,97,116,97,59,32,122,108,105,98,32,110,111, + 116,32,97,118,97,105,108,97,98,108,101,84,114,0,0,0, + 0,169,1,218,10,100,101,99,111,109,112,114,101,115,115,70, + 122,25,122,105,112,105,109,112,111,114,116,58,32,122,108,105, + 98,32,97,118,97,105,108,97,98,108,101,41,7,218,15,95, + 105,109,112,111,114,116,105,110,103,95,122,108,105,98,114,48, + 0,0,0,114,81,0,0,0,114,3,0,0,0,90,4,122, + 108,105,98,114,147,0,0,0,218,9,69,120,99,101,112,116, + 105,111,110,114,146,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,20,95,103,101,116,95,100,101, + 99,111,109,112,114,101,115,115,95,102,117,110,99,48,2,0, + 0,115,28,0,0,0,4,2,10,3,8,1,4,2,4,1, + 16,1,12,1,10,1,8,1,2,254,2,255,12,5,10,2, + 4,1,114,150,0,0,0,99,2,0,0,0,0,0,0,0, + 0,0,0,0,17,0,0,0,9,0,0,0,67,0,0,0, + 115,120,1,0,0,124,1,92,8,125,2,125,3,125,4,125, + 5,125,6,125,7,125,8,125,9,124,4,100,1,107,0,114, + 18,116,0,100,2,131,1,130,1,116,1,160,2,124,0,161, + 1,143,129,125,10,122,7,124,10,160,3,124,6,161,1,1, + 0,87,0,110,16,4,0,116,4,121,47,1,0,1,0,1, + 0,116,0,100,3,124,0,155,2,157,2,124,0,100,4,141, + 2,130,1,119,0,124,10,160,5,100,5,161,1,125,11,116, + 6,124,11,131,1,100,5,107,3,114,63,116,7,100,6,131, + 1,130,1,124,11,100,0,100,7,133,2,25,0,100,8,107, + 3,114,80,116,0,100,9,124,0,155,2,157,2,124,0,100, + 4,141,2,130,1,116,8,124,11,100,10,100,11,133,2,25, + 0,131,1,125,12,116,8,124,11,100,11,100,5,133,2,25, + 0,131,1,125,13,100,5,124,12,23,0,124,13,23,0,125, + 14,124,6,124,14,55,0,125,6,122,7,124,10,160,3,124, + 6,161,1,1,0,87,0,110,16,4,0,116,4,121,129,1, + 0,1,0,1,0,116,0,100,3,124,0,155,2,157,2,124, + 0,100,4,141,2,130,1,119,0,124,10,160,5,124,4,161, + 1,125,15,116,6,124,15,131,1,124,4,107,3,114,145,116, + 4,100,12,131,1,130,1,87,0,100,0,4,0,4,0,131, + 3,1,0,110,8,49,0,115,155,119,1,1,0,1,0,1, + 0,89,0,1,0,124,3,100,1,107,2,114,166,124,15,83, + 0,122,5,116,9,131,0,125,16,87,0,110,11,4,0,116, + 10,121,182,1,0,1,0,1,0,116,0,100,13,131,1,130, + 1,119,0,124,16,124,15,100,14,131,2,83,0,41,15,78, + 114,0,0,0,0,122,18,110,101,103,97,116,105,118,101,32, + 100,97,116,97,32,115,105,122,101,114,98,0,0,0,114,12, + 0,0,0,114,110,0,0,0,114,104,0,0,0,114,99,0, + 0,0,115,4,0,0,0,80,75,3,4,122,23,98,97,100, + 32,108,111,99,97,108,32,102,105,108,101,32,104,101,97,100, + 101,114,58,32,233,26,0,0,0,114,109,0,0,0,122,26, + 122,105,112,105,109,112,111,114,116,58,32,99,97,110,39,116, + 32,114,101,97,100,32,100,97,116,97,114,145,0,0,0,105, + 241,255,255,255,41,11,114,3,0,0,0,114,116,0,0,0, + 114,117,0,0,0,114,118,0,0,0,114,22,0,0,0,114, + 120,0,0,0,114,58,0,0,0,114,125,0,0,0,114,1, + 0,0,0,114,150,0,0,0,114,149,0,0,0,41,17,114, + 29,0,0,0,114,61,0,0,0,90,8,100,97,116,97,112, + 97,116,104,114,136,0,0,0,114,140,0,0,0,114,131,0, + 0,0,114,143,0,0,0,114,137,0,0,0,114,138,0,0, + 0,114,139,0,0,0,114,129,0,0,0,114,130,0,0,0, + 114,141,0,0,0,114,142,0,0,0,114,133,0,0,0,90, + 8,114,97,119,95,100,97,116,97,114,147,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,114,59,0, + 0,0,69,2,0,0,115,72,0,0,0,20,1,8,1,8, + 1,12,2,2,2,14,1,12,1,18,1,2,255,10,2,12, + 1,8,1,16,2,18,2,16,2,16,1,12,1,8,1,2, + 1,14,1,12,1,18,1,2,255,10,2,12,1,8,1,2, + 255,28,233,8,26,4,2,2,3,10,1,12,1,8,1,2, + 255,10,2,114,59,0,0,0,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, + 0,115,16,0,0,0,116,0,124,0,124,1,24,0,131,1, + 100,1,107,1,83,0,41,2,78,114,5,0,0,0,41,1, + 218,3,97,98,115,41,2,90,2,116,49,90,2,116,50,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,9, + 95,101,113,95,109,116,105,109,101,115,2,0,0,115,2,0, + 0,0,16,2,114,153,0,0,0,99,5,0,0,0,0,0, + 0,0,0,0,0,0,14,0,0,0,6,0,0,0,67,0, + 0,0,115,254,0,0,0,124,3,124,2,100,1,156,2,125, + 5,116,0,160,1,124,4,124,3,124,5,161,3,125,6,124, + 6,100,2,64,0,100,3,107,3,125,7,124,7,114,63,124, + 6,100,4,64,0,100,3,107,3,125,8,116,2,106,3,100, + 5,107,3,114,62,124,8,115,38,116,2,106,3,100,6,107, + 2,114,62,116,4,124,0,124,2,131,2,125,9,124,9,100, + 0,117,1,114,62,116,2,160,5,116,0,106,6,124,9,161, + 2,125,10,116,0,160,7,124,4,124,10,124,3,124,5,161, + 4,1,0,110,40,116,8,124,0,124,2,131,2,92,2,125, + 11,125,12,124,11,114,103,116,9,116,10,124,4,100,7,100, + 8,133,2,25,0,131,1,124,11,131,2,114,93,116,10,124, + 4,100,8,100,9,133,2,25,0,131,1,124,12,107,3,114, + 103,116,11,160,12,100,10,124,3,155,2,157,2,161,1,1, + 0,100,0,83,0,116,13,160,14,124,4,100,9,100,0,133, + 2,25,0,161,1,125,13,116,15,124,13,116,16,131,2,115, + 125,116,17,100,11,124,1,155,2,100,12,157,3,131,1,130, + 1,124,13,83,0,41,13,78,41,2,114,47,0,0,0,114, + 13,0,0,0,114,5,0,0,0,114,0,0,0,0,114,93, + 0,0,0,90,5,110,101,118,101,114,90,6,97,108,119,97, + 121,115,114,105,0,0,0,114,100,0,0,0,114,101,0,0, + 0,122,22,98,121,116,101,99,111,100,101,32,105,115,32,115, + 116,97,108,101,32,102,111,114,32,122,16,99,111,109,112,105, + 108,101,100,32,109,111,100,117,108,101,32,122,21,32,105,115, + 32,110,111,116,32,97,32,99,111,100,101,32,111,98,106,101, + 99,116,41,18,114,21,0,0,0,90,13,95,99,108,97,115, + 115,105,102,121,95,112,121,99,218,4,95,105,109,112,90,21, 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95, 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104, @@ -821,259 +907,157 @@ const unsigned char _Py_M__zipimport[] = { 78,85,77,66,69,82,90,18,95,118,97,108,105,100,97,116, 101,95,104,97,115,104,95,112,121,99,218,29,95,103,101,116, 95,109,116,105,109,101,95,97,110,100,95,115,105,122,101,95, - 111,102,95,115,111,117,114,99,101,114,147,0,0,0,114,2, - 0,0,0,114,76,0,0,0,114,77,0,0,0,218,7,109, + 111,102,95,115,111,117,114,99,101,114,153,0,0,0,114,2, + 0,0,0,114,48,0,0,0,114,81,0,0,0,218,7,109, 97,114,115,104,97,108,90,5,108,111,97,100,115,114,15,0, 0,0,218,10,95,99,111,100,101,95,116,121,112,101,218,9, 84,121,112,101,69,114,114,111,114,41,14,114,32,0,0,0, - 114,53,0,0,0,114,63,0,0,0,114,38,0,0,0,114, - 126,0,0,0,90,11,101,120,99,95,100,101,116,97,105,108, - 115,114,129,0,0,0,90,10,104,97,115,104,95,98,97,115, + 114,60,0,0,0,114,69,0,0,0,114,41,0,0,0,114, + 132,0,0,0,90,11,101,120,99,95,100,101,116,97,105,108, + 115,114,135,0,0,0,90,10,104,97,115,104,95,98,97,115, 101,100,90,12,99,104,101,99,107,95,115,111,117,114,99,101, - 90,12,115,111,117,114,99,101,95,98,121,116,101,115,114,150, + 90,12,115,111,117,114,99,101,95,98,121,116,101,115,114,156, 0,0,0,90,12,115,111,117,114,99,101,95,109,116,105,109, - 101,90,11,115,111,117,114,99,101,95,115,105,122,101,114,46, + 101,90,11,115,111,117,114,99,101,95,115,105,122,101,114,53, 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, 0,0,218,15,95,117,110,109,97,114,115,104,97,108,95,99, - 111,100,101,75,2,0,0,115,82,0,0,0,0,2,2,1, - 2,254,6,5,2,1,18,1,12,1,8,2,12,1,4,1, - 12,1,10,1,2,255,2,1,8,255,2,2,10,1,8,1, - 4,1,4,1,2,254,4,5,2,1,4,1,8,255,8,2, - 12,1,10,3,8,255,6,3,6,3,22,1,18,255,4,2, - 4,1,8,255,4,2,4,2,18,1,12,1,16,1,114,155, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0, - 0,124,0,160,0,100,1,100,2,161,2,125,0,124,0,160, - 0,100,3,100,2,161,2,125,0,124,0,83,0,41,4,78, - 115,2,0,0,0,13,10,243,1,0,0,0,10,243,1,0, - 0,0,13,41,1,114,19,0,0,0,41,1,218,6,115,111, - 117,114,99,101,114,9,0,0,0,114,9,0,0,0,114,10, - 0,0,0,218,23,95,110,111,114,109,97,108,105,122,101,95, - 108,105,110,101,95,101,110,100,105,110,103,115,126,2,0,0, - 115,6,0,0,0,0,1,12,1,12,1,114,159,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,6,0,0,0,67,0,0,0,115,24,0,0,0,116,0, - 124,1,131,1,125,1,116,1,124,1,124,0,100,1,100,2, - 100,3,141,4,83,0,41,4,78,114,74,0,0,0,84,41, - 1,90,12,100,111,110,116,95,105,110,104,101,114,105,116,41, - 2,114,159,0,0,0,218,7,99,111,109,112,105,108,101,41, - 2,114,53,0,0,0,114,158,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,15,95,99,111,109, - 112,105,108,101,95,115,111,117,114,99,101,133,2,0,0,115, - 4,0,0,0,0,1,8,1,114,161,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,11,0, - 0,0,67,0,0,0,115,68,0,0,0,116,0,160,1,124, - 0,100,1,63,0,100,2,23,0,124,0,100,3,63,0,100, - 4,64,0,124,0,100,5,64,0,124,1,100,6,63,0,124, - 1,100,3,63,0,100,7,64,0,124,1,100,5,64,0,100, - 8,20,0,100,9,100,9,100,9,102,9,161,1,83,0,41, - 10,78,233,9,0,0,0,105,188,7,0,0,233,5,0,0, - 0,233,15,0,0,0,233,31,0,0,0,233,11,0,0,0, - 233,63,0,0,0,114,86,0,0,0,114,14,0,0,0,41, - 2,114,131,0,0,0,90,6,109,107,116,105,109,101,41,2, - 218,1,100,114,138,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,14,95,112,97,114,115,101,95, - 100,111,115,116,105,109,101,139,2,0,0,115,18,0,0,0, - 0,1,4,1,10,1,10,1,6,1,6,1,10,1,10,1, - 6,249,114,169,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,6,0,0,0,10,0,0,0,67,0,0,0, - 115,114,0,0,0,122,82,124,1,100,1,100,0,133,2,25, - 0,100,2,118,0,115,22,74,0,130,1,124,1,100,0,100, - 1,133,2,25,0,125,1,124,0,106,0,124,1,25,0,125, - 2,124,2,100,3,25,0,125,3,124,2,100,4,25,0,125, - 4,124,2,100,5,25,0,125,5,116,1,124,4,124,3,131, - 2,124,5,102,2,87,0,83,0,4,0,116,2,116,3,116, - 4,102,3,121,108,1,0,1,0,1,0,89,0,100,6,83, - 0,48,0,100,0,83,0,41,7,78,114,14,0,0,0,169, - 2,218,1,99,218,1,111,114,163,0,0,0,233,6,0,0, - 0,233,3,0,0,0,41,2,114,0,0,0,0,114,0,0, - 0,0,41,5,114,28,0,0,0,114,169,0,0,0,114,26, - 0,0,0,218,10,73,110,100,101,120,69,114,114,111,114,114, - 154,0,0,0,41,6,114,32,0,0,0,114,13,0,0,0, - 114,54,0,0,0,114,131,0,0,0,114,132,0,0,0,90, - 17,117,110,99,111,109,112,114,101,115,115,101,100,95,115,105, - 122,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,151,0,0,0,152,2,0,0,115,20,0,0,0,0, - 1,2,2,20,1,12,1,10,3,8,1,8,1,8,1,16, - 1,18,1,114,151,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, - 0,115,84,0,0,0,124,1,100,1,100,0,133,2,25,0, - 100,2,118,0,115,20,74,0,130,1,124,1,100,0,100,1, - 133,2,25,0,125,1,122,14,124,0,106,0,124,1,25,0, - 125,2,87,0,110,20,4,0,116,1,121,66,1,0,1,0, - 1,0,89,0,100,0,83,0,48,0,116,2,124,0,106,3, - 124,2,131,2,83,0,100,0,83,0,41,3,78,114,14,0, - 0,0,114,170,0,0,0,41,4,114,28,0,0,0,114,26, - 0,0,0,114,52,0,0,0,114,29,0,0,0,41,3,114, - 32,0,0,0,114,13,0,0,0,114,54,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,114,149,0, - 0,0,171,2,0,0,115,14,0,0,0,0,2,20,1,12, - 2,2,1,14,1,12,1,8,2,114,149,0,0,0,99,2, - 0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,9, - 0,0,0,67,0,0,0,115,196,0,0,0,116,0,124,0, - 124,1,131,2,125,2,116,1,68,0,93,158,92,3,125,3, - 125,4,125,5,124,2,124,3,23,0,125,6,116,2,106,3, - 100,1,124,0,106,4,116,5,124,6,100,2,100,3,141,5, - 1,0,122,14,124,0,106,6,124,6,25,0,125,7,87,0, - 110,18,4,0,116,7,121,86,1,0,1,0,1,0,89,0, - 113,14,48,0,124,7,100,4,25,0,125,8,116,8,124,0, - 106,4,124,7,131,2,125,9,124,4,114,130,116,9,124,0, - 124,8,124,6,124,1,124,9,131,5,125,10,110,10,116,10, - 124,8,124,9,131,2,125,10,124,10,100,0,117,0,114,150, - 113,14,124,7,100,4,25,0,125,8,124,10,124,5,124,8, - 102,3,2,0,1,0,83,0,113,14,116,11,100,5,124,1, - 155,2,157,2,124,1,100,6,141,2,130,1,100,0,83,0, - 41,7,78,122,13,116,114,121,105,110,103,32,123,125,123,125, - 123,125,114,86,0,0,0,41,1,90,9,118,101,114,98,111, - 115,105,116,121,114,0,0,0,0,114,57,0,0,0,114,58, - 0,0,0,41,12,114,36,0,0,0,114,89,0,0,0,114, - 76,0,0,0,114,77,0,0,0,114,29,0,0,0,114,20, - 0,0,0,114,28,0,0,0,114,26,0,0,0,114,52,0, - 0,0,114,155,0,0,0,114,161,0,0,0,114,3,0,0, - 0,41,11,114,32,0,0,0,114,38,0,0,0,114,13,0, - 0,0,114,90,0,0,0,114,91,0,0,0,114,47,0,0, - 0,114,63,0,0,0,114,54,0,0,0,114,40,0,0,0, - 114,126,0,0,0,114,46,0,0,0,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,114,44,0,0,0,186,2, - 0,0,115,36,0,0,0,0,1,10,1,14,1,8,1,22, - 1,2,1,14,1,12,1,6,2,8,1,12,1,4,1,18, - 2,10,1,8,3,2,1,8,1,16,2,114,44,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,64,0,0,0,115,60,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,100,2,90,4,100,3, - 100,4,132,0,90,5,100,5,100,6,132,0,90,6,100,7, - 100,8,132,0,90,7,100,9,100,10,132,0,90,8,100,11, - 100,12,132,0,90,9,100,13,83,0,41,14,114,80,0,0, - 0,122,165,80,114,105,118,97,116,101,32,99,108,97,115,115, - 32,117,115,101,100,32,116,111,32,115,117,112,112,111,114,116, - 32,90,105,112,73,109,112,111,114,116,46,103,101,116,95,114, - 101,115,111,117,114,99,101,95,114,101,97,100,101,114,40,41, - 46,10,10,32,32,32,32,84,104,105,115,32,99,108,97,115, - 115,32,105,115,32,97,108,108,111,119,101,100,32,116,111,32, - 114,101,102,101,114,101,110,99,101,32,97,108,108,32,116,104, - 101,32,105,110,110,97,114,100,115,32,97,110,100,32,112,114, - 105,118,97,116,101,32,112,97,114,116,115,32,111,102,10,32, - 32,32,32,116,104,101,32,122,105,112,105,109,112,111,114,116, - 101,114,46,10,32,32,32,32,70,99,3,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,2,0,0,0,67,0, - 0,0,115,16,0,0,0,124,1,124,0,95,0,124,2,124, - 0,95,1,100,0,83,0,114,88,0,0,0,41,2,114,4, - 0,0,0,114,38,0,0,0,41,3,114,32,0,0,0,114, - 4,0,0,0,114,38,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,34,0,0,0,220,2,0, - 0,115,4,0,0,0,0,1,6,1,122,33,95,90,105,112, - 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101, - 97,100,101,114,46,95,95,105,110,105,116,95,95,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,8,0, - 0,0,67,0,0,0,115,90,0,0,0,124,0,106,0,160, - 1,100,1,100,2,161,2,125,2,124,2,155,0,100,2,124, - 1,155,0,157,3,125,3,100,3,100,4,108,2,109,3,125, - 4,1,0,122,18,124,4,124,0,106,4,160,5,124,3,161, - 1,131,1,87,0,83,0,4,0,116,6,121,84,1,0,1, - 0,1,0,116,7,124,3,131,1,130,1,89,0,110,2,48, - 0,100,0,83,0,41,5,78,114,85,0,0,0,114,109,0, - 0,0,114,0,0,0,0,41,1,218,7,66,121,116,101,115, - 73,79,41,8,114,38,0,0,0,114,19,0,0,0,90,2, - 105,111,114,176,0,0,0,114,4,0,0,0,114,55,0,0, - 0,114,22,0,0,0,218,17,70,105,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,41,5,114,32,0,0,0, - 218,8,114,101,115,111,117,114,99,101,218,16,102,117,108,108, - 110,97,109,101,95,97,115,95,112,97,116,104,114,13,0,0, - 0,114,176,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,13,111,112,101,110,95,114,101,115,111, - 117,114,99,101,224,2,0,0,115,14,0,0,0,0,1,14, - 1,14,1,12,1,2,1,18,1,12,1,122,38,95,90,105, - 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, - 101,97,100,101,114,46,111,112,101,110,95,114,101,115,111,117, - 114,99,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,8,0,0, - 0,116,0,130,1,100,0,83,0,114,88,0,0,0,41,1, - 114,177,0,0,0,41,2,114,32,0,0,0,114,178,0,0, + 111,100,101,123,2,0,0,115,72,0,0,0,2,2,2,1, + 6,254,14,5,12,2,4,1,12,1,10,1,2,1,2,255, + 8,1,2,255,10,2,8,1,4,1,4,1,2,1,4,254, + 4,5,8,1,4,255,2,128,8,4,6,255,4,3,22,3, + 18,1,2,255,4,2,8,1,4,255,4,2,18,2,10,1, + 16,1,4,1,114,161,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,4,0,0,0,67,0, + 0,0,115,28,0,0,0,124,0,160,0,100,1,100,2,161, + 2,125,0,124,0,160,0,100,3,100,2,161,2,125,0,124, + 0,83,0,41,4,78,115,2,0,0,0,13,10,243,1,0, + 0,0,10,243,1,0,0,0,13,41,1,114,19,0,0,0, + 41,1,218,6,115,111,117,114,99,101,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,23,95,110,111,114,109, + 97,108,105,122,101,95,108,105,110,101,95,101,110,100,105,110, + 103,115,168,2,0,0,115,6,0,0,0,12,1,12,1,4, + 1,114,165,0,0,0,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,6,0,0,0,67,0,0,0,115, + 24,0,0,0,116,0,124,1,131,1,125,1,116,1,124,1, + 124,0,100,1,100,2,100,3,141,4,83,0,41,4,78,114, + 79,0,0,0,84,41,1,90,12,100,111,110,116,95,105,110, + 104,101,114,105,116,41,2,114,165,0,0,0,218,7,99,111, + 109,112,105,108,101,41,2,114,60,0,0,0,114,164,0,0, 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,13,114,101,115,111,117,114,99,101,95,112,97,116,104,233, - 2,0,0,115,2,0,0,0,0,4,122,38,95,90,105,112, - 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101, - 97,100,101,114,46,114,101,115,111,117,114,99,101,95,112,97, - 116,104,99,2,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,8,0,0,0,67,0,0,0,115,70,0,0,0, - 124,0,106,0,160,1,100,1,100,2,161,2,125,2,124,2, - 155,0,100,2,124,1,155,0,157,3,125,3,122,16,124,0, - 106,2,160,3,124,3,161,1,1,0,87,0,110,20,4,0, - 116,4,121,64,1,0,1,0,1,0,89,0,100,3,83,0, - 48,0,100,4,83,0,41,5,78,114,85,0,0,0,114,109, - 0,0,0,70,84,41,5,114,38,0,0,0,114,19,0,0, - 0,114,4,0,0,0,114,55,0,0,0,114,22,0,0,0, - 41,4,114,32,0,0,0,114,59,0,0,0,114,179,0,0, - 0,114,13,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,11,105,115,95,114,101,115,111,117,114, - 99,101,239,2,0,0,115,14,0,0,0,0,3,14,1,14, - 1,2,1,16,1,12,1,8,1,122,36,95,90,105,112,73, - 109,112,111,114,116,82,101,115,111,117,114,99,101,82,101,97, - 100,101,114,46,105,115,95,114,101,115,111,117,114,99,101,99, - 1,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0, - 9,0,0,0,99,0,0,0,115,184,0,0,0,100,1,100, - 2,108,0,109,1,125,1,1,0,124,1,124,0,106,2,160, - 3,124,0,106,4,161,1,131,1,125,2,124,2,160,5,124, - 0,106,2,106,6,161,1,125,3,124,3,106,7,100,3,107, - 2,115,58,74,0,130,1,124,3,106,8,125,4,116,9,131, - 0,125,5,124,0,106,2,106,10,68,0,93,100,125,6,122, - 18,124,1,124,6,131,1,160,5,124,4,161,1,125,7,87, - 0,110,22,4,0,116,11,121,122,1,0,1,0,1,0,89, - 0,113,78,89,0,110,2,48,0,124,7,106,8,106,7,125, - 8,116,12,124,8,131,1,100,1,107,2,114,154,124,7,106, - 7,86,0,1,0,113,78,124,8,124,5,118,1,114,78,124, - 5,160,13,124,8,161,1,1,0,124,8,86,0,1,0,113, - 78,100,0,83,0,41,4,78,114,0,0,0,0,41,1,218, - 4,80,97,116,104,114,60,0,0,0,41,14,90,7,112,97, - 116,104,108,105,98,114,183,0,0,0,114,4,0,0,0,114, - 56,0,0,0,114,38,0,0,0,90,11,114,101,108,97,116, - 105,118,101,95,116,111,114,29,0,0,0,114,59,0,0,0, - 90,6,112,97,114,101,110,116,218,3,115,101,116,114,28,0, - 0,0,114,23,0,0,0,114,51,0,0,0,218,3,97,100, - 100,41,9,114,32,0,0,0,114,183,0,0,0,90,13,102, - 117,108,108,110,97,109,101,95,112,97,116,104,90,13,114,101, - 108,97,116,105,118,101,95,112,97,116,104,90,12,112,97,99, - 107,97,103,101,95,112,97,116,104,90,12,115,117,98,100,105, - 114,115,95,115,101,101,110,218,8,102,105,108,101,110,97,109, - 101,90,8,114,101,108,97,116,105,118,101,90,11,112,97,114, - 101,110,116,95,110,97,109,101,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,8,99,111,110,116,101,110,116, - 115,250,2,0,0,115,34,0,0,0,0,8,12,1,18,1, - 14,3,14,1,6,1,6,1,12,1,2,1,18,1,12,1, - 10,5,8,1,12,1,10,1,8,1,10,1,122,33,95,90, - 105,112,73,109,112,111,114,116,82,101,115,111,117,114,99,101, - 82,101,97,100,101,114,46,99,111,110,116,101,110,116,115,78, - 41,10,114,6,0,0,0,114,7,0,0,0,114,8,0,0, - 0,114,84,0,0,0,114,81,0,0,0,114,34,0,0,0, - 114,180,0,0,0,114,181,0,0,0,114,182,0,0,0,114, - 187,0,0,0,114,9,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,80,0,0,0,212,2,0, - 0,115,14,0,0,0,8,1,4,5,4,2,8,4,8,9, - 8,6,8,11,114,80,0,0,0,41,45,114,84,0,0,0, - 90,26,95,102,114,111,122,101,110,95,105,109,112,111,114,116, - 108,105,98,95,101,120,116,101,114,110,97,108,114,21,0,0, - 0,114,1,0,0,0,114,2,0,0,0,90,17,95,102,114, - 111,122,101,110,95,105,109,112,111,114,116,108,105,98,114,76, - 0,0,0,114,148,0,0,0,114,110,0,0,0,114,152,0, - 0,0,114,67,0,0,0,114,131,0,0,0,90,7,95,95, - 97,108,108,95,95,114,20,0,0,0,90,15,112,97,116,104, - 95,115,101,112,97,114,97,116,111,114,115,114,18,0,0,0, - 114,75,0,0,0,114,3,0,0,0,114,25,0,0,0,218, - 4,116,121,112,101,114,70,0,0,0,114,113,0,0,0,114, - 115,0,0,0,114,117,0,0,0,114,4,0,0,0,114,89, - 0,0,0,114,36,0,0,0,114,37,0,0,0,114,35,0, - 0,0,114,27,0,0,0,114,122,0,0,0,114,142,0,0, - 0,114,144,0,0,0,114,52,0,0,0,114,147,0,0,0, - 114,155,0,0,0,218,8,95,95,99,111,100,101,95,95,114, - 153,0,0,0,114,159,0,0,0,114,161,0,0,0,114,169, - 0,0,0,114,151,0,0,0,114,149,0,0,0,114,44,0, - 0,0,114,80,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,8,60,109,111, - 100,117,108,101,62,1,0,0,0,115,88,0,0,0,4,16, - 8,1,16,1,8,1,8,1,8,1,8,1,8,1,8,2, - 8,3,6,1,14,3,16,4,4,2,8,2,4,1,4,1, - 4,2,14,127,0,127,0,1,12,1,12,1,2,1,2,252, - 4,9,8,4,8,9,8,31,8,126,2,254,2,29,4,5, - 8,21,8,46,8,10,8,46,10,5,8,7,8,6,8,13, - 8,19,8,15,8,26, + 218,15,95,99,111,109,112,105,108,101,95,115,111,117,114,99, + 101,175,2,0,0,115,4,0,0,0,8,1,16,1,114,167, + 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,11,0,0,0,67,0,0,0,115,68,0,0, + 0,116,0,160,1,124,0,100,1,63,0,100,2,23,0,124, + 0,100,3,63,0,100,4,64,0,124,0,100,5,64,0,124, + 1,100,6,63,0,124,1,100,3,63,0,100,7,64,0,124, + 1,100,5,64,0,100,8,20,0,100,9,100,9,100,9,102, + 9,161,1,83,0,41,10,78,233,9,0,0,0,105,188,7, + 0,0,233,5,0,0,0,233,15,0,0,0,233,31,0,0, + 0,233,11,0,0,0,233,63,0,0,0,114,93,0,0,0, + 114,14,0,0,0,41,2,114,137,0,0,0,90,6,109,107, + 116,105,109,101,41,2,218,1,100,114,144,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,218,14,95, + 112,97,114,115,101,95,100,111,115,116,105,109,101,181,2,0, + 0,115,18,0,0,0,4,1,10,1,10,1,6,1,6,1, + 10,1,10,1,6,1,6,249,114,175,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,6,0,0,0,10,0, + 0,0,67,0,0,0,115,110,0,0,0,122,41,124,1,100, + 1,100,0,133,2,25,0,100,2,118,0,115,11,74,0,130, + 1,124,1,100,0,100,1,133,2,25,0,125,1,124,0,106, + 0,124,1,25,0,125,2,124,2,100,3,25,0,125,3,124, + 2,100,4,25,0,125,4,124,2,100,5,25,0,125,5,116, + 1,124,4,124,3,131,2,124,5,102,2,87,0,83,0,4, + 0,116,2,116,3,116,4,102,3,121,54,1,0,1,0,1, + 0,89,0,100,6,83,0,119,0,41,7,78,114,14,0,0, + 0,169,2,218,1,99,218,1,111,114,169,0,0,0,233,6, + 0,0,0,233,3,0,0,0,41,2,114,0,0,0,0,114, + 0,0,0,0,41,5,114,28,0,0,0,114,175,0,0,0, + 114,26,0,0,0,218,10,73,110,100,101,120,69,114,114,111, + 114,114,160,0,0,0,41,6,114,32,0,0,0,114,13,0, + 0,0,114,61,0,0,0,114,137,0,0,0,114,138,0,0, + 0,90,17,117,110,99,111,109,112,114,101,115,115,101,100,95, + 115,105,122,101,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,114,157,0,0,0,194,2,0,0,115,22,0,0, + 0,2,1,20,2,12,1,10,1,8,3,8,1,8,1,16, + 1,18,1,6,1,2,255,114,157,0,0,0,99,2,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,8,0,0, + 0,67,0,0,0,115,80,0,0,0,124,1,100,1,100,0, + 133,2,25,0,100,2,118,0,115,10,74,0,130,1,124,1, + 100,0,100,1,133,2,25,0,125,1,122,7,124,0,106,0, + 124,1,25,0,125,2,87,0,110,10,4,0,116,1,121,33, + 1,0,1,0,1,0,89,0,100,0,83,0,119,0,116,2, + 124,0,106,3,124,2,131,2,83,0,41,3,78,114,14,0, + 0,0,114,176,0,0,0,41,4,114,28,0,0,0,114,26, + 0,0,0,114,59,0,0,0,114,29,0,0,0,41,3,114, + 32,0,0,0,114,13,0,0,0,114,61,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,114,155,0, + 0,0,213,2,0,0,115,16,0,0,0,20,2,12,1,2, + 2,14,1,12,1,6,1,2,255,12,3,114,155,0,0,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,14,0,0, + 0,11,0,0,0,67,0,0,0,115,14,1,0,0,116,0, + 124,0,124,1,131,2,125,2,100,0,125,3,116,1,68,0, + 93,102,92,3,125,4,125,5,125,6,124,2,124,4,23,0, + 125,7,116,2,106,3,100,1,124,0,106,4,116,5,124,7, + 100,2,100,3,141,5,1,0,122,7,124,0,106,6,124,7, + 25,0,125,8,87,0,110,9,4,0,116,7,121,45,1,0, + 1,0,1,0,89,0,113,9,119,0,124,8,100,4,25,0, + 125,9,116,8,124,0,106,4,124,8,131,2,125,10,100,0, + 125,11,124,5,114,91,122,10,116,9,124,0,124,9,124,7, + 124,1,124,10,131,5,125,11,87,0,110,25,4,0,116,10, + 121,90,1,0,125,12,1,0,122,8,124,12,125,3,87,0, + 89,0,100,0,125,12,126,12,110,10,100,0,125,12,126,12, + 119,1,119,0,116,11,124,9,124,10,131,2,125,11,124,11, + 100,0,117,0,114,101,113,9,124,8,100,4,25,0,125,9, + 124,11,124,6,124,9,102,3,2,0,1,0,83,0,124,3, + 114,126,100,5,124,3,155,0,157,2,125,13,116,12,124,13, + 124,1,100,6,141,2,124,3,130,2,116,12,100,7,124,1, + 155,2,157,2,124,1,100,6,141,2,130,1,41,8,78,122, + 13,116,114,121,105,110,103,32,123,125,123,125,123,125,114,93, + 0,0,0,41,1,90,9,118,101,114,98,111,115,105,116,121, + 114,0,0,0,0,122,20,109,111,100,117,108,101,32,108,111, + 97,100,32,102,97,105,108,101,100,58,32,114,65,0,0,0, + 114,64,0,0,0,41,13,114,39,0,0,0,114,95,0,0, + 0,114,48,0,0,0,114,81,0,0,0,114,29,0,0,0, + 114,20,0,0,0,114,28,0,0,0,114,26,0,0,0,114, + 59,0,0,0,114,161,0,0,0,114,80,0,0,0,114,167, + 0,0,0,114,3,0,0,0,41,14,114,32,0,0,0,114, + 41,0,0,0,114,13,0,0,0,90,12,105,109,112,111,114, + 116,95,101,114,114,111,114,114,96,0,0,0,114,97,0,0, + 0,114,54,0,0,0,114,69,0,0,0,114,61,0,0,0, + 114,43,0,0,0,114,132,0,0,0,114,53,0,0,0,90, + 3,101,120,99,114,82,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,114,51,0,0,0,228,2,0, + 0,115,58,0,0,0,10,1,4,1,14,1,8,1,22,1, + 2,1,14,1,12,1,4,1,2,255,8,3,12,1,4,1, + 4,1,2,1,20,1,14,1,16,1,8,128,2,255,10,3, + 8,1,2,3,8,1,14,1,4,2,10,1,14,1,18,2, + 114,51,0,0,0,41,46,114,91,0,0,0,90,26,95,102, + 114,111,122,101,110,95,105,109,112,111,114,116,108,105,98,95, + 101,120,116,101,114,110,97,108,114,21,0,0,0,114,1,0, + 0,0,114,2,0,0,0,90,17,95,102,114,111,122,101,110, + 95,105,109,112,111,114,116,108,105,98,114,48,0,0,0,114, + 154,0,0,0,114,116,0,0,0,114,158,0,0,0,114,72, + 0,0,0,114,137,0,0,0,114,35,0,0,0,90,7,95, + 95,97,108,108,95,95,114,20,0,0,0,90,15,112,97,116, + 104,95,115,101,112,97,114,97,116,111,114,115,114,18,0,0, + 0,114,80,0,0,0,114,3,0,0,0,114,25,0,0,0, + 218,4,116,121,112,101,114,75,0,0,0,114,119,0,0,0, + 114,121,0,0,0,114,123,0,0,0,90,13,95,76,111,97, + 100,101,114,66,97,115,105,99,115,114,4,0,0,0,114,95, + 0,0,0,114,39,0,0,0,114,40,0,0,0,114,38,0, + 0,0,114,27,0,0,0,114,128,0,0,0,114,148,0,0, + 0,114,150,0,0,0,114,59,0,0,0,114,153,0,0,0, + 114,161,0,0,0,218,8,95,95,99,111,100,101,95,95,114, + 159,0,0,0,114,165,0,0,0,114,167,0,0,0,114,175, + 0,0,0,114,157,0,0,0,114,155,0,0,0,114,51,0, + 0,0,114,9,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,8,60,109,111,100,117,108,101,62, + 1,0,0,0,115,90,0,0,0,4,0,8,16,16,1,8, + 1,8,1,8,1,8,1,8,1,8,1,8,1,8,2,6, + 3,14,1,16,3,4,4,8,2,4,2,4,1,4,1,18, + 2,0,127,0,127,12,50,12,1,2,1,2,1,4,252,8, + 9,8,4,8,9,8,31,2,126,2,254,4,29,8,5,8, + 21,8,46,8,8,10,40,8,5,8,7,8,6,8,13,8, + 19,12,15, }; diff --git a/contrib/tools/python3/src/Python/initconfig.c b/contrib/tools/python3/src/Python/initconfig.c index 9c109cef2c1..86472c0ff8f 100644 --- a/contrib/tools/python3/src/Python/initconfig.c +++ b/contrib/tools/python3/src/Python/initconfig.c @@ -11,11 +11,7 @@ #include "osdefs.h" // DELIM #include // setlocale() -#ifdef HAVE_LANGINFO_H -# include // nl_langinfo(CODESET) -#endif #if defined(MS_WINDOWS) || defined(__CYGWIN__) -# include // GetACP() # ifdef HAVE_IO_H # include # endif @@ -73,7 +69,6 @@ static const char usage_3[] = "\ -X opt : set implementation-specific option. The following options are available:\n\ \n\ -X faulthandler: enable faulthandler\n\ - -X oldparser: enable the traditional LL(1) parser; also PYTHONOLDPARSER\n\ -X showrefcount: output the total reference count and number of used\n\ memory blocks when the program finishes or after each statement in the\n\ interactive interpreter. This only works on debug builds\n\ @@ -99,6 +94,7 @@ static const char usage_3[] = "\ otherwise activate automatically)\n\ -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ given directory instead of to the code tree\n\ + -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\ \n\ --check-hash-based-pycs always|default|never:\n\ control how Python invalidates hash-based .pyc files\n\ @@ -134,7 +130,8 @@ static const char usage_6[] = "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n" " debugger. It can be set to the callable of your debugger of choice.\n" "PYTHONDEVMODE: enable the development mode.\n" -"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n"; +"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n" +"PYTHONWARNDEFAULTENCODING: enable opt-in EncodingWarning for 'encoding=None'.\n"; #if defined(MS_WINDOWS) # define PYTHONHOMEHELP "\\python{major}{minor}" @@ -248,8 +245,9 @@ PyStatus PyStatus_Ok(void) PyStatus PyStatus_Error(const char *err_msg) { + assert(err_msg != NULL); return (PyStatus){._type = _PyStatus_TYPE_ERROR, - .err_msg = err_msg}; + .err_msg = err_msg}; } PyStatus PyStatus_NoMemory(void) @@ -268,6 +266,23 @@ int PyStatus_IsExit(PyStatus status) int PyStatus_Exception(PyStatus status) { return _PyStatus_EXCEPTION(status); } +PyObject* +_PyErr_SetFromPyStatus(PyStatus status) +{ + if (!_PyStatus_IS_ERROR(status)) { + PyErr_Format(PyExc_SystemError, + "%s() expects an error PyStatus", + _PyStatus_GET_FUNC()); + } + else if (status.func) { + PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg); + } + else { + PyErr_Format(PyExc_ValueError, "%s", status.err_msg); + } + return NULL; +} + /* --- PyWideStringList ------------------------------------------------ */ @@ -549,6 +564,7 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) } +// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv. void Py_GetArgcArgv(int *argc, wchar_t ***argv) { @@ -570,6 +586,66 @@ Py_InitArgcArgv(int argc, wchar_t **argv) ? _PyStatus_ERR("cannot decode " NAME) \ : _PyStatus_NO_MEMORY()) +#define MAX_HASH_SEED 4294967295UL + + +#ifndef NDEBUG +static int +config_check_consistency(const PyConfig *config) +{ + /* Check config consistency */ + assert(config->isolated >= 0); + assert(config->use_environment >= 0); + assert(config->dev_mode >= 0); + assert(config->install_signal_handlers >= 0); + assert(config->use_hash_seed >= 0); + assert(config->hash_seed <= MAX_HASH_SEED); + assert(config->faulthandler >= 0); + assert(config->tracemalloc >= 0); + assert(config->import_time >= 0); + assert(config->show_ref_count >= 0); + assert(config->dump_refs >= 0); + assert(config->malloc_stats >= 0); + assert(config->site_import >= 0); + assert(config->bytes_warning >= 0); + assert(config->warn_default_encoding >= 0); + assert(config->inspect >= 0); + assert(config->interactive >= 0); + assert(config->optimization_level >= 0); + assert(config->parser_debug >= 0); + assert(config->write_bytecode >= 0); + assert(config->verbose >= 0); + assert(config->quiet >= 0); + assert(config->user_site_directory >= 0); + assert(config->parse_argv >= 0); + assert(config->configure_c_stdio >= 0); + assert(config->buffered_stdio >= 0); + assert(config->program_name != NULL); + assert(_PyWideStringList_CheckConsistency(&config->orig_argv)); + assert(_PyWideStringList_CheckConsistency(&config->argv)); + /* sys.argv must be non-empty: empty argv is replaced with [''] */ + assert(config->argv.length >= 1); + assert(_PyWideStringList_CheckConsistency(&config->xoptions)); + assert(_PyWideStringList_CheckConsistency(&config->warnoptions)); + assert(_PyWideStringList_CheckConsistency(&config->module_search_paths)); + assert(config->module_search_paths_set >= 0); + assert(config->platlibdir != NULL); + assert(config->filesystem_encoding != NULL); + assert(config->filesystem_errors != NULL); + assert(config->stdio_encoding != NULL); + assert(config->stdio_errors != NULL); +#ifdef MS_WINDOWS + assert(config->legacy_windows_stdio >= 0); +#endif + /* -c and -m options are exclusive */ + assert(!(config->run_command != NULL && config->run_module != NULL)); + assert(config->check_hash_pycs_mode != NULL); + assert(config->_install_importlib >= 0); + assert(config->pathconfig_warnings >= 0); + return 1; +} +#endif + /* Free memory allocated in config, but don't clear all attributes */ void @@ -609,7 +685,7 @@ PyConfig_Clear(PyConfig *config) CLEAR(config->run_filename); CLEAR(config->check_hash_pycs_mode); - _PyWideStringList_Clear(&config->_orig_argv); + _PyWideStringList_Clear(&config->orig_argv); #undef CLEAR } @@ -631,6 +707,7 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->parse_argv = 0; config->site_import = -1; config->bytes_warning = -1; + config->warn_default_encoding = 0; config->inspect = -1; config->interactive = -1; config->optimization_level = -1; @@ -649,7 +726,6 @@ _PyConfig_InitCompatConfig(PyConfig *config) #ifdef MS_WINDOWS config->legacy_windows_stdio = -1; #endif - config->_use_peg_parser = 1; } @@ -775,7 +851,7 @@ config_set_bytes_string(PyConfig *config, wchar_t **config_str, configured. */ PyStatus PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str, - const char *str) + const char *str) { return CONFIG_SET_BYTES_STR(config, config_str, str, "string"); } @@ -807,7 +883,6 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(isolated); COPY_ATTR(use_environment); COPY_ATTR(dev_mode); - COPY_ATTR(_use_peg_parser); COPY_ATTR(install_signal_handlers); COPY_ATTR(use_hash_seed); COPY_ATTR(hash_seed); @@ -841,6 +916,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(site_import); COPY_ATTR(bytes_warning); + COPY_ATTR(warn_default_encoding); COPY_ATTR(inspect); COPY_ATTR(interactive); COPY_ATTR(optimization_level); @@ -866,7 +942,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(pathconfig_warnings); COPY_ATTR(_init_main); COPY_ATTR(_isolated_interpreter); - COPY_WSTRLIST(_orig_argv); + COPY_WSTRLIST(orig_argv); #undef COPY_ATTR #undef COPY_WSTR_ATTR @@ -875,12 +951,10 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) } -static PyObject * -config_as_dict(const PyConfig *config) +PyObject * +_PyConfig_AsDict(const PyConfig *config) { - PyObject *dict; - - dict = PyDict_New(); + PyObject *dict = PyDict_New(); if (dict == NULL) { return NULL; } @@ -914,7 +988,6 @@ config_as_dict(const PyConfig *config) SET_ITEM_INT(isolated); SET_ITEM_INT(use_environment); SET_ITEM_INT(dev_mode); - SET_ITEM_INT(_use_peg_parser); SET_ITEM_INT(install_signal_handlers); SET_ITEM_INT(use_hash_seed); SET_ITEM_UINT(hash_seed); @@ -934,6 +1007,7 @@ config_as_dict(const PyConfig *config) SET_ITEM_WSTRLIST(warnoptions); SET_ITEM_WSTR(pythonpath_env); SET_ITEM_WSTR(home); + SET_ITEM_INT(module_search_paths_set); SET_ITEM_WSTRLIST(module_search_paths); SET_ITEM_WSTR(executable); SET_ITEM_WSTR(base_executable); @@ -944,6 +1018,7 @@ config_as_dict(const PyConfig *config) SET_ITEM_WSTR(platlibdir); SET_ITEM_INT(site_import); SET_ITEM_INT(bytes_warning); + SET_ITEM_INT(warn_default_encoding); SET_ITEM_INT(inspect); SET_ITEM_INT(interactive); SET_ITEM_INT(optimization_level); @@ -968,7 +1043,7 @@ config_as_dict(const PyConfig *config) SET_ITEM_INT(pathconfig_warnings); SET_ITEM_INT(_init_main); SET_ITEM_INT(_isolated_interpreter); - SET_ITEM_WSTRLIST(_orig_argv); + SET_ITEM_WSTRLIST(orig_argv); return dict; @@ -985,6 +1060,280 @@ fail: } +static PyObject* +config_dict_get(PyObject *dict, const char *name) +{ + PyObject *item = _PyDict_GetItemStringWithError(dict, name); + if (item == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, "missing config key: %s", name); + return NULL; + } + return item; +} + + +static void +config_dict_invalid_value(const char *name) +{ + PyErr_Format(PyExc_ValueError, "invalid config value: %s", name); +} + + +static void +config_dict_invalid_type(const char *name) +{ + PyErr_Format(PyExc_TypeError, "invalid config type: %s", name); +} + + +static int +config_dict_get_int(PyObject *dict, const char *name, int *result) +{ + PyObject *item = config_dict_get(dict, name); + if (item == NULL) { + return -1; + } + int value = _PyLong_AsInt(item); + if (value == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + config_dict_invalid_type(name); + } + else if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + config_dict_invalid_value(name); + } + return -1; + } + *result = value; + return 0; +} + + +static int +config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result) +{ + PyObject *item = config_dict_get(dict, name); + if (item == NULL) { + return -1; + } + unsigned long value = PyLong_AsUnsignedLong(item); + if (value == (unsigned long)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + config_dict_invalid_type(name); + } + else if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + config_dict_invalid_value(name); + } + return -1; + } + *result = value; + return 0; +} + + +static int +config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config, + wchar_t **result) +{ + PyObject *item = config_dict_get(dict, name); + if (item == NULL) { + return -1; + } + PyStatus status; + if (item == Py_None) { + status = PyConfig_SetString(config, result, NULL); + } + else if (!PyUnicode_Check(item)) { + config_dict_invalid_type(name); + return -1; + } + else { + wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL); + if (wstr == NULL) { + return -1; + } + status = PyConfig_SetString(config, result, wstr); + PyMem_Free(wstr); + } + if (_PyStatus_EXCEPTION(status)) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + + +static int +config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config, + PyWideStringList *result) +{ + PyObject *list = config_dict_get(dict, name); + if (list == NULL) { + return -1; + } + + if (!PyList_CheckExact(list)) { + config_dict_invalid_type(name); + return -1; + } + + PyWideStringList wstrlist = _PyWideStringList_INIT; + for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) { + PyObject *item = PyList_GET_ITEM(list, i); + + if (item == Py_None) { + config_dict_invalid_value(name); + goto error; + } + else if (!PyUnicode_Check(item)) { + config_dict_invalid_type(name); + goto error; + } + wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL); + if (wstr == NULL) { + goto error; + } + PyStatus status = PyWideStringList_Append(&wstrlist, wstr); + PyMem_Free(wstr); + if (_PyStatus_EXCEPTION(status)) { + PyErr_NoMemory(); + goto error; + } + } + + if (_PyWideStringList_Copy(result, &wstrlist) < 0) { + PyErr_NoMemory(); + goto error; + } + _PyWideStringList_Clear(&wstrlist); + return 0; + +error: + _PyWideStringList_Clear(&wstrlist); + return -1; +} + + +int +_PyConfig_FromDict(PyConfig *config, PyObject *dict) +{ + if (!PyDict_Check(dict)) { + PyErr_SetString(PyExc_TypeError, "dict expected"); + return -1; + } + +#define CHECK_VALUE(NAME, TEST) \ + if (!(TEST)) { \ + config_dict_invalid_value(NAME); \ + return -1; \ + } +#define GET_UINT(KEY) \ + do { \ + if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \ + return -1; \ + } \ + CHECK_VALUE(#KEY, config->KEY >= 0); \ + } while (0) +#define GET_WSTR(KEY) \ + do { \ + if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ + return -1; \ + } \ + CHECK_VALUE(#KEY, config->KEY != NULL); \ + } while (0) +#define GET_WSTR_OPT(KEY) \ + do { \ + if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ + return -1; \ + } \ + } while (0) +#define GET_WSTRLIST(KEY) \ + do { \ + if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \ + return -1; \ + } \ + } while (0) + + GET_UINT(_config_init); + CHECK_VALUE("_config_init", + config->_config_init == _PyConfig_INIT_COMPAT + || config->_config_init == _PyConfig_INIT_PYTHON + || config->_config_init == _PyConfig_INIT_ISOLATED); + GET_UINT(isolated); + GET_UINT(use_environment); + GET_UINT(dev_mode); + GET_UINT(install_signal_handlers); + GET_UINT(use_hash_seed); + if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) { + return -1; + } + CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED); + GET_UINT(faulthandler); + GET_UINT(tracemalloc); + GET_UINT(import_time); + GET_UINT(show_ref_count); + GET_UINT(dump_refs); + GET_UINT(malloc_stats); + GET_WSTR(filesystem_encoding); + GET_WSTR(filesystem_errors); + GET_WSTR_OPT(pycache_prefix); + GET_UINT(parse_argv); + GET_WSTRLIST(orig_argv); + GET_WSTRLIST(argv); + GET_WSTRLIST(xoptions); + GET_WSTRLIST(warnoptions); + GET_UINT(site_import); + GET_UINT(bytes_warning); + GET_UINT(warn_default_encoding); + GET_UINT(inspect); + GET_UINT(interactive); + GET_UINT(optimization_level); + GET_UINT(parser_debug); + GET_UINT(write_bytecode); + GET_UINT(verbose); + GET_UINT(quiet); + GET_UINT(user_site_directory); + GET_UINT(configure_c_stdio); + GET_UINT(buffered_stdio); + GET_WSTR(stdio_encoding); + GET_WSTR(stdio_errors); +#ifdef MS_WINDOWS + GET_UINT(legacy_windows_stdio); +#endif + GET_WSTR(check_hash_pycs_mode); + + GET_UINT(pathconfig_warnings); + GET_WSTR(program_name); + GET_WSTR_OPT(pythonpath_env); + GET_WSTR_OPT(home); + GET_WSTR(platlibdir); + + // Path configuration output + GET_UINT(module_search_paths_set); + GET_WSTRLIST(module_search_paths); + GET_WSTR_OPT(executable); + GET_WSTR_OPT(base_executable); + GET_WSTR_OPT(prefix); + GET_WSTR_OPT(base_prefix); + GET_WSTR_OPT(exec_prefix); + GET_WSTR_OPT(base_exec_prefix); + + GET_UINT(skip_source_first_line); + GET_WSTR_OPT(run_command); + GET_WSTR_OPT(run_module); + GET_WSTR_OPT(run_filename); + + GET_UINT(_install_importlib); + GET_UINT(_init_main); + GET_UINT(_isolated_interpreter); + +#undef CHECK_VALUE +#undef GET_UINT +#undef GET_WSTR +#undef GET_WSTR_OPT + return 0; +} + + static const char* config_get_env(const PyConfig *config, const char *name) { @@ -1252,7 +1601,6 @@ config_init_home(PyConfig *config) L"PYTHONHOME", "PYTHONHOME"); } - static PyStatus config_init_hash_seed(PyConfig *config) { @@ -1266,7 +1614,7 @@ config_init_hash_seed(PyConfig *config) errno = 0; seed = strtoul(seed_text, (char **)&endptr, 10); if (*endptr != '\0' - || seed > 4294967295UL + || seed > MAX_HASH_SEED || (errno == ERANGE && seed == ULONG_MAX)) { return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" " @@ -1335,7 +1683,7 @@ config_read_env_vars(PyConfig *config) #ifdef MS_WINDOWS _Py_get_env_flag(use_env, &config->legacy_windows_stdio, - "PYTHONLEGACYWINDOWSSTDIO"); + "PYTHONLEGACYWINDOWSSTDIO"); #endif if (config_get_env(config, "PYTHONDUMPREFS")) { @@ -1460,11 +1808,6 @@ config_read_complex_options(PyConfig *config) config->import_time = 1; } - if (config_get_env(config, "PYTHONOLDPARSER") - || config_get_xoption(config, L"oldparser")) { - config->_use_peg_parser = 0; - } - PyStatus status; if (config->tracemalloc < 0) { status = config_init_tracemalloc(config); @@ -1484,8 +1827,13 @@ config_read_complex_options(PyConfig *config) static const wchar_t * -config_get_stdio_errors(void) +config_get_stdio_errors(const PyPreConfig *preconfig) { + if (preconfig->utf8_mode) { + /* UTF-8 Mode uses UTF-8/surrogateescape */ + return L"surrogateescape"; + } + #ifndef MS_WINDOWS const char *loc = setlocale(LC_CTYPE, NULL); if (loc != NULL) { @@ -1510,26 +1858,18 @@ config_get_stdio_errors(void) } +// See also config_get_fs_encoding() static PyStatus -config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding) +config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig, + wchar_t **locale_encoding) { -#ifdef MS_WINDOWS - char encoding[20]; - PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); - return PyConfig_SetBytesString(config, locale_encoding, encoding); -#elif defined(_Py_FORCE_UTF8_LOCALE) - return PyConfig_SetString(config, locale_encoding, L"utf-8"); -#else - const char *encoding = nl_langinfo(CODESET); - if (!encoding || encoding[0] == '\0') { - return _PyStatus_ERR("failed to get the locale encoding: " - "nl_langinfo(CODESET) failed"); - } - /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */ - return CONFIG_SET_BYTES_STR(config, - locale_encoding, encoding, - "nl_langinfo(CODESET)"); -#endif + wchar_t *encoding = _Py_GetLocaleEncoding(); + if (encoding == NULL) { + return _PyStatus_NO_MEMORY(); + } + PyStatus status = PyConfig_SetString(config, locale_encoding, encoding); + PyMem_RawFree(encoding); + return status; } @@ -1539,8 +1879,8 @@ config_init_stdio_encoding(PyConfig *config, { PyStatus status; - /* If Py_SetStandardStreamEncoding() have been called, use these - parameters. */ + /* If Py_SetStandardStreamEncoding() has been called, use its + arguments if they are not NULL. */ if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding, _Py_StandardStreamEncoding, @@ -1559,6 +1899,7 @@ config_init_stdio_encoding(PyConfig *config, } } + // Exit if encoding and errors are defined if (config->stdio_encoding != NULL && config->stdio_errors != NULL) { return _PyStatus_OK(); } @@ -1614,33 +1955,16 @@ config_init_stdio_encoding(PyConfig *config, PyMem_RawFree(pythonioencoding); } - /* UTF-8 Mode uses UTF-8/surrogateescape */ - if (preconfig->utf8_mode) { - if (config->stdio_encoding == NULL) { - status = PyConfig_SetString(config, &config->stdio_encoding, - L"utf-8"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - if (config->stdio_errors == NULL) { - status = PyConfig_SetString(config, &config->stdio_errors, - L"surrogateescape"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - } - /* Choose the default error handler based on the current locale. */ if (config->stdio_encoding == NULL) { - status = config_get_locale_encoding(config, &config->stdio_encoding); + status = config_get_locale_encoding(config, preconfig, + &config->stdio_encoding); if (_PyStatus_EXCEPTION(status)) { return status; } } if (config->stdio_errors == NULL) { - const wchar_t *errors = config_get_stdio_errors(); + const wchar_t *errors = config_get_stdio_errors(preconfig); assert(errors != NULL); status = PyConfig_SetString(config, &config->stdio_errors, errors); @@ -1653,46 +1977,46 @@ config_init_stdio_encoding(PyConfig *config, } +// See also config_get_locale_encoding() +static PyStatus +config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig, + wchar_t **fs_encoding) +{ +#ifdef _Py_FORCE_UTF8_FS_ENCODING + return PyConfig_SetString(config, fs_encoding, L"utf-8"); +#elif defined(MS_WINDOWS) + const wchar_t *encoding; + if (preconfig->legacy_windows_fs_encoding) { + // Legacy Windows filesystem encoding: mbcs/replace + encoding = L"mbcs"; + } + else { + // Windows defaults to utf-8/surrogatepass (PEP 529) + encoding = L"utf-8"; + } + return PyConfig_SetString(config, fs_encoding, encoding); +#else // !MS_WINDOWS + if (preconfig->utf8_mode) { + return PyConfig_SetString(config, fs_encoding, L"utf-8"); + } + + if (_Py_GetForceASCII()) { + return PyConfig_SetString(config, fs_encoding, L"ascii"); + } + + return config_get_locale_encoding(config, preconfig, fs_encoding); +#endif // !MS_WINDOWS +} + + static PyStatus config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig) { PyStatus status; if (config->filesystem_encoding == NULL) { -#ifdef _Py_FORCE_UTF8_FS_ENCODING - status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8"); -#else - -#ifdef MS_WINDOWS - if (preconfig->legacy_windows_fs_encoding) { - /* Legacy Windows filesystem encoding: mbcs/replace */ - status = PyConfig_SetString(config, &config->filesystem_encoding, - L"mbcs"); - } - else -#endif - if (preconfig->utf8_mode) { - status = PyConfig_SetString(config, &config->filesystem_encoding, - L"utf-8"); - } -#ifndef MS_WINDOWS - else if (_Py_GetForceASCII()) { - status = PyConfig_SetString(config, &config->filesystem_encoding, - L"ascii"); - } -#endif - else { -#ifdef MS_WINDOWS - /* Windows defaults to utf-8/surrogatepass (PEP 529). */ - status = PyConfig_SetString(config, &config->filesystem_encoding, - L"utf-8"); -#else - status = config_get_locale_encoding(config, - &config->filesystem_encoding); -#endif - } -#endif /* !_Py_FORCE_UTF8_FS_ENCODING */ - + status = config_get_fs_encoding(config, preconfig, + &config->filesystem_encoding); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1720,7 +2044,7 @@ config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig) static PyStatus -config_read(PyConfig *config) +config_read(PyConfig *config, int compute_path_config) { PyStatus status; const PyPreConfig *preconfig = &_PyRuntime.preconfig; @@ -1765,7 +2089,7 @@ config_read(PyConfig *config) } if (config->_install_importlib) { - status = _PyConfig_InitPathConfig(config); + status = _PyConfig_InitPathConfig(config, compute_path_config); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1820,6 +2144,11 @@ config_read(PyConfig *config) config->configure_c_stdio = 1; } + // Only parse arguments once. + if (config->parse_argv == 1) { + config->parse_argv = 2; + } + return _PyStatus_OK(); } @@ -1880,8 +2209,8 @@ _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime) preconfig->use_environment = config->use_environment; preconfig->dev_mode = config->dev_mode; - if (_Py_SetArgcArgv(config->_orig_argv.length, - config->_orig_argv.items) < 0) + if (_Py_SetArgcArgv(config->orig_argv.length, + config->orig_argv.items) < 0) { return _PyStatus_NO_MEMORY(); } @@ -2310,7 +2639,7 @@ core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline) { PyStatus status; - if (config->parse_argv) { + if (config->parse_argv == 1) { if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) { return _PyStatus_NO_MEMORY(); } @@ -2388,7 +2717,7 @@ config_read_cmdline(PyConfig *config) } } - if (config->parse_argv) { + if (config->parse_argv == 1) { Py_ssize_t opt_index; status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index); if (_PyStatus_EXCEPTION(status)) { @@ -2506,7 +2835,7 @@ PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, The only side effects are to modify config and to call _Py_SetArgcArgv(). */ PyStatus -PyConfig_Read(PyConfig *config) +_PyConfig_Read(PyConfig *config, int compute_path_config) { PyStatus status; @@ -2517,11 +2846,11 @@ PyConfig_Read(PyConfig *config) config_get_global_vars(config); - if (config->_orig_argv.length == 0 + if (config->orig_argv.length == 0 && !(config->argv.length == 1 && wcscmp(config->argv.items[0], L"") == 0)) { - if (_PyWideStringList_Copy(&config->_orig_argv, &config->argv) < 0) { + if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) { return _PyStatus_NO_MEMORY(); } } @@ -2549,64 +2878,12 @@ PyConfig_Read(PyConfig *config) goto done; } - status = config_read(config); + status = config_read(config, compute_path_config); if (_PyStatus_EXCEPTION(status)) { goto done; } - /* Check config consistency */ - assert(config->isolated >= 0); - assert(config->use_environment >= 0); - assert(config->dev_mode >= 0); - assert(config->_use_peg_parser >= 0); - assert(config->install_signal_handlers >= 0); - assert(config->use_hash_seed >= 0); - assert(config->faulthandler >= 0); - assert(config->tracemalloc >= 0); - assert(config->site_import >= 0); - assert(config->bytes_warning >= 0); - assert(config->inspect >= 0); - assert(config->interactive >= 0); - assert(config->optimization_level >= 0); - assert(config->parser_debug >= 0); - assert(config->write_bytecode >= 0); - assert(config->verbose >= 0); - assert(config->quiet >= 0); - assert(config->user_site_directory >= 0); - assert(config->parse_argv >= 0); - assert(config->configure_c_stdio >= 0); - assert(config->buffered_stdio >= 0); - assert(config->program_name != NULL); - assert(_PyWideStringList_CheckConsistency(&config->argv)); - /* sys.argv must be non-empty: empty argv is replaced with [''] */ - assert(config->argv.length >= 1); - assert(_PyWideStringList_CheckConsistency(&config->xoptions)); - assert(_PyWideStringList_CheckConsistency(&config->warnoptions)); - assert(_PyWideStringList_CheckConsistency(&config->module_search_paths)); - if (config->_install_importlib) { - assert(config->module_search_paths_set != 0); - /* don't check config->module_search_paths */ - assert(config->executable != NULL); - assert(config->base_executable != NULL); - assert(config->prefix != NULL); - assert(config->base_prefix != NULL); - assert(config->exec_prefix != NULL); - assert(config->base_exec_prefix != NULL); - } - assert(config->platlibdir != NULL); - assert(config->filesystem_encoding != NULL); - assert(config->filesystem_errors != NULL); - assert(config->stdio_encoding != NULL); - assert(config->stdio_errors != NULL); -#ifdef MS_WINDOWS - assert(config->legacy_windows_stdio >= 0); -#endif - /* -c and -m options are exclusive */ - assert(!(config->run_command != NULL && config->run_module != NULL)); - assert(config->check_hash_pycs_mode != NULL); - assert(config->_install_importlib >= 0); - assert(config->pathconfig_warnings >= 0); - assert(_PyWideStringList_CheckConsistency(&config->_orig_argv)); + assert(config_check_consistency(config)); status = _PyStatus_OK(); @@ -2616,6 +2893,13 @@ done: } +PyStatus +PyConfig_Read(PyConfig *config) +{ + return _PyConfig_Read(config, 1); +} + + PyObject* _Py_GetConfigsAsDict(void) { @@ -2638,8 +2922,8 @@ _Py_GetConfigsAsDict(void) Py_CLEAR(dict); /* pre config */ - PyThreadState *tstate = _PyThreadState_GET(); - const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig; + PyInterpreterState *interp = _PyInterpreterState_GET(); + const PyPreConfig *pre_config = &interp->runtime->preconfig; dict = _PyPreConfig_AsDict(pre_config); if (dict == NULL) { goto error; @@ -2650,8 +2934,8 @@ _Py_GetConfigsAsDict(void) Py_CLEAR(dict); /* core config */ - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); - dict = config_as_dict(config); + const PyConfig *config = _PyInterpreterState_GetConfig(interp); + dict = _PyConfig_AsDict(config); if (dict == NULL) { goto error; } @@ -2660,6 +2944,16 @@ _Py_GetConfigsAsDict(void) } Py_CLEAR(dict); + /* path config */ + dict = _PyPathConfig_AsDict(); + if (dict == NULL) { + goto error; + } + if (PyDict_SetItemString(result, "path_config", dict) < 0) { + goto error; + } + Py_CLEAR(dict); + return result; error: diff --git a/contrib/tools/python3/src/Python/marshal.c b/contrib/tools/python3/src/Python/marshal.c index baafa3ecfbf..41252406060 100644 --- a/contrib/tools/python3/src/Python/marshal.c +++ b/contrib/tools/python3/src/Python/marshal.c @@ -524,7 +524,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) w_object(co->co_filename, p); w_object(co->co_name, p); w_long(co->co_firstlineno, p); - w_object(co->co_lnotab, p); + w_object(co->co_linetable, p); } else if (PyObject_CheckBuffer(v)) { /* Write unknown bytes-like objects as a bytes object */ @@ -642,7 +642,7 @@ r_string(Py_ssize_t n, RFILE *p) return res; } if (p->buf == NULL) { - p->buf = PyMem_MALLOC(n); + p->buf = PyMem_Malloc(n); if (p->buf == NULL) { PyErr_NoMemory(); return NULL; @@ -650,7 +650,7 @@ r_string(Py_ssize_t n, RFILE *p) p->buf_size = n; } else if (p->buf_size < n) { - char *tmp = PyMem_REALLOC(p->buf, n); + char *tmp = PyMem_Realloc(p->buf, n); if (tmp == NULL) { PyErr_NoMemory(); return NULL; @@ -1316,7 +1316,7 @@ r_object(RFILE *p) PyObject *filename = NULL; PyObject *name = NULL; int firstlineno; - PyObject *lnotab = NULL; + PyObject *linetable = NULL; idx = r_ref_reserve(flag, p); if (idx < 0) @@ -1371,8 +1371,8 @@ r_object(RFILE *p) firstlineno = (int)r_long(p); if (firstlineno == -1 && PyErr_Occurred()) break; - lnotab = r_object(p); - if (lnotab == NULL) + linetable = r_object(p); + if (linetable == NULL) goto code_error; v = (PyObject *) PyCode_NewWithPosOnlyArgs( @@ -1380,7 +1380,7 @@ r_object(RFILE *p) nlocals, stacksize, flags, code, consts, names, varnames, freevars, cellvars, filename, name, - firstlineno, lnotab); + firstlineno, linetable); v = r_ref_insert(v, idx, flag, p); code_error: @@ -1392,7 +1392,7 @@ r_object(RFILE *p) Py_XDECREF(cellvars); Py_XDECREF(filename); Py_XDECREF(name); - Py_XDECREF(lnotab); + Py_XDECREF(linetable); } retval = v; break; @@ -1460,7 +1460,7 @@ PyMarshal_ReadShortFromFile(FILE *fp) rf.buf = NULL; res = r_short(&rf); if (rf.buf != NULL) - PyMem_FREE(rf.buf); + PyMem_Free(rf.buf); return res; } @@ -1475,7 +1475,7 @@ PyMarshal_ReadLongFromFile(FILE *fp) rf.buf = NULL; res = r_long(&rf); if (rf.buf != NULL) - PyMem_FREE(rf.buf); + PyMem_Free(rf.buf); return res; } @@ -1508,11 +1508,11 @@ PyMarshal_ReadLastObjectFromFile(FILE *fp) off_t filesize; filesize = getfilesize(fp); if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) { - char* pBuf = (char *)PyMem_MALLOC(filesize); + char* pBuf = (char *)PyMem_Malloc(filesize); if (pBuf != NULL) { size_t n = fread(pBuf, 1, (size_t)filesize, fp); PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n); - PyMem_FREE(pBuf); + PyMem_Free(pBuf); return v; } @@ -1541,7 +1541,7 @@ PyMarshal_ReadObjectFromFile(FILE *fp) result = read_object(&rf); Py_DECREF(rf.refs); if (rf.buf != NULL) - PyMem_FREE(rf.buf); + PyMem_Free(rf.buf); return result; } @@ -1562,7 +1562,7 @@ PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len) result = read_object(&rf); Py_DECREF(rf.refs); if (rf.buf != NULL) - PyMem_FREE(rf.buf); + PyMem_Free(rf.buf); return result; } @@ -1694,7 +1694,7 @@ marshal_load(PyObject *module, PyObject *file) result = read_object(&rf); Py_DECREF(rf.refs); if (rf.buf != NULL) - PyMem_FREE(rf.buf); + PyMem_Free(rf.buf); } else result = NULL; } @@ -1795,28 +1795,30 @@ dumps() -- marshal value as a bytes object\n\ loads() -- read value from a bytes-like object"); +static int +marshal_module_exec(PyObject *mod) +{ + if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot marshalmodule_slots[] = { + {Py_mod_exec, marshal_module_exec}, + {0, NULL} +}; static struct PyModuleDef marshalmodule = { PyModuleDef_HEAD_INIT, - "marshal", - module_doc, - 0, - marshal_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "marshal", + .m_doc = module_doc, + .m_methods = marshal_methods, + .m_slots = marshalmodule_slots, }; PyMODINIT_FUNC PyMarshal_Init(void) { - PyObject *mod = PyModule_Create(&marshalmodule); - if (mod == NULL) - return NULL; - if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { - Py_DECREF(mod); - return NULL; - } - return mod; + return PyModuleDef_Init(&marshalmodule); } diff --git a/contrib/tools/python3/src/Python/modsupport.c b/contrib/tools/python3/src/Python/modsupport.c index 13482c65083..8655daa1fc5 100644 --- a/contrib/tools/python3/src/Python/modsupport.c +++ b/contrib/tools/python3/src/Python/modsupport.c @@ -283,6 +283,13 @@ do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int static PyObject * do_mkvalue(const char **p_format, va_list *p_va, int flags) { +#define ERROR_NEED_PY_SSIZE_T_CLEAN \ + { \ + PyErr_SetString(PyExc_SystemError, \ + "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \ + return NULL; \ + } + for (;;) { switch (*(*p_format)++) { case '(': @@ -341,14 +348,12 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) Py_ssize_t n; if (**p_format == '#') { ++*p_format; - if (flags & FLAG_SIZE_T) + if (flags & FLAG_SIZE_T) { n = va_arg(*p_va, Py_ssize_t); + } else { n = va_arg(*p_va, int); - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { - return NULL; - } + ERROR_NEED_PY_SSIZE_T_CLEAN; } } else @@ -394,14 +399,12 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) Py_ssize_t n; if (**p_format == '#') { ++*p_format; - if (flags & FLAG_SIZE_T) + if (flags & FLAG_SIZE_T) { n = va_arg(*p_va, Py_ssize_t); + } else { n = va_arg(*p_va, int); - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { - return NULL; - } + ERROR_NEED_PY_SSIZE_T_CLEAN; } } else @@ -432,14 +435,12 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) Py_ssize_t n; if (**p_format == '#') { ++*p_format; - if (flags & FLAG_SIZE_T) + if (flags & FLAG_SIZE_T) { n = va_arg(*p_va, Py_ssize_t); + } else { n = va_arg(*p_va, int); - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { - return NULL; - } + ERROR_NEED_PY_SSIZE_T_CLEAN; } } else @@ -507,6 +508,8 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) } } + +#undef ERROR_NEED_PY_SSIZE_T_CLEAN } @@ -631,56 +634,70 @@ va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, int -PyModule_AddObject(PyObject *m, const char *name, PyObject *o) +PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value) { - PyObject *dict; - if (!PyModule_Check(m)) { + if (!PyModule_Check(mod)) { PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs module as first arg"); + "PyModule_AddObjectRef() first argument " + "must be a module"); return -1; } - if (!o) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs non-NULL value"); + if (!value) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_SystemError, + "PyModule_AddObjectRef() must be called " + "with an exception raised if value is NULL"); + } return -1; } - dict = PyModule_GetDict(m); + PyObject *dict = PyModule_GetDict(mod); if (dict == NULL) { /* Internal error -- modules must have a dict! */ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); + PyModule_GetName(mod)); return -1; } - if (PyDict_SetItemString(dict, name, o)) + + if (PyDict_SetItemString(dict, name, value)) { return -1; - Py_DECREF(o); + } return 0; } + +int +PyModule_AddObject(PyObject *mod, const char *name, PyObject *value) +{ + int res = PyModule_AddObjectRef(mod, name, value); + if (res == 0) { + Py_DECREF(value); + } + return res; +} + int PyModule_AddIntConstant(PyObject *m, const char *name, long value) { - PyObject *o = PyLong_FromLong(value); - if (!o) + PyObject *obj = PyLong_FromLong(value); + if (!obj) { return -1; - if (PyModule_AddObject(m, name, o) == 0) - return 0; - Py_DECREF(o); - return -1; + } + int res = PyModule_AddObjectRef(m, name, obj); + Py_DECREF(obj); + return res; } int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) { - PyObject *o = PyUnicode_FromString(value); - if (!o) + PyObject *obj = PyUnicode_FromString(value); + if (!obj) { return -1; - if (PyModule_AddObject(m, name, o) == 0) - return 0; - Py_DECREF(o); - return -1; + } + int res = PyModule_AddObjectRef(m, name, obj); + Py_DECREF(obj); + return res; } int @@ -693,11 +710,5 @@ PyModule_AddType(PyObject *module, PyTypeObject *type) const char *name = _PyType_Name(type); assert(name != NULL); - Py_INCREF(type); - if (PyModule_AddObject(module, name, (PyObject *)type) < 0) { - Py_DECREF(type); - return -1; - } - - return 0; + return PyModule_AddObjectRef(module, name, (PyObject *)type); } diff --git a/contrib/tools/python3/src/Python/mysnprintf.c b/contrib/tools/python3/src/Python/mysnprintf.c index 458ca14d5c6..cd69198011e 100644 --- a/contrib/tools/python3/src/Python/mysnprintf.c +++ b/contrib/tools/python3/src/Python/mysnprintf.c @@ -15,10 +15,6 @@ PyOS_snprintf and PyOS_vsnprintf never write more than size bytes (including the trailing '\0') into str. - If the platform doesn't have vsnprintf, and the buffer size needed to - avoid truncation exceeds size by more than 512, Python aborts with a - Py_FatalError. - Return value (rv): When 0 <= rv < size, the output conversion was unexceptional, and @@ -37,6 +33,7 @@ PyMem_Malloc couldn't obtain space for a temp buffer. CAUTION: Unlike C99, str != NULL and size > 0 are required. + Also, size must be smaller than INT_MAX. */ int @@ -56,50 +53,22 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) { assert(str != NULL); assert(size > 0); + assert(size <= (INT_MAX - 1)); assert(format != NULL); int len; /* # bytes written, excluding \0 */ -#if defined(_MSC_VER) || defined(HAVE_SNPRINTF) -# define _PyOS_vsnprintf_EXTRA_SPACE 1 -#else -# define _PyOS_vsnprintf_EXTRA_SPACE 512 - char *buffer; -#endif /* We take a size_t as input but return an int. Sanity check * our input so that it won't cause an overflow in the - * vsnprintf return value or the buffer malloc size. */ - if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) { + * vsnprintf return value. */ + if (size > INT_MAX - 1) { len = -666; goto Done; } #if defined(_MSC_VER) len = _vsnprintf(str, size, format, va); -#elif defined(HAVE_SNPRINTF) - len = vsnprintf(str, size, format, va); #else - /* Emulate vsnprintf(). */ - buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE); - if (buffer == NULL) { - len = -666; - goto Done; - } - - len = vsprintf(buffer, format, va); - if (len < 0) { - /* ignore the error */; - } - else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE) { - _Py_FatalErrorFunc(__func__, "Buffer overflow"); - } - else { - const size_t to_copy = (size_t)len < size ? - (size_t)len : size - 1; - assert(to_copy < size); - memcpy(str, buffer, to_copy); - str[to_copy] = '\0'; - } - PyMem_FREE(buffer); + len = vsnprintf(str, size, format, va); #endif Done: @@ -107,5 +76,4 @@ Done: str[size-1] = '\0'; } return len; -#undef _PyOS_vsnprintf_EXTRA_SPACE } diff --git a/contrib/tools/python3/src/Python/opcode_targets.h b/contrib/tools/python3/src/Python/opcode_targets.h index 538fdbe3e0b..951f8f8a556 100644 --- a/contrib/tools/python3/src/Python/opcode_targets.h +++ b/contrib/tools/python3/src/Python/opcode_targets.h @@ -29,6 +29,11 @@ static void *opcode_targets[256] = { &&TARGET_BINARY_TRUE_DIVIDE, &&TARGET_INPLACE_FLOOR_DIVIDE, &&TARGET_INPLACE_TRUE_DIVIDE, + &&TARGET_GET_LEN, + &&TARGET_MATCH_MAPPING, + &&TARGET_MATCH_SEQUENCE, + &&TARGET_MATCH_KEYS, + &&TARGET_COPY_DICT_WITHOUT_KEYS, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, @@ -43,11 +48,6 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_RERAISE, &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, @@ -98,7 +98,7 @@ static void *opcode_targets[256] = { &&TARGET_DELETE_ATTR, &&TARGET_STORE_GLOBAL, &&TARGET_DELETE_GLOBAL, - &&_unknown_opcode, + &&TARGET_ROT_N, &&TARGET_LOAD_CONST, &&TARGET_LOAD_NAME, &&TARGET_BUILD_TUPLE, @@ -118,7 +118,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_GLOBAL, &&TARGET_IS_OP, &&TARGET_CONTAINS_OP, - &&_unknown_opcode, + &&TARGET_RERAISE, &&_unknown_opcode, &&TARGET_JUMP_IF_NOT_EXC_MATCH, &&TARGET_SETUP_FINALLY, @@ -128,7 +128,7 @@ static void *opcode_targets[256] = { &&TARGET_DELETE_FAST, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_GEN_START, &&TARGET_RAISE_VARARGS, &&TARGET_CALL_FUNCTION, &&TARGET_MAKE_FUNCTION, @@ -151,7 +151,7 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_MATCH_CLASS, &&_unknown_opcode, &&TARGET_SETUP_ASYNC_WITH, &&TARGET_FORMAT_VALUE, diff --git a/contrib/tools/python3/src/Python/pathconfig.c b/contrib/tools/python3/src/Python/pathconfig.c index b2ce86e64ce..1017a571f2b 100644 --- a/contrib/tools/python3/src/Python/pathconfig.c +++ b/contrib/tools/python3/src/Python/pathconfig.c @@ -186,6 +186,80 @@ done: return status; } +PyObject * +_PyPathConfig_AsDict(void) +{ + PyObject *dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define SET_ITEM(KEY, EXPR) \ + do { \ + PyObject *obj = (EXPR); \ + if (obj == NULL) { \ + goto fail; \ + } \ + int res = PyDict_SetItemString(dict, KEY, obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) +#define SET_ITEM_STR(KEY) \ + SET_ITEM(#KEY, \ + (_Py_path_config.KEY \ + ? PyUnicode_FromWideChar(_Py_path_config.KEY, -1) \ + : (Py_INCREF(Py_None), Py_None))) +#define SET_ITEM_INT(KEY) \ + SET_ITEM(#KEY, PyLong_FromLong(_Py_path_config.KEY)) + + SET_ITEM_STR(program_full_path); + SET_ITEM_STR(prefix); + SET_ITEM_STR(exec_prefix); + SET_ITEM_STR(module_search_path); + SET_ITEM_STR(program_name); + SET_ITEM_STR(home); +#ifdef MS_WINDOWS + SET_ITEM_INT(isolated); + SET_ITEM_INT(site_import); + SET_ITEM_STR(base_executable); + + { + wchar_t py3path[MAX_PATH]; + HMODULE hPython3 = GetModuleHandleW(PY3_DLLNAME); + PyObject *obj; + if (hPython3 + && GetModuleFileNameW(hPython3, py3path, Py_ARRAY_LENGTH(py3path))) + { + obj = PyUnicode_FromWideChar(py3path, -1); + if (obj == NULL) { + goto fail; + } + } + else { + obj = Py_None; + Py_INCREF(obj); + } + if (PyDict_SetItemString(dict, "python3_dll", obj) < 0) { + Py_DECREF(obj); + goto fail; + } + Py_DECREF(obj); + } +#endif + +#undef SET_ITEM +#undef SET_ITEM_STR +#undef SET_ITEM_INT + + return dict; + +fail: + Py_DECREF(dict); + return NULL; +} + PyStatus _PyConfig_WritePathConfig(const PyConfig *config) @@ -258,7 +332,8 @@ config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) - _PyPathConfig_Calculate() */ static PyStatus -pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config) +pathconfig_init(_PyPathConfig *pathconfig, const PyConfig *config, + int compute_path_config) { PyStatus status; @@ -275,12 +350,9 @@ pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config) goto done; } - if (_Py_path_config.module_search_path == NULL) { + if (compute_path_config) { status = _PyPathConfig_Calculate(pathconfig, config); } - else { - /* Py_SetPath() has been called: avoid _PyPathConfig_Calculate() */ - } done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -289,17 +361,19 @@ done: static PyStatus -config_calculate_pathconfig(PyConfig *config) +config_init_pathconfig(PyConfig *config, int compute_path_config) { _PyPathConfig pathconfig = _PyPathConfig_INIT; PyStatus status; - status = pathconfig_calculate(&pathconfig, config); + status = pathconfig_init(&pathconfig, config, compute_path_config); if (_PyStatus_EXCEPTION(status)) { goto done; } - if (!config->module_search_paths_set) { + if (!config->module_search_paths_set + && pathconfig.module_search_path != NULL) + { status = config_init_module_search_paths(config, &pathconfig); if (_PyStatus_EXCEPTION(status)) { goto done; @@ -307,7 +381,7 @@ config_calculate_pathconfig(PyConfig *config) } #define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \ - if (config->CONFIG_ATTR == NULL) { \ + if (config->CONFIG_ATTR == NULL && pathconfig.PATH_ATTR != NULL) { \ if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \ goto no_memory; \ } \ @@ -353,7 +427,7 @@ done: PyStatus -_PyConfig_InitPathConfig(PyConfig *config) +_PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) { /* Do we need to calculate the path? */ if (!config->module_search_paths_set @@ -361,26 +435,26 @@ _PyConfig_InitPathConfig(PyConfig *config) || config->prefix == NULL || config->exec_prefix == NULL) { - PyStatus status = config_calculate_pathconfig(config); + PyStatus status = config_init_pathconfig(config, compute_path_config); if (_PyStatus_EXCEPTION(status)) { return status; } } - if (config->base_prefix == NULL) { + if (config->base_prefix == NULL && config->prefix != NULL) { if (copy_wstr(&config->base_prefix, config->prefix) < 0) { return _PyStatus_NO_MEMORY(); } } - if (config->base_exec_prefix == NULL) { + if (config->base_exec_prefix == NULL && config->exec_prefix != NULL) { if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) { return _PyStatus_NO_MEMORY(); } } - if (config->base_executable == NULL) { + if (config->base_executable == NULL && config->executable != NULL) { if (copy_wstr(&config->base_executable, config->executable) < 0) { return _PyStatus_NO_MEMORY(); @@ -391,53 +465,6 @@ _PyConfig_InitPathConfig(PyConfig *config) } -static PyStatus -pathconfig_global_read(_PyPathConfig *pathconfig) -{ - PyConfig config; - _PyConfig_InitCompatConfig(&config); - - /* Call _PyConfig_InitPathConfig() */ - PyStatus status = PyConfig_Read(&config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = pathconfig_set_from_config(pathconfig, &config); - -done: - PyConfig_Clear(&config); - return status; -} - - -static void -pathconfig_global_init(void) -{ - PyStatus status; - - if (_Py_path_config.module_search_path == NULL) { - status = pathconfig_global_read(&_Py_path_config); - if (_PyStatus_EXCEPTION(status)) { - Py_ExitStatusException(status); - } - } - else { - /* Global configuration already initialized */ - } - - assert(_Py_path_config.program_full_path != NULL); - assert(_Py_path_config.prefix != NULL); - assert(_Py_path_config.exec_prefix != NULL); - assert(_Py_path_config.module_search_path != NULL); - assert(_Py_path_config.program_name != NULL); - /* home can be NULL */ -#ifdef MS_WINDOWS - assert(_Py_path_config.base_executable != NULL); -#endif -} - - /* External interface */ static void _Py_NO_RETURN @@ -457,23 +484,17 @@ Py_SetPath(const wchar_t *path) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - /* Getting the program full path calls pathconfig_global_init() */ - wchar_t *program_full_path = _PyMem_RawWcsdup(Py_GetProgramFullPath()); - - PyMem_RawFree(_Py_path_config.program_full_path); PyMem_RawFree(_Py_path_config.prefix); PyMem_RawFree(_Py_path_config.exec_prefix); PyMem_RawFree(_Py_path_config.module_search_path); - _Py_path_config.program_full_path = program_full_path; _Py_path_config.prefix = _PyMem_RawWcsdup(L""); _Py_path_config.exec_prefix = _PyMem_RawWcsdup(L""); _Py_path_config.module_search_path = _PyMem_RawWcsdup(path); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (_Py_path_config.program_full_path == NULL - || _Py_path_config.prefix == NULL + if (_Py_path_config.prefix == NULL || _Py_path_config.exec_prefix == NULL || _Py_path_config.module_search_path == NULL) { @@ -547,7 +568,6 @@ _Py_SetProgramFullPath(const wchar_t *program_full_path) wchar_t * Py_GetPath(void) { - pathconfig_global_init(); return _Py_path_config.module_search_path; } @@ -555,7 +575,6 @@ Py_GetPath(void) wchar_t * Py_GetPrefix(void) { - pathconfig_global_init(); return _Py_path_config.prefix; } @@ -563,7 +582,6 @@ Py_GetPrefix(void) wchar_t * Py_GetExecPrefix(void) { - pathconfig_global_init(); return _Py_path_config.exec_prefix; } @@ -571,7 +589,6 @@ Py_GetExecPrefix(void) wchar_t * Py_GetProgramFullPath(void) { - pathconfig_global_init(); return _Py_path_config.program_full_path; } @@ -579,7 +596,6 @@ Py_GetProgramFullPath(void) wchar_t* Py_GetPythonHome(void) { - pathconfig_global_init(); return _Py_path_config.home; } @@ -587,7 +603,6 @@ Py_GetPythonHome(void) wchar_t * Py_GetProgramName(void) { - pathconfig_global_init(); return _Py_path_config.program_name; } diff --git a/contrib/tools/python3/src/Python/peephole.c b/contrib/tools/python3/src/Python/peephole.c deleted file mode 100644 index 6954c87b13b..00000000000 --- a/contrib/tools/python3/src/Python/peephole.c +++ /dev/null @@ -1,538 +0,0 @@ -/* Peephole optimizations for bytecode compiler. */ - -#include "Python.h" - -#include "Python-ast.h" -#include "node.h" -#include "ast.h" -#include "code.h" -#include "symtable.h" -#include "opcode.h" -#include "wordcode_helpers.h" - -#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD) -#define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ - || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP) -#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE \ - || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ - || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP || op==JUMP_IF_NOT_EXC_MATCH) -#define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP) -#define GETJUMPTGT(arr, i) (get_arg(arr, i) / sizeof(_Py_CODEUNIT) + \ - (ABSOLUTE_JUMP(_Py_OPCODE(arr[i])) ? 0 : i+1)) -#define ISBASICBLOCK(blocks, start, end) \ - (blocks[start]==blocks[end]) - - -/* Scans back N consecutive LOAD_CONST instructions, skipping NOPs, - returns index of the Nth last's LOAD_CONST's EXTENDED_ARG prefix. - Callers are responsible to check CONST_STACK_LEN beforehand. -*/ -static Py_ssize_t -lastn_const_start(const _Py_CODEUNIT *codestr, Py_ssize_t i, Py_ssize_t n) -{ - assert(n > 0); - for (;;) { - i--; - assert(i >= 0); - if (_Py_OPCODE(codestr[i]) == LOAD_CONST) { - if (!--n) { - while (i > 0 && _Py_OPCODE(codestr[i-1]) == EXTENDED_ARG) { - i--; - } - return i; - } - } - else { - assert(_Py_OPCODE(codestr[i]) == EXTENDED_ARG); - } - } -} - -/* Scans through EXTENDED ARGs, seeking the index of the effective opcode */ -static Py_ssize_t -find_op(const _Py_CODEUNIT *codestr, Py_ssize_t codelen, Py_ssize_t i) -{ - while (i < codelen && _Py_OPCODE(codestr[i]) == EXTENDED_ARG) { - i++; - } - return i; -} - -/* Given the index of the effective opcode, - scan back to construct the oparg with EXTENDED_ARG */ -static unsigned int -get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) -{ - _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; - } - } - } - return oparg; -} - -/* Fill the region with NOPs. */ -static void -fill_nops(_Py_CODEUNIT *codestr, Py_ssize_t start, Py_ssize_t end) -{ - memset(codestr + start, NOP, (end - start) * sizeof(_Py_CODEUNIT)); -} - -/* Given the index of the effective opcode, - attempt to replace the argument, taking into account EXTENDED_ARG. - Returns -1 on failure, or the new op index on success */ -static Py_ssize_t -set_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned int oparg) -{ - unsigned int curarg = get_arg(codestr, i); - int curilen, newilen; - if (curarg == oparg) - return i; - curilen = instrsize(curarg); - newilen = instrsize(oparg); - if (curilen < newilen) { - return -1; - } - - write_op_arg(codestr + i + 1 - curilen, _Py_OPCODE(codestr[i]), oparg, newilen); - fill_nops(codestr, i + 1 - curilen + newilen, i + 1); - return i-curilen+newilen; -} - -/* Attempt to write op/arg at end of specified region of memory. - Preceding memory in the region is overwritten with NOPs. - Returns -1 on failure, op index on success */ -static Py_ssize_t -copy_op_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned char op, - unsigned int oparg, Py_ssize_t maxi) -{ - int ilen = instrsize(oparg); - if (i + ilen > maxi) { - return -1; - } - write_op_arg(codestr + maxi - ilen, op, oparg, ilen); - fill_nops(codestr, i, maxi - ilen); - return maxi - 1; -} - -/* 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 Py_ssize_t -fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen, - Py_ssize_t c_start, Py_ssize_t opcode_end, - PyObject *consts, int n) -{ - /* Pre-conditions */ - assert(PyList_CheckExact(consts)); - - /* Buildup new tuple of constants */ - PyObject *newconst = PyTuple_New(n); - if (newconst == NULL) { - return -1; - } - - for (Py_ssize_t i = 0, pos = c_start; i < n; i++, pos++) { - assert(pos < opcode_end); - pos = find_op(codestr, codelen, pos); - assert(_Py_OPCODE(codestr[pos]) == LOAD_CONST); - - unsigned int arg = get_arg(codestr, pos); - PyObject *constant = PyList_GET_ITEM(consts, arg); - Py_INCREF(constant); - PyTuple_SET_ITEM(newconst, i, constant); - } - - Py_ssize_t index = PyList_GET_SIZE(consts); -#if SIZEOF_SIZE_T > SIZEOF_INT - if ((size_t)index >= UINT_MAX - 1) { - Py_DECREF(newconst); - PyErr_SetString(PyExc_OverflowError, "too many constants"); - return -1; - } -#endif - - /* Append folded constant onto consts */ - if (PyList_Append(consts, newconst)) { - Py_DECREF(newconst); - return -1; - } - Py_DECREF(newconst); - - return copy_op_arg(codestr, c_start, LOAD_CONST, - (unsigned int)index, opcode_end); -} - -static unsigned int * -markblocks(_Py_CODEUNIT *code, Py_ssize_t len) -{ - unsigned int *blocks = PyMem_New(unsigned int, len); - int i, j, opcode, blockcnt = 0; - - if (blocks == NULL) { - PyErr_NoMemory(); - return NULL; - } - memset(blocks, 0, len*sizeof(int)); - - /* Mark labels in the first pass */ - for (i = 0; i < len; i++) { - opcode = _Py_OPCODE(code[i]); - switch (opcode) { - case FOR_ITER: - case JUMP_FORWARD: - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_IF_NOT_EXC_MATCH: - case JUMP_ABSOLUTE: - case SETUP_FINALLY: - case SETUP_WITH: - case SETUP_ASYNC_WITH: - j = GETJUMPTGT(code, i); - assert(j < len); - blocks[j] = 1; - break; - } - } - /* Build block numbers in the second pass */ - for (i = 0; i < len; i++) { - blockcnt += blocks[i]; /* increment blockcnt over labels */ - blocks[i] = blockcnt; - } - return blocks; -} - -/* Perform basic peephole optimizations to components of a code object. - The consts object should still be in list form to allow new constants - to be appended. - - To keep the optimizer simple, it bails when the lineno table has complex - encoding for gaps >= 255. - - Optimizations are restricted to simple transformations occurring within a - single basic block. 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 and the jump addresses retargeted in - a single pass. */ - -PyObject * -PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, - PyObject *lnotab_obj) -{ - Py_ssize_t h, i, nexti, op_start, tgt; - unsigned int j, nops; - unsigned char opcode, nextop; - _Py_CODEUNIT *codestr = NULL; - unsigned char *lnotab; - unsigned int cum_orig_offset, last_offset; - Py_ssize_t tabsiz; - // Count runs of consecutive LOAD_CONSTs - unsigned int cumlc = 0, lastlc = 0; - unsigned int *blocks = NULL; - - /* Bail out if an exception is set */ - if (PyErr_Occurred()) - goto exitError; - - /* Bypass optimization when the lnotab table is too complex */ - assert(PyBytes_Check(lnotab_obj)); - lnotab = (unsigned char*)PyBytes_AS_STRING(lnotab_obj); - tabsiz = PyBytes_GET_SIZE(lnotab_obj); - assert(tabsiz == 0 || Py_REFCNT(lnotab_obj) == 1); - - /* Don't optimize if lnotab contains instruction pointer delta larger - than +255 (encoded as multiple bytes), just to keep the peephole optimizer - simple. The optimizer leaves line number deltas unchanged. */ - - for (i = 0; i < tabsiz; i += 2) { - if (lnotab[i] == 255) { - goto exitUnchanged; - } - } - - assert(PyBytes_Check(code)); - Py_ssize_t codesize = PyBytes_GET_SIZE(code); - assert(codesize % sizeof(_Py_CODEUNIT) == 0); - Py_ssize_t codelen = codesize / sizeof(_Py_CODEUNIT); - if (codelen > INT_MAX) { - /* Python assembler is limited to INT_MAX: see assembler.a_offset in - compile.c. */ - goto exitUnchanged; - } - - /* Make a modifiable copy of the code string */ - codestr = (_Py_CODEUNIT *)PyMem_Malloc(codesize); - if (codestr == NULL) { - PyErr_NoMemory(); - goto exitError; - } - memcpy(codestr, PyBytes_AS_STRING(code), codesize); - - blocks = markblocks(codestr, codelen); - if (blocks == NULL) - goto exitError; - assert(PyList_Check(consts)); - - for (i=find_op(codestr, codelen, 0) ; i= 1 && _Py_OPCODE(codestr[op_start-1]) == EXTENDED_ARG) { - op_start--; - } - - nexti = i + 1; - while (nexti < codelen && _Py_OPCODE(codestr[nexti]) == EXTENDED_ARG) - nexti++; - nextop = nexti < codelen ? _Py_OPCODE(codestr[nexti]) : 0; - - lastlc = cumlc; - cumlc = 0; - - switch (opcode) { - /* Skip over LOAD_CONST trueconst - POP_JUMP_IF_FALSE xx. This improves - "while 1" performance. */ - case LOAD_CONST: - cumlc = lastlc + 1; - if (nextop != POP_JUMP_IF_FALSE || - !ISBASICBLOCK(blocks, op_start, i + 1)) { - break; - } - PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); - int is_true = PyObject_IsTrue(cnt); - if (is_true == -1) { - goto exitError; - } - if (is_true == 1) { - fill_nops(codestr, op_start, nexti + 1); - cumlc = 0; - } - break; - - /* Try to fold tuples of constants. - Skip over BUILD_SEQN 1 UNPACK_SEQN 1. - Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. - Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ - case BUILD_TUPLE: - j = get_arg(codestr, i); - if (j > 0 && lastlc >= j) { - h = lastn_const_start(codestr, op_start, j); - if (ISBASICBLOCK(blocks, h, op_start)) { - h = fold_tuple_on_constants(codestr, codelen, - h, i+1, consts, j); - break; - } - } - if (nextop != UNPACK_SEQUENCE || - !ISBASICBLOCK(blocks, op_start, i + 1) || - j != get_arg(codestr, nexti)) - break; - if (j < 2) { - fill_nops(codestr, op_start, nexti + 1); - } else if (j == 2) { - codestr[op_start] = PACKOPARG(ROT_TWO, 0); - fill_nops(codestr, op_start + 1, nexti + 1); - } else if (j == 3) { - codestr[op_start] = PACKOPARG(ROT_THREE, 0); - codestr[op_start + 1] = PACKOPARG(ROT_TWO, 0); - fill_nops(codestr, op_start + 2, nexti + 1); - } - 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: - case JUMP_IF_TRUE_OR_POP: - h = get_arg(codestr, i) / sizeof(_Py_CODEUNIT); - tgt = find_op(codestr, codelen, h); - - j = _Py_OPCODE(codestr[tgt]); - if (CONDITIONAL_JUMP(j)) { - /* NOTE: all possible jumps here are absolute. */ - if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) { - /* The second jump will be taken iff the first is. - The current opcode inherits its target's - stack effect */ - h = set_arg(codestr, i, get_arg(codestr, tgt)); - } else { - /* The second jump is not taken if the first is (so - jump past it), and all conditional jumps pop their - argument when they're not taken (so change the - first jump to pop its argument when it's taken). */ - Py_ssize_t arg = (tgt + 1); - /* cannot overflow: codelen <= INT_MAX */ - assert((size_t)arg <= UINT_MAX / sizeof(_Py_CODEUNIT)); - arg *= sizeof(_Py_CODEUNIT); - h = set_arg(codestr, i, (unsigned int)arg); - j = opcode == JUMP_IF_TRUE_OR_POP ? - POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE; - } - - if (h >= 0) { - nexti = h; - codestr[nexti] = PACKOPARG(j, _Py_OPARG(codestr[nexti])); - break; - } - } - /* Intentional fallthrough */ - - /* Replace jumps to unconditional jumps */ - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_FORWARD: - case JUMP_ABSOLUTE: - h = GETJUMPTGT(codestr, i); - tgt = find_op(codestr, codelen, h); - /* Replace JUMP_* to a RETURN into just a RETURN */ - if (UNCONDITIONAL_JUMP(opcode) && - _Py_OPCODE(codestr[tgt]) == RETURN_VALUE) { - codestr[op_start] = PACKOPARG(RETURN_VALUE, 0); - fill_nops(codestr, op_start + 1, i + 1); - } else if (UNCONDITIONAL_JUMP(_Py_OPCODE(codestr[tgt]))) { - size_t arg = GETJUMPTGT(codestr, tgt); - if (opcode == JUMP_FORWARD) { /* JMP_ABS can go backwards */ - opcode = JUMP_ABSOLUTE; - } else if (!ABSOLUTE_JUMP(opcode)) { - if (arg < (size_t)(i + 1)) { - break; /* No backward relative jumps */ - } - arg -= i + 1; /* Calc relative jump addr */ - } - /* cannot overflow: codelen <= INT_MAX */ - assert(arg <= (UINT_MAX / sizeof(_Py_CODEUNIT))); - arg *= sizeof(_Py_CODEUNIT); - copy_op_arg(codestr, op_start, opcode, - (unsigned int)arg, i + 1); - } - break; - - /* Remove unreachable ops after RETURN */ - case RETURN_VALUE: - h = i + 1; - while (h < codelen && ISBASICBLOCK(blocks, i, h)) - { - /* Leave SETUP_FINALLY and RERAISE in place to help find block limits. */ - if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY || _Py_OPCODE(codestr[h]) == RERAISE) { - while (h > i + 1 && - _Py_OPCODE(codestr[h - 1]) == EXTENDED_ARG) - { - h--; - } - break; - } - h++; - } - if (h > i + 1) { - fill_nops(codestr, i + 1, h); - nexti = find_op(codestr, codelen, h); - } - break; - } - } - - /* Fixup lnotab */ - for (i = 0, nops = 0; i < codelen; i++) { - size_t block = (size_t)i - nops; - /* cannot overflow: codelen <= INT_MAX */ - assert(block <= UINT_MAX); - /* original code offset => new code offset */ - blocks[i] = (unsigned int)block; - if (_Py_OPCODE(codestr[i]) == NOP) { - nops++; - } - } - cum_orig_offset = 0; - last_offset = 0; - for (i=0 ; i < tabsiz ; i+=2) { - unsigned int offset_delta, new_offset; - cum_orig_offset += lnotab[i]; - assert(cum_orig_offset % sizeof(_Py_CODEUNIT) == 0); - new_offset = blocks[cum_orig_offset / sizeof(_Py_CODEUNIT)] * - sizeof(_Py_CODEUNIT); - offset_delta = new_offset - last_offset; - assert(offset_delta <= 255); - lnotab[i] = (unsigned char)offset_delta; - last_offset = new_offset; - } - - /* Remove NOPs and fixup jump targets */ - for (op_start = i = h = 0; i < codelen; i++, op_start = i) { - j = _Py_OPARG(codestr[i]); - while (_Py_OPCODE(codestr[i]) == EXTENDED_ARG) { - i++; - j = j<<8 | _Py_OPARG(codestr[i]); - } - opcode = _Py_OPCODE(codestr[i]); - switch (opcode) { - case NOP:continue; - - case JUMP_ABSOLUTE: - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case JUMP_IF_NOT_EXC_MATCH: - j = blocks[j / sizeof(_Py_CODEUNIT)] * sizeof(_Py_CODEUNIT); - break; - - case FOR_ITER: - case JUMP_FORWARD: - case SETUP_FINALLY: - case SETUP_WITH: - case SETUP_ASYNC_WITH: - j = blocks[j / sizeof(_Py_CODEUNIT) + i + 1] - blocks[i] - 1; - j *= sizeof(_Py_CODEUNIT); - break; - } - Py_ssize_t ilen = i - op_start + 1; - if (instrsize(j) > ilen) { - goto exitUnchanged; - } - /* If instrsize(j) < ilen, we'll emit EXTENDED_ARG 0 */ - if (ilen > 4) { - /* Can only happen when PyCode_Optimize() is called with - malformed bytecode. */ - goto exitUnchanged; - } - write_op_arg(codestr + h, opcode, j, (int)ilen); - h += ilen; - } - assert(h + (Py_ssize_t)nops == codelen); - - PyMem_Free(blocks); - code = PyBytes_FromStringAndSize((char *)codestr, h * sizeof(_Py_CODEUNIT)); - PyMem_Free(codestr); - return code; - - exitError: - code = NULL; - - exitUnchanged: - Py_XINCREF(code); - PyMem_Free(blocks); - PyMem_Free(codestr); - return code; -} diff --git a/contrib/tools/python3/src/Python/preconfig.c b/contrib/tools/python3/src/Python/preconfig.c index 262738fa57d..ae1cc3f90fc 100644 --- a/contrib/tools/python3/src/Python/preconfig.c +++ b/contrib/tools/python3/src/Python/preconfig.c @@ -19,11 +19,6 @@ preconfig_copy(PyPreConfig *config, const PyPreConfig *config2); /* --- File system encoding/errors -------------------------------- */ -/* The filesystem encoding is chosen by config_init_fs_encoding(), - see also initfsencoding(). - - Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors - are encoded to UTF-8. */ const char *Py_FileSystemDefaultEncoding = NULL; int Py_HasFileSystemDefaultEncoding = 0; const char *Py_FileSystemDefaultEncodeErrors = NULL; @@ -44,7 +39,10 @@ _Py_ClearFileSystemEncoding(void) /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors - global configuration variables. */ + global configuration variables to PyConfig.filesystem_encoding and + PyConfig.filesystem_errors (encoded to UTF-8). + + Function called by _PyUnicode_InitEncodings(). */ int _Py_SetFileSystemEncoding(const char *encoding, const char *errors) { @@ -171,6 +169,7 @@ _PyPreCmdline_SetConfig(const _PyPreCmdline *cmdline, PyConfig *config) COPY_ATTR(isolated); COPY_ATTR(use_environment); COPY_ATTR(dev_mode); + COPY_ATTR(warn_default_encoding); return _PyStatus_OK(); #undef COPY_ATTR @@ -259,9 +258,17 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, const PyPreConfig *preconfig) cmdline->dev_mode = 0; } + // warn_default_encoding + if (_Py_get_xoption(&cmdline->xoptions, L"warn_default_encoding") + || _Py_GetEnv(cmdline->use_environment, "PYTHONWARNDEFAULTENCODING")) + { + cmdline->warn_default_encoding = 1; + } + assert(cmdline->use_environment >= 0); assert(cmdline->isolated >= 0); assert(cmdline->dev_mode >= 0); + assert(cmdline->warn_default_encoding >= 0); return _PyStatus_OK(); } @@ -291,7 +298,17 @@ _PyPreConfig_InitCompatConfig(PyPreConfig *config) config->coerce_c_locale_warn = 0; config->dev_mode = -1; +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + /* bpo-40512: pymalloc is not compatible with subinterpreters, + force usage of libc malloc() which is thread-safe. */ +#ifdef Py_DEBUG + config->allocator = PYMEM_ALLOCATOR_MALLOC_DEBUG; +#else + config->allocator = PYMEM_ALLOCATOR_MALLOC; +#endif +#else config->allocator = PYMEM_ALLOCATOR_NOT_SET; +#endif #ifdef MS_WINDOWS config->legacy_windows_fs_encoding = -1; #endif @@ -819,13 +836,6 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; #endif - if (args) { - status = _PyPreCmdline_SetArgv(&cmdline, args); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - } - int locale_coerced = 0; int loops = 0; @@ -836,7 +846,7 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) loops++; if (loops == 3) { status = _PyStatus_ERR("Encoding changed twice while " - "reading the configuration"); + "reading the configuration"); goto done; } @@ -847,6 +857,15 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; #endif + if (args) { + // Set command line arguments at each iteration. If they are bytes + // strings, they are decoded from the new encoding. + status = _PyPreCmdline_SetArgv(&cmdline, args); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + } + status = preconfig_read(config, &cmdline); if (_PyStatus_EXCEPTION(status)) { goto done; @@ -886,7 +905,7 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) } /* Reset the configuration before reading again the configuration, - just keep UTF-8 Mode value. */ + just keep UTF-8 Mode and coerce C locale value. */ int new_utf8_mode = config->utf8_mode; int new_coerce_c_locale = config->coerce_c_locale; preconfig_copy(config, &save_config); diff --git a/contrib/tools/python3/src/Python/pyarena.c b/contrib/tools/python3/src/Python/pyarena.c index aefb787e554..ead03370d15 100644 --- a/contrib/tools/python3/src/Python/pyarena.c +++ b/contrib/tools/python3/src/Python/pyarena.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_pyarena.h" // PyArena /* A simple arena block structure. @@ -125,7 +126,7 @@ block_alloc(block *b, size_t size) } PyArena * -PyArena_New() +_PyArena_New(void) { PyArena* arena = (PyArena *)PyMem_Malloc(sizeof(PyArena)); if (!arena) @@ -154,7 +155,7 @@ PyArena_New() } void -PyArena_Free(PyArena *arena) +_PyArena_Free(PyArena *arena) { assert(arena); #if defined(Py_DEBUG) @@ -177,7 +178,7 @@ PyArena_Free(PyArena *arena) } void * -PyArena_Malloc(PyArena *arena, size_t size) +_PyArena_Malloc(PyArena *arena, size_t size) { void *p = block_alloc(arena->a_cur, size); if (!p) @@ -200,7 +201,7 @@ PyArena_Malloc(PyArena *arena, size_t size) } int -PyArena_AddPyObject(PyArena *arena, PyObject *obj) +_PyArena_AddPyObject(PyArena *arena, PyObject *obj) { int r = PyList_Append(arena->a_objects, obj); if (r >= 0) { diff --git a/contrib/tools/python3/src/Python/pyhash.c b/contrib/tools/python3/src/Python/pyhash.c index 3843079fbbc..f0c82356f1e 100644 --- a/contrib/tools/python3/src/Python/pyhash.c +++ b/contrib/tools/python3/src/Python/pyhash.c @@ -56,8 +56,12 @@ static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0}; If the result of the reduction is infinity (this is impossible for integers, floats and Decimals) then use the predefined hash value _PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead. - _PyHASH_INF, -_PyHASH_INF and _PyHASH_NAN are also used for the - hashes of float and Decimal infinities and nans. + _PyHASH_INF and -_PyHASH_INF are also used for the + hashes of float and Decimal infinities. + + NaNs hash with a pointer hash. Having distinct hash values prevents + catastrophic pileups from distinct NaN instances which used to always + have the same hash value but would compare unequal. A selling point for the above strategy is that it makes it possible to compute hashes of decimal and binary floating-point numbers @@ -82,8 +86,10 @@ static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0}; */ +Py_hash_t _Py_HashPointer(const void *); + Py_hash_t -_Py_HashDouble(double v) +_Py_HashDouble(PyObject *inst, double v) { int e, sign; double m; @@ -93,7 +99,7 @@ _Py_HashDouble(double v) if (Py_IS_INFINITY(v)) return v > 0 ? _PyHASH_INF : -_PyHASH_INF; else - return _PyHASH_NAN; + return _Py_HashPointer(inst); } m = frexp(v, &e); @@ -200,18 +206,14 @@ void _PyHash_Fini(void) { #ifdef Py_HASH_STATS - int i; - Py_ssize_t total = 0; - const char *fmt = "%2i %8" PY_FORMAT_SIZE_T "d %8" PY_FORMAT_SIZE_T "d\n"; - fprintf(stderr, "len calls total\n"); - for (i = 1; i <= Py_HASH_STATS_MAX; i++) { + Py_ssize_t total = 0; + for (int i = 1; i <= Py_HASH_STATS_MAX; i++) { total += hashstats[i]; - fprintf(stderr, fmt, i, hashstats[i], total); + fprintf(stderr, "%2i %8zd %8zd\n", i, hashstats[i], total); } total += hashstats[0]; - fprintf(stderr, "> %8" PY_FORMAT_SIZE_T "d %8" PY_FORMAT_SIZE_T "d\n", - hashstats[0], total); + fprintf(stderr, "> %8zd %8zd\n", hashstats[0], total); #endif } diff --git a/contrib/tools/python3/src/Python/pylifecycle.c b/contrib/tools/python3/src/Python/pylifecycle.c index 7f591179ac4..0d534fcf685 100644 --- a/contrib/tools/python3/src/Python/pylifecycle.c +++ b/contrib/tools/python3/src/Python/pylifecycle.c @@ -2,13 +2,10 @@ #include "Python.h" -#include "Python-ast.h" -#undef Yield /* undefine macro conflicting with */ - #include "pycore_ceval.h" // _PyEval_FiniGIL() #include "pycore_context.h" // _PyContext_Init() #include "pycore_fileutils.h" // _Py_ResetForceASCII() -#include "pycore_import.h" // _PyImport_Cleanup() +#include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_object.h" // _PyDebug_PrintTotalRefs() #include "pycore_pathconfig.h" // _PyConfig_WritePathConfig() @@ -18,9 +15,12 @@ #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() -#include "grammar.h" // PyGrammar_RemoveAccelerators() #include // setlocale() +#if defined(__APPLE__) +#include +#endif + #ifdef HAVE_SIGNAL_H # include // SIG_IGN #endif @@ -38,6 +38,8 @@ (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type)) #endif +#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) + _Py_IDENTIFIER(flush); _Py_IDENTIFIER(name); @@ -50,19 +52,40 @@ _Py_IDENTIFIER(threading); extern "C" { #endif -extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward declarations */ static PyStatus add_main_module(PyInterpreterState *interp); static PyStatus init_import_site(void); static PyStatus init_set_builtins_open(void); static PyStatus init_sys_streams(PyThreadState *tstate); -static void call_py_exitfuncs(PyThreadState *tstate); static void wait_for_thread_shutdown(PyThreadState *tstate); static void call_ll_exitfuncs(_PyRuntimeState *runtime); int _Py_UnhandledKeyboardInterrupt = 0; -_PyRuntimeState _PyRuntime = _PyRuntimeState_INIT; + +/* 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 + * officially supported feature */ + +#if defined(MS_WINDOWS) + +#pragma section("PyRuntime", read, write) +__declspec(allocate("PyRuntime")) + +#elif defined(__APPLE__) + +__attribute__(( + section(SEG_DATA ",PyRuntime") +)) + +#endif + +_PyRuntimeState _PyRuntime +#if defined(__linux__) && (defined(__GNUC__) || defined(__clang__)) +__attribute__ ((section (".PyRuntime"))) +#endif += _PyRuntimeState_INIT; static int runtime_initialized = 0; PyStatus @@ -99,14 +122,6 @@ _Py_IsFinalizing(void) int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \ PyOS_mystrnicmp; /* Python/pystrcmp.o */ -/* PyModule_GetWarningsModule is no longer necessary as of 2.6 -since _warnings is builtin. This API should not be used. */ -PyObject * -PyModule_GetWarningsModule(void) -{ - return PyImport_ImportModule("warnings"); -} - /* APIs to access the initialization flags * @@ -137,59 +152,54 @@ Py_IsInitialized(void) having the lock, but you cannot use multiple threads.) */ - -static PyStatus +static int init_importlib(PyThreadState *tstate, PyObject *sysmod) { - PyObject *importlib; - PyObject *impmod; - PyObject *value; + assert(!_PyErr_Occurred(tstate)); + PyInterpreterState *interp = tstate->interp; int verbose = _PyInterpreterState_GetConfig(interp)->verbose; - /* Import _importlib through its frozen version, _frozen_importlib. */ - if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { - return _PyStatus_ERR("can't import _frozen_importlib"); - } - else if (verbose) { + // Import _importlib through its frozen version, _frozen_importlib. + if (verbose) { PySys_FormatStderr("import _frozen_importlib # frozen\n"); } - importlib = PyImport_AddModule("_frozen_importlib"); + if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { + return -1; + } + PyObject *importlib = PyImport_AddModule("_frozen_importlib"); // borrowed if (importlib == NULL) { - return _PyStatus_ERR("couldn't get _frozen_importlib from sys.modules"); + return -1; } - interp->importlib = importlib; - Py_INCREF(interp->importlib); - - interp->import_func = PyDict_GetItemString(interp->builtins, "__import__"); - if (interp->import_func == NULL) - return _PyStatus_ERR("__import__ not found"); - Py_INCREF(interp->import_func); + interp->importlib = Py_NewRef(importlib); - /* Import the _imp module */ - impmod = PyInit__imp(); - if (impmod == NULL) { - return _PyStatus_ERR("can't import _imp"); - } - else if (verbose) { + // Import the _imp module + if (verbose) { PySys_FormatStderr("import _imp # builtin\n"); } - if (_PyImport_SetModuleString("_imp", impmod) < 0) { - return _PyStatus_ERR("can't save _imp to sys.modules"); + 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 */ - value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); + // Install importlib as the implementation of import + PyObject *value = PyObject_CallMethod(importlib, "_install", + "OO", sysmod, imp_mod); + Py_DECREF(imp_mod); if (value == NULL) { - _PyErr_Print(tstate); - return _PyStatus_ERR("importlib install failed"); + return -1; } Py_DECREF(value); - Py_DECREF(impmod); - return _PyStatus_OK(); + assert(!_PyErr_Occurred(tstate)); + return 0; } + static PyStatus init_importlib_external(PyThreadState *tstate) { @@ -438,6 +448,69 @@ _Py_SetLocaleFromEnv(int category) } +static int +interpreter_update_config(PyThreadState *tstate, int only_update_path_config) +{ + const PyConfig *config = &tstate->interp->config; + + if (!only_update_path_config) { + PyStatus status = _PyConfig_Write(config, tstate->interp->runtime); + if (_PyStatus_EXCEPTION(status)) { + _PyErr_SetFromPyStatus(status); + return -1; + } + } + + if (_Py_IsMainInterpreter(tstate->interp)) { + PyStatus status = _PyConfig_WritePathConfig(config); + if (_PyStatus_EXCEPTION(status)) { + _PyErr_SetFromPyStatus(status); + return -1; + } + } + + // Update the sys module for the new configuration + if (_PySys_UpdateConfig(tstate) < 0) { + return -1; + } + return 0; +} + + +int +_PyInterpreterState_SetConfig(const PyConfig *src_config) +{ + PyThreadState *tstate = PyThreadState_Get(); + int res = -1; + + PyConfig config; + PyConfig_InitPythonConfig(&config); + PyStatus status = _PyConfig_Copy(&config, src_config); + if (_PyStatus_EXCEPTION(status)) { + _PyErr_SetFromPyStatus(status); + goto done; + } + + status = PyConfig_Read(&config); + if (_PyStatus_EXCEPTION(status)) { + _PyErr_SetFromPyStatus(status); + goto done; + } + + status = _PyConfig_Copy(&tstate->interp->config, &config); + if (_PyStatus_EXCEPTION(status)) { + _PyErr_SetFromPyStatus(status); + goto done; + } + + res = interpreter_update_config(tstate, 0); + +done: + PyConfig_Clear(&config); + return res; +} + + /* Global initializations. Can be undone by Py_Finalize(). Don't call this twice without an intervening Py_Finalize() call. @@ -472,7 +545,7 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime, return status; } - status = _PyInterpreterState_SetConfig(interp, config); + status = _PyConfig_Copy(&interp->config, config); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -532,10 +605,10 @@ init_interp_create_gil(PyThreadState *tstate) /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is only called here. */ - _PyEval_FiniGIL(tstate); + _PyEval_FiniGIL(tstate->interp); /* Auto-thread-state API */ - status = _PyGILState_Init(tstate); + status = _PyGILState_SetTstate(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -555,12 +628,19 @@ pycore_create_interpreter(_PyRuntimeState *runtime, const PyConfig *config, PyThreadState **tstate_p) { + /* Auto-thread-state API */ + PyStatus status = _PyGILState_Init(runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { return _PyStatus_ERR("can't make main interpreter"); } + assert(_Py_IsMainInterpreter(interp)); - PyStatus status = _PyInterpreterState_SetConfig(interp, config); + status = _PyConfig_Copy(&interp->config, config); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -582,51 +662,75 @@ pycore_create_interpreter(_PyRuntimeState *runtime, static PyStatus -pycore_init_types(PyThreadState *tstate) +pycore_init_singletons(PyInterpreterState *interp) { PyStatus status; - int is_main_interp = _Py_IsMainInterpreter(tstate); - status = _PyGC_Init(tstate); + if (_PyLong_Init(interp) < 0) { + return _PyStatus_ERR("can't init longs"); + } + + if (_Py_IsMainInterpreter(interp)) { + _PyFloat_Init(); + } + + status = _PyBytes_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyUnicode_Init(interp); if (_PyStatus_EXCEPTION(status)) { return status; } + status = _PyTuple_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + return _PyStatus_OK(); +} + + +static PyStatus +pycore_init_types(PyInterpreterState *interp) +{ + PyStatus status; + int is_main_interp = _Py_IsMainInterpreter(interp); + if (is_main_interp) { + if (_PyStructSequence_Init() < 0) { + return _PyStatus_ERR("can't initialize structseq"); + } + status = _PyTypes_Init(); if (_PyStatus_EXCEPTION(status)) { return status; } - } - - if (!_PyLong_Init(tstate)) { - return _PyStatus_ERR("can't init longs"); - } + if (_PyLong_InitTypes() < 0) { + return _PyStatus_ERR("can't init int type"); + } - if (is_main_interp) { - status = _PyUnicode_Init(); + status = _PyUnicode_InitTypes(); if (_PyStatus_EXCEPTION(status)) { return status; } } - status = _PyExc_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (is_main_interp) { - if (!_PyFloat_Init()) { + if (_PyFloat_InitTypes() < 0) { return _PyStatus_ERR("can't init float"); } + } - if (_PyStructSequence_Init() < 0) { - return _PyStatus_ERR("can't initialize structseq"); - } + status = _PyExc_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - status = _PyErr_Init(); + status = _PyErr_InitTypes(); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -644,14 +748,13 @@ pycore_init_types(PyThreadState *tstate) static PyStatus pycore_init_builtins(PyThreadState *tstate) { - assert(!_PyErr_Occurred(tstate)); + PyInterpreterState *interp = tstate->interp; - PyObject *bimod = _PyBuiltin_Init(tstate); + PyObject *bimod = _PyBuiltin_Init(interp); if (bimod == NULL) { goto error; } - PyInterpreterState *interp = tstate->interp; if (_PyImport_FixupBuiltin(bimod, "builtins", interp->modules) < 0) { goto error; } @@ -674,8 +777,15 @@ pycore_init_builtins(PyThreadState *tstate) } Py_DECREF(bimod); - assert(!_PyErr_Occurred(tstate)); + // Get the __import__ function + PyObject *import_func = _PyDict_GetItemStringWithError(interp->builtins, + "__import__"); + if (import_func == NULL) { + goto error; + } + interp->import_func = Py_NewRef(import_func); + assert(!_PyErr_Occurred(tstate)); return _PyStatus_OK(); error: @@ -685,54 +795,38 @@ error: static PyStatus -pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) +pycore_interp_init(PyThreadState *tstate) { - assert(!_PyErr_Occurred(tstate)); + PyInterpreterState *interp = tstate->interp; + PyStatus status; + PyObject *sysmod = NULL; - PyStatus status = _PyImportHooks_Init(tstate); + // Create singletons before the first PyType_Ready() call, since + // PyType_Ready() uses singletons like the Unicode empty string (tp_doc) + // and the empty tuple singletons (tp_bases). + status = pycore_init_singletons(interp); if (_PyStatus_EXCEPTION(status)) { return status; } - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); - if (_Py_IsMainInterpreter(tstate)) { - /* Initialize _warnings. */ - status = _PyWarnings_InitState(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (config->_install_importlib) { - status = _PyConfig_WritePathConfig(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } + // The GC must be initialized before the first GC collection. + status = _PyGC_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - /* This call sets up builtin and frozen import support */ - if (config->_install_importlib) { - status = init_importlib(tstate, sysmod); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + status = pycore_init_types(interp); + if (_PyStatus_EXCEPTION(status)) { + goto done; } - assert(!_PyErr_Occurred(tstate)); - - return _PyStatus_OK(); -} - - -static PyStatus -pycore_interp_init(PyThreadState *tstate) -{ - PyStatus status; - PyObject *sysmod = NULL; + if (_PyWarnings_InitState(interp) < 0) { + return _PyStatus_ERR("can't initialize warnings"); + } - status = pycore_init_types(tstate); + status = _PyAtExit_Init(interp); if (_PyStatus_EXCEPTION(status)) { - goto done; + return status; } status = _PySys_Create(tstate, &sysmod); @@ -745,7 +839,13 @@ pycore_interp_init(PyThreadState *tstate) goto done; } - status = pycore_init_import_warnings(tstate, sysmod); + 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"); + } + } done: /* sys.modules['sys'] contains a strong reference to the module */ @@ -919,14 +1019,16 @@ pyinit_core(_PyRuntimeState *runtime, } PyConfig config; - _PyConfig_InitCompatConfig(&config); + PyConfig_InitPythonConfig(&config); status = _PyConfig_Copy(&config, src_config); if (_PyStatus_EXCEPTION(status)) { goto done; } - status = PyConfig_Read(&config); + // Read the configuration, but don't compute the path configuration + // (it is computed in the main init). + status = _PyConfig_Read(&config, 0); if (_PyStatus_EXCEPTION(status)) { goto done; } @@ -951,19 +1053,10 @@ done: configuration. Example of bpo-34008: Py_Main() called after Py_Initialize(). */ static PyStatus -_Py_ReconfigureMainInterpreter(PyThreadState *tstate) +pyinit_main_reconfigure(PyThreadState *tstate) { - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); - - PyObject *argv = _PyWideStringList_AsList(&config->argv); - if (argv == NULL) { - return _PyStatus_NO_MEMORY(); \ - } - - int res = PyDict_SetItemString(tstate->interp->sysdict, "argv", argv); - Py_DECREF(argv); - if (res < 0) { - return _PyStatus_ERR("fail to set sys.argv"); + if (interpreter_update_config(tstate, 0) < 0) { + return _PyStatus_ERR("fail to reconfigure Python"); } return _PyStatus_OK(); } @@ -972,10 +1065,12 @@ _Py_ReconfigureMainInterpreter(PyThreadState *tstate) static PyStatus init_interp_main(PyThreadState *tstate) { + extern void _PyThread_debug_deprecation(void); + assert(!_PyErr_Occurred(tstate)); PyStatus status; - int is_main_interp = _Py_IsMainInterpreter(tstate); + int is_main_interp = _Py_IsMainInterpreter(tstate->interp); PyInterpreterState *interp = tstate->interp; const PyConfig *config = _PyInterpreterState_GetConfig(interp); @@ -991,14 +1086,14 @@ init_interp_main(PyThreadState *tstate) return _PyStatus_OK(); } - if (is_main_interp) { - if (_PyTime_Init() < 0) { - return _PyStatus_ERR("can't initialize time"); - } + // Compute the path configuration + status = _PyConfig_InitPathConfig(&interp->config, 1); + if (_PyStatus_EXCEPTION(status)) { + return status; } - if (_PySys_InitMain(tstate) < 0) { - return _PyStatus_ERR("can't finish initializing sys"); + if (interpreter_update_config(tstate, 1) < 0) { + return _PyStatus_ERR("failed to update the Python config"); } status = init_importlib_external(tstate); @@ -1073,6 +1168,9 @@ init_interp_main(PyThreadState *tstate) #endif } + // Warn about PYTHONTHREADDEBUG deprecation + _PyThread_debug_deprecation(); + assert(!_PyErr_Occurred(tstate)); return _PyStatus_OK(); @@ -1099,7 +1197,7 @@ pyinit_main(PyThreadState *tstate) } if (interp->runtime->initialized) { - return _Py_ReconfigureMainInterpreter(tstate); + return pyinit_main_reconfigure(tstate); } PyStatus status = init_interp_main(tstate); @@ -1110,19 +1208,6 @@ pyinit_main(PyThreadState *tstate) } -PyStatus -_Py_InitializeMain(void) -{ - PyStatus status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - return pyinit_main(tstate); -} - - PyStatus Py_InitializeFromConfig(const PyConfig *config) { @@ -1190,6 +1275,305 @@ Py_Initialize(void) } +PyStatus +_Py_InitializeMain(void) +{ + PyStatus status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + return pyinit_main(tstate); +} + + +static void +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", + "last_type", "last_value", "last_traceback", + "path_hooks", "path_importer_cache", "meta_path", + "__interactivehook__", + NULL + }; + + static const char * const sys_files[] = { + "stdin", "__stdin__", + "stdout", "__stdout__", + "stderr", "__stderr__", + NULL + }; + + PyInterpreterState *interp = tstate->interp; + if (verbose) { + PySys_WriteStderr("# clear builtins._\n"); + } + if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) { + PyErr_WriteUnraisable(NULL); + } + + 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) { + PyErr_WriteUnraisable(NULL); + } + } + for (p = sys_files; *p != NULL; p+=2) { + const char *name = p[0]; + const char *orig_name = p[1]; + if (verbose) { + PySys_WriteStderr("# restore sys.%s\n", name); + } + PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict, + orig_name); + if (value == NULL) { + if (_PyErr_Occurred(tstate)) { + PyErr_WriteUnraisable(NULL); + } + value = Py_None; + } + if (PyDict_SetItemString(interp->sysdict, name, value) < 0) { + PyErr_WriteUnraisable(NULL); + } + } +} + + +static PyObject* +finalize_remove_modules(PyObject *modules, int verbose) +{ + PyObject *weaklist = PyList_New(0); + if (weaklist == NULL) { + PyErr_WriteUnraisable(NULL); + } + +#define STORE_MODULE_WEAKREF(name, mod) \ + if (weaklist != NULL) { \ + PyObject *wr = PyWeakref_NewRef(mod, NULL); \ + if (wr) { \ + PyObject *tup = PyTuple_Pack(2, name, wr); \ + if (!tup || PyList_Append(weaklist, tup) < 0) { \ + PyErr_WriteUnraisable(NULL); \ + } \ + Py_XDECREF(tup); \ + Py_DECREF(wr); \ + } \ + else { \ + PyErr_WriteUnraisable(NULL); \ + } \ + } + +#define CLEAR_MODULE(name, mod) \ + if (PyModule_Check(mod)) { \ + if (verbose && PyUnicode_Check(name)) { \ + PySys_FormatStderr("# cleanup[2] removing %U\n", name); \ + } \ + STORE_MODULE_WEAKREF(name, mod); \ + if (PyObject_SetItem(modules, name, Py_None) < 0) { \ + PyErr_WriteUnraisable(NULL); \ + } \ + } + + if (PyDict_CheckExact(modules)) { + Py_ssize_t pos = 0; + PyObject *key, *value; + while (PyDict_Next(modules, &pos, &key, &value)) { + CLEAR_MODULE(key, value); + } + } + else { + PyObject *iterator = PyObject_GetIter(modules); + if (iterator == NULL) { + PyErr_WriteUnraisable(NULL); + } + else { + PyObject *key; + while ((key = PyIter_Next(iterator))) { + PyObject *value = PyObject_GetItem(modules, key); + if (value == NULL) { + PyErr_WriteUnraisable(NULL); + continue; + } + CLEAR_MODULE(key, value); + Py_DECREF(value); + Py_DECREF(key); + } + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(NULL); + } + Py_DECREF(iterator); + } + } +#undef CLEAR_MODULE +#undef STORE_MODULE_WEAKREF + + return weaklist; +} + + +static void +finalize_clear_modules_dict(PyObject *modules) +{ + if (PyDict_CheckExact(modules)) { + PyDict_Clear(modules); + } + else { + _Py_IDENTIFIER(clear); + if (_PyObject_CallMethodIdNoArgs(modules, &PyId_clear) == NULL) { + PyErr_WriteUnraisable(NULL); + } + } +} + + +static void +finalize_restore_builtins(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + PyObject *dict = PyDict_Copy(interp->builtins); + if (dict == NULL) { + PyErr_WriteUnraisable(NULL); + } + PyDict_Clear(interp->builtins); + if (PyDict_Update(interp->builtins, interp->builtins_copy)) { + _PyErr_Clear(tstate); + } + Py_XDECREF(dict); +} + + +static void +finalize_modules_clear_weaklist(PyInterpreterState *interp, + PyObject *weaklist, int verbose) +{ + // First clear modules imported later + for (Py_ssize_t i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) { + PyObject *tup = PyList_GET_ITEM(weaklist, i); + PyObject *name = PyTuple_GET_ITEM(tup, 0); + PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); + if (mod == Py_None) { + continue; + } + assert(PyModule_Check(mod)); + PyObject *dict = PyModule_GetDict(mod); + if (dict == interp->builtins || dict == interp->sysdict) { + continue; + } + Py_INCREF(mod); + if (verbose && PyUnicode_Check(name)) { + PySys_FormatStderr("# cleanup[3] wiping %U\n", name); + } + _PyModule_Clear(mod); + Py_DECREF(mod); + } +} + + +static void +finalize_clear_sys_builtins_dict(PyInterpreterState *interp, int verbose) +{ + // Clear sys dict + if (verbose) { + PySys_FormatStderr("# cleanup[3] wiping sys\n"); + } + _PyModule_ClearDict(interp->sysdict); + + // Clear builtins dict + if (verbose) { + PySys_FormatStderr("# cleanup[3] wiping builtins\n"); + } + _PyModule_ClearDict(interp->builtins); +} + + +/* Clear modules, as good as we can */ +static void +finalize_modules(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + PyObject *modules = interp->modules; + if (modules == NULL) { + // Already done + return; + } + int verbose = _PyInterpreterState_GetConfig(interp)->verbose; + + // Delete some special builtins._ and sys attributes first. These are + // common places where user values hide and people complain when their + // destructors fail. Since the modules containing them are + // deleted *last* of all, they would come too late in the normal + // destruction order. Sigh. + // + // XXX Perhaps these precautions are obsolete. Who knows? + finalize_modules_delete_special(tstate, verbose); + + // Remove all modules from sys.modules, hoping that garbage collection + // can reclaim most of them: set all sys.modules values to None. + // + // We prepare a list which will receive (name, weakref) tuples of + // modules when they are removed from sys.modules. The name is used + // for diagnosis messages (in verbose mode), while the weakref helps + // detect those modules which have been held alive. + PyObject *weaklist = finalize_remove_modules(modules, verbose); + + // Clear the modules dict + finalize_clear_modules_dict(modules); + + // Restore the original builtins dict, to ensure that any + // user data gets cleared. + finalize_restore_builtins(tstate); + + // Collect garbage + _PyGC_CollectNoFail(tstate); + + // Dump GC stats before it's too late, since it uses the warnings + // machinery. + _PyGC_DumpShutdownStats(interp); + + if (weaklist != NULL) { + // Now, if there are any modules left alive, clear their globals to + // minimize potential leaks. All C extension modules actually end + // up here, since they are kept alive in the interpreter state. + // + // The special treatment of "builtins" here is because even + // when it's not referenced as a module, its dictionary is + // referenced by almost every module's __builtins__. Since + // deleting a module clears its dictionary (even if there are + // references left to it), we need to delete the "builtins" + // module last. Likewise, we don't delete sys until the very + // end because it is implicitly referenced (e.g. by print). + // + // Since dict is ordered in CPython 3.6+, modules are saved in + // importing order. First clear modules imported later. + finalize_modules_clear_weaklist(interp, weaklist, verbose); + Py_DECREF(weaklist); + } + + // Clear sys and builtins modules dict + finalize_clear_sys_builtins_dict(interp, verbose); + + // Clear module dict copies stored in the interpreter state: + // clear PyInterpreterState.modules_by_index and + // clear PyModuleDef.m_base.m_copy (of extensions not using the multi-phase + // initialization API) + _PyInterpreterState_ClearModules(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); + + // Collect garbage once more + _PyGC_CollectNoFail(tstate); +} + + /* Flush stdout and stderr */ static int @@ -1208,6 +1592,7 @@ file_is_closed(PyObject *fobj) return r > 0; } + static int flush_std_files(void) { @@ -1255,56 +1640,37 @@ flush_std_files(void) static void -finalize_interp_types(PyThreadState *tstate, int is_main_interp) +finalize_interp_types(PyInterpreterState *interp) { - if (is_main_interp) { - /* Sundry finalizers */ - _PyAST_Fini(); - _PyFrame_Fini(); - _PyTuple_Fini(); - _PyList_Fini(); - _PySet_Fini(); - _PyBytes_Fini(); - } - - _PyLong_Fini(tstate); - - if (is_main_interp) { - _PyFloat_Fini(); - _PyDict_Fini(); - _PySlice_Fini(); - } + _PyExc_Fini(interp); + _PyFrame_Fini(interp); + _PyAsyncGen_Fini(interp); + _PyContext_Fini(interp); + _PyType_Fini(interp); + // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses + // a dict internally. + _PyUnicode_ClearInterned(interp); - _PyWarnings_Fini(tstate->interp); + _PyDict_Fini(interp); + _PyList_Fini(interp); + _PyTuple_Fini(interp); - if (is_main_interp) { - _Py_HashRandomization_Fini(); - _PyArg_Fini(); - _PyAsyncGen_Fini(); - _PyContext_Fini(); - } + _PySlice_Fini(interp); - /* Cleanup Unicode implementation */ - _PyUnicode_Fini(tstate); - - if (is_main_interp) { - _Py_ClearFileSystemEncoding(); - } + _PyBytes_Fini(interp); + _PyUnicode_Fini(interp); + _PyFloat_Fini(interp); + _PyLong_Fini(interp); } static void finalize_interp_clear(PyThreadState *tstate) { - int is_main_interp = _Py_IsMainInterpreter(tstate); + int is_main_interp = _Py_IsMainInterpreter(tstate->interp); /* Clear interpreter state and all thread states */ - PyInterpreterState_Clear(tstate->interp); - - /* Trigger a GC collection on subinterpreters*/ - if (!is_main_interp) { - _PyGC_CollectNoFail(); - } + _PyInterpreterState_Clear(tstate); /* Clear all loghooks */ /* Both _PySys_Audit function and users still need PyObject, such as tuple. @@ -1313,30 +1679,22 @@ finalize_interp_clear(PyThreadState *tstate) _PySys_ClearAuditHooks(tstate); } - finalize_interp_types(tstate, is_main_interp); - if (is_main_interp) { - /* XXX Still allocated: - - various static ad-hoc pointers to interned strings - - int and float free list blocks - - whatever various modules and libraries allocate - */ - - PyGrammar_RemoveAccelerators(&_PyParser_Grammar); - - _PyExc_Fini(); + _Py_HashRandomization_Fini(); + _PyArg_Fini(); + _Py_ClearFileSystemEncoding(); } - _PyGC_Fini(tstate); + finalize_interp_types(tstate->interp); } static void -finalize_interp_delete(PyThreadState *tstate) +finalize_interp_delete(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(tstate)) { + if (_Py_IsMainInterpreter(interp)) { /* Cleanup auto-thread-state */ - _PyGILState_Fini(tstate); + _PyGILState_Fini(interp); } /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can @@ -1345,7 +1703,7 @@ finalize_interp_delete(PyThreadState *tstate) created GIL, which ensures that Py_Initialize / Py_FinalizeEx can be called multiple times. */ - PyInterpreterState_Delete(tstate->interp); + PyInterpreterState_Delete(interp); } @@ -1378,7 +1736,7 @@ Py_FinalizeEx(void) * the threads created via Threading. */ - call_py_exitfuncs(tstate); + _PyAtExit_Call(tstate->interp); /* Copy the core config, PyInterpreterState_Delete() free the core config memory */ @@ -1414,7 +1772,7 @@ Py_FinalizeEx(void) } /* Disable signal handling */ - PyOS_FiniInterrupts(); + _PySignal_Fini(); /* Collect garbage. This may call finalizers; it's nice to call these * before all modules are destroyed. @@ -1428,10 +1786,10 @@ Py_FinalizeEx(void) * XXX but I'm unclear on exactly how that one happens. In any case, * XXX I haven't seen a real-life report of either of these. */ - _PyGC_CollectIfEnabled(); + PyGC_Collect(); /* Destroy all modules */ - _PyImport_Cleanup(tstate); + finalize_modules(tstate); /* Print debug stats if any */ _PyEval_Fini(); @@ -1467,9 +1825,6 @@ Py_FinalizeEx(void) /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ _PyImport_Fini(); - /* Cleanup typeobject.c's internal caches. */ - _PyType_Fini(); - /* unload faulthandler module */ _PyFaulthandler_Fini(); @@ -1494,7 +1849,7 @@ Py_FinalizeEx(void) #endif /* Py_TRACE_REFS */ finalize_interp_clear(tstate); - finalize_interp_delete(tstate); + finalize_interp_delete(tstate->interp); #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. @@ -1573,17 +1928,20 @@ new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter) /* Copy the current interpreter config into the new interpreter */ const PyConfig *config; +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS if (save_tstate != NULL) { config = _PyInterpreterState_GetConfig(save_tstate->interp); } else +#endif { /* No current thread state, copy from the main interpreter */ PyInterpreterState *main_interp = PyInterpreterState_Main(); config = _PyInterpreterState_GetConfig(main_interp); } - status = _PyInterpreterState_SetConfig(interp, config); + + status = _PyConfig_Copy(&interp->config, config); if (_PyStatus_EXCEPTION(status)) { goto error; } @@ -1666,15 +2024,16 @@ Py_EndInterpreter(PyThreadState *tstate) // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(tstate); - call_py_exitfuncs(tstate); + _PyAtExit_Call(tstate->interp); if (tstate != interp->tstate_head || tstate->next != NULL) { Py_FatalError("not the last thread"); } - _PyImport_Cleanup(tstate); + finalize_modules(tstate); + finalize_interp_clear(tstate); - finalize_interp_delete(tstate); + finalize_interp_delete(tstate->interp); } /* Add the __main__ module */ @@ -1695,7 +2054,10 @@ add_main_module(PyInterpreterState *interp) } Py_DECREF(ann_dict); - if (PyDict_GetItemString(d, "__builtins__") == NULL) { + if (_PyDict_GetItemStringWithError(d, "__builtins__") == NULL) { + if (PyErr_Occurred()) { + return _PyStatus_ERR("Failed to test __main__.__builtins__"); + } PyObject *bimod = PyImport_ImportModule("builtins"); if (bimod == NULL) { return _PyStatus_ERR("Failed to retrieve builtins module"); @@ -1712,8 +2074,11 @@ add_main_module(PyInterpreterState *interp) * be set if __main__ gets further initialized later in the startup * process. */ - loader = PyDict_GetItemString(d, "__loader__"); + loader = _PyDict_GetItemStringWithError(d, "__loader__"); if (loader == NULL || loader == Py_None) { + if (PyErr_Occurred()) { + return _PyStatus_ERR("Failed to test __main__.__loader__"); + } PyObject *loader = PyObject_GetAttrString(interp->importlib, "BuiltinImporter"); if (loader == NULL) { @@ -1915,7 +2280,7 @@ error: return NULL; } -/* Set builtins.open to io.OpenWrapper */ +/* Set builtins.open to io.open */ static PyStatus init_set_builtins_open(void) { @@ -1931,7 +2296,7 @@ init_set_builtins_open(void) goto error; } - if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { + if (!(wrapper = PyObject_GetAttrString(iomod, "open"))) { goto error; } @@ -1953,12 +2318,11 @@ done: } -/* Initialize sys.stdin, stdout, stderr and builtins.open */ +/* Create sys.stdin, sys.stdout and sys.stderr */ static PyStatus init_sys_streams(PyThreadState *tstate) { PyObject *iomod = NULL; - PyObject *m; PyObject *std = NULL; int fd; PyObject * encoding_attr; @@ -1978,18 +2342,6 @@ init_sys_streams(PyThreadState *tstate) } #endif - /* Hack to avoid a nasty recursion issue when Python is invoked - in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ - if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { - goto error; - } - Py_DECREF(m); - - if (!(m = PyImport_ImportModule("encodings.latin_1"))) { - goto error; - } - Py_DECREF(m); - if (!(iomod = PyImport_ImportModule("io"))) { goto error; } @@ -2069,8 +2421,7 @@ static void _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, PyThreadState *tstate) { - fputc('\n', stderr); - fflush(stderr); + PUTS(fd, "\n"); /* display the current Python stack */ _Py_DumpTracebackThreads(fd, interp, tstate); @@ -2172,30 +2523,31 @@ fatal_output_debug(const char *msg) static void -fatal_error_dump_runtime(FILE *stream, _PyRuntimeState *runtime) +fatal_error_dump_runtime(int fd, _PyRuntimeState *runtime) { - fprintf(stream, "Python runtime state: "); + PUTS(fd, "Python runtime state: "); PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime); if (finalizing) { - fprintf(stream, "finalizing (tstate=%p)", finalizing); + PUTS(fd, "finalizing (tstate=0x"); + _Py_DumpHexadecimal(fd, (uintptr_t)finalizing, sizeof(finalizing) * 2); + PUTS(fd, ")"); } else if (runtime->initialized) { - fprintf(stream, "initialized"); + PUTS(fd, "initialized"); } else if (runtime->core_initialized) { - fprintf(stream, "core initialized"); + PUTS(fd, "core initialized"); } else if (runtime->preinitialized) { - fprintf(stream, "preinitialized"); + PUTS(fd, "preinitialized"); } else if (runtime->preinitializing) { - fprintf(stream, "preinitializing"); + PUTS(fd, "preinitializing"); } else { - fprintf(stream, "unknown"); + PUTS(fd, "unknown"); } - fprintf(stream, "\n"); - fflush(stream); + PUTS(fd, "\n"); } @@ -2214,11 +2566,104 @@ fatal_error_exit(int status) } +// Dump the list of extension modules of sys.modules, excluding stdlib modules +// (sys.stdlib_module_names), into fd file descriptor. +// +// This function is called by a signal handler in faulthandler: avoid memory +// allocations and keep the implementation simple. For example, the list is not +// sorted on purpose. +void +_Py_DumpExtensionModules(int fd, PyInterpreterState *interp) +{ + if (interp == NULL) { + return; + } + PyObject *modules = interp->modules; + if (modules == NULL || !PyDict_Check(modules)) { + return; + } + + Py_ssize_t pos; + PyObject *key, *value; + + // Avoid PyDict_GetItemString() which calls PyUnicode_FromString(), + // memory cannot be allocated on the heap in a signal handler. + // Iterate on the dict instead. + PyObject *stdlib_module_names = NULL; + if (interp->sysdict != NULL) { + pos = 0; + while (PyDict_Next(interp->sysdict, &pos, &key, &value)) { + if (PyUnicode_Check(key) + && PyUnicode_CompareWithASCIIString(key, "stdlib_module_names") == 0) { + stdlib_module_names = value; + break; + } + } + } + // If we failed to get sys.stdlib_module_names or it's not a frozenset, + // don't exclude stdlib modules. + if (stdlib_module_names != NULL && !PyFrozenSet_Check(stdlib_module_names)) { + stdlib_module_names = NULL; + } + + // List extensions + int header = 1; + Py_ssize_t count = 0; + pos = 0; + while (PyDict_Next(modules, &pos, &key, &value)) { + if (!PyUnicode_Check(key)) { + continue; + } + if (!_PyModule_IsExtension(value)) { + continue; + } + // Use the module name from the sys.modules key, + // don't attempt to get the module object name. + if (stdlib_module_names != NULL) { + int is_stdlib_ext = 0; + + Py_ssize_t i = 0; + PyObject *item; + Py_hash_t hash; + while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) { + if (PyUnicode_Check(item) + && PyUnicode_Compare(key, item) == 0) + { + is_stdlib_ext = 1; + break; + } + } + if (is_stdlib_ext) { + // Ignore stdlib extension + continue; + } + } + + if (header) { + PUTS(fd, "\nExtension modules: "); + header = 0; + } + else { + PUTS(fd, ", "); + } + + _Py_DumpASCII(fd, key); + count++; + } + + if (count) { + PUTS(fd, " (total: "); + _Py_DumpDecimal(fd, count); + PUTS(fd, ")"); + PUTS(fd, "\n"); + } +} + + static void _Py_NO_RETURN -fatal_error(FILE *stream, int header, const char *prefix, const char *msg, +fatal_error(int fd, int header, const char *prefix, const char *msg, int status) { - const int fd = fileno(stream); static int reentrant = 0; if (reentrant) { @@ -2229,29 +2674,22 @@ fatal_error(FILE *stream, int header, const char *prefix, const char *msg, reentrant = 1; if (header) { - fprintf(stream, "Fatal Python error: "); + PUTS(fd, "Fatal Python error: "); if (prefix) { - fputs(prefix, stream); - fputs(": ", stream); + PUTS(fd, prefix); + PUTS(fd, ": "); } if (msg) { - fputs(msg, stream); + PUTS(fd, msg); } else { - fprintf(stream, ""); + PUTS(fd, ""); } - fputs("\n", stream); - fflush(stream); + PUTS(fd, "\n"); } _PyRuntimeState *runtime = &_PyRuntime; - fatal_error_dump_runtime(stream, runtime); - - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - PyInterpreterState *interp = NULL; - if (tstate != NULL) { - interp = tstate->interp; - } + fatal_error_dump_runtime(fd, runtime); /* Check if the current thread has a Python thread state and holds the GIL. @@ -2261,8 +2699,17 @@ fatal_error(FILE *stream, 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); + PyInterpreterState *interp = NULL; PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); + if (tstate != NULL) { + interp = tstate->interp; + } + else if (tss_tstate != NULL) { + interp = tss_tstate->interp; + } int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate); + if (has_tstate_and_gil) { /* If an exception is set, print the exception with its traceback */ if (!_Py_FatalError_PrintExc(tss_tstate)) { @@ -2274,6 +2721,8 @@ fatal_error(FILE *stream, int header, const char *prefix, const char *msg, _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); } + _Py_DumpExtensionModules(fd, interp); + /* The main purpose of faulthandler is to display the traceback. This function already did its best to display a traceback. Disable faulthandler to prevent writing a second traceback @@ -2299,14 +2748,14 @@ fatal_error(FILE *stream, int header, const char *prefix, const char *msg, void _Py_NO_RETURN Py_FatalError(const char *msg) { - fatal_error(stderr, 1, NULL, msg, -1); + fatal_error(fileno(stderr), 1, NULL, msg, -1); } void _Py_NO_RETURN _Py_FatalErrorFunc(const char *func, const char *msg) { - fatal_error(stderr, 1, func, msg, -1); + fatal_error(fileno(stderr), 1, func, msg, -1); } @@ -2321,12 +2770,12 @@ _Py_FatalErrorFormat(const char *func, const char *format, ...) reentrant = 1; FILE *stream = stderr; - fprintf(stream, "Fatal Python error: "); + const int fd = fileno(stream); + PUTS(fd, "Fatal Python error: "); if (func) { - fputs(func, stream); - fputs(": ", stream); + PUTS(fd, func); + PUTS(fd, ": "); } - fflush(stream); va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES @@ -2340,7 +2789,7 @@ _Py_FatalErrorFormat(const char *func, const char *format, ...) fputs("\n", stream); fflush(stream); - fatal_error(stream, 0, NULL, NULL, -1); + fatal_error(fd, 0, NULL, NULL, -1); } @@ -2351,37 +2800,13 @@ Py_ExitStatusException(PyStatus status) exit(status.exitcode); } else if (_PyStatus_IS_ERROR(status)) { - fatal_error(stderr, 1, status.func, status.err_msg, 1); + fatal_error(fileno(stderr), 1, status.func, status.err_msg, 1); } else { Py_FatalError("Py_ExitStatusException() must not be called on success"); } } -/* Clean up and exit */ - -/* For the atexit module. */ -void _Py_PyAtExit(void (*func)(PyObject *), PyObject *module) -{ - PyInterpreterState *is = _PyInterpreterState_GET(); - - /* Guard against API misuse (see bpo-17852) */ - assert(is->pyexitfunc == NULL || is->pyexitfunc == func); - - is->pyexitfunc = func; - is->pyexitmodule = module; -} - -static void -call_py_exitfuncs(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - if (interp->pyexitfunc == NULL) - return; - - (*interp->pyexitfunc)(interp->pyexitmodule); - _PyErr_Clear(tstate); -} /* Wait until threading._shutdown completes, provided the threading module was imported in the first place. @@ -2446,29 +2871,6 @@ Py_Exit(int sts) } -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. - * - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - * - * If this function is updated, update also _posix_spawn() of subprocess.py. - */ -void -_Py_RestoreSignals(void) -{ -#ifdef SIGPIPE - PyOS_setsig(SIGPIPE, SIG_DFL); -#endif -#ifdef SIGXFZ - PyOS_setsig(SIGXFZ, SIG_DFL); -#endif -#ifdef SIGXFSZ - PyOS_setsig(SIGXFSZ, SIG_DFL); -#endif -} - - /* * The file descriptor fd is considered ``interactive'' if either * a) isatty(fd) is TRUE, or @@ -2488,6 +2890,21 @@ Py_FdIsInteractive(FILE *fp, const char *filename) } +int +_Py_FdIsInteractive(FILE *fp, PyObject *filename) +{ + if (isatty((int)fileno(fp))) { + return 1; + } + if (!Py_InteractiveFlag) { + return 0; + } + return (filename == NULL) || + (PyUnicode_CompareWithASCIIString(filename, "") == 0) || + (PyUnicode_CompareWithASCIIString(filename, "???") == 0); +} + + /* Wrappers around sigaction() or signal(). */ PyOS_sighandler_t @@ -2540,7 +2957,10 @@ PyOS_setsig(int sig, PyOS_sighandler_t handler) struct sigaction context, ocontext; context.sa_handler = handler; sigemptyset(&context.sa_mask); - context.sa_flags = 0; + /* Using SA_ONSTACK is friendlier to other C/C++/Golang-VM code that + * extension module or embedding code may use where tiny thread stacks + * are used. https://bugs.python.org/issue43390 */ + context.sa_flags = SA_ONSTACK; if (sigaction(sig, &context, &ocontext) == -1) return SIG_ERR; return ocontext.sa_handler; diff --git a/contrib/tools/python3/src/Python/pymath.c b/contrib/tools/python3/src/Python/pymath.c index a08a0e79615..24b804223ee 100644 --- a/contrib/tools/python3/src/Python/pymath.c +++ b/contrib/tools/python3/src/Python/pymath.c @@ -79,18 +79,3 @@ round(double x) return copysign(y, x); } #endif /* HAVE_ROUND */ - -static const unsigned int BitLengthTable[32] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 -}; - -unsigned int _Py_bit_length(unsigned long d) { - unsigned int d_bits = 0; - while (d >= 32) { - d_bits += 6; - d >>= 6; - } - d_bits += BitLengthTable[d]; - return d_bits; -} diff --git a/contrib/tools/python3/src/Python/pystate.c b/contrib/tools/python3/src/Python/pystate.c index c3520c336a7..df98eb11bb0 100644 --- a/contrib/tools/python3/src/Python/pystate.c +++ b/contrib/tools/python3/src/Python/pystate.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_ceval.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() @@ -53,6 +54,9 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) 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; + // 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; memset(runtime, 0, sizeof(*runtime)); @@ -73,18 +77,24 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) runtime->interpreters.mutex = PyThread_allocate_lock(); if (runtime->interpreters.mutex == NULL) { - return _PyStatus_ERR("Can't initialize threads for interpreter"); + return _PyStatus_NO_MEMORY(); } runtime->interpreters.next_id = -1; runtime->xidregistry.mutex = PyThread_allocate_lock(); if (runtime->xidregistry.mutex == NULL) { - return _PyStatus_ERR("Can't initialize threads for cross-interpreter data registry"); + return _PyStatus_NO_MEMORY(); } // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); + runtime->unicode_ids.lock = PyThread_allocate_lock(); + if (runtime->unicode_ids.lock == NULL) { + return _PyStatus_NO_MEMORY(); + } + runtime->unicode_ids.next_index = unicode_next_index; + return _PyStatus_OK(); } @@ -108,26 +118,24 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) /* Force the allocator used by _PyRuntimeState_Init(). */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (runtime->interpreters.mutex != NULL) { - PyThread_free_lock(runtime->interpreters.mutex); - runtime->interpreters.mutex = NULL; +#define FREE_LOCK(LOCK) \ + if (LOCK != NULL) { \ + PyThread_free_lock(LOCK); \ + LOCK = NULL; \ } - if (runtime->xidregistry.mutex != NULL) { - PyThread_free_lock(runtime->xidregistry.mutex); - runtime->xidregistry.mutex = NULL; - } + FREE_LOCK(runtime->interpreters.mutex); + FREE_LOCK(runtime->xidregistry.mutex); + FREE_LOCK(runtime->unicode_ids.lock); +#undef FREE_LOCK PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } #ifdef HAVE_FORK /* This function is called from PyOS_AfterFork_Child to ensure that - * newly created child processes do not share locks with the parent. - */ - -void + newly created child processes do not share locks with the parent. */ +PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) { // This was initially set in _PyRuntimeState_Init(). @@ -138,26 +146,25 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - int interp_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); - int xidregistry_mutex = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); + 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); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does * not force the default allocator. */ - int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); + int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); - if (interp_mutex < 0) { - Py_FatalError("Can't initialize lock for runtime interpreters"); - } - - if (main_interp_id_mutex < 0) { - Py_FatalError("Can't initialize ID lock for main interpreter"); - } + if (reinit_interp < 0 + || reinit_main_id < 0 + || reinit_xidregistry < 0 + || reinit_unicode_ids < 0) + { + return _PyStatus_ERR("Failed to reinitialize runtime locks"); - if (xidregistry_mutex < 0) { - Py_FatalError("Can't initialize lock for cross-interpreter data registry"); } + return _PyStatus_OK(); } #endif @@ -223,6 +230,7 @@ PyInterpreterState_New(void) _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); + _PyType_InitCache(interp); interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN @@ -276,14 +284,11 @@ out_of_memory: } -void -PyInterpreterState_Clear(PyInterpreterState *interp) +static void +interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) { _PyRuntimeState *runtime = interp->runtime; - /* Use the current Python thread state to call audit hooks, - not the current Python thread state of 'interp'. */ - PyThreadState *tstate = _PyThreadState_GET(); if (_PySys_Audit(tstate, "cpython.PyInterpreterState_Clear", NULL) < 0) { _PyErr_Clear(tstate); } @@ -302,8 +307,6 @@ PyInterpreterState_Clear(PyInterpreterState *interp) Py_CLEAR(interp->codec_error_registry); Py_CLEAR(interp->modules); Py_CLEAR(interp->modules_by_index); - Py_CLEAR(interp->sysdict); - Py_CLEAR(interp->builtins); Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->importlib); Py_CLEAR(interp->import_func); @@ -313,15 +316,52 @@ PyInterpreterState_Clear(PyInterpreterState *interp) Py_CLEAR(interp->after_forkers_parent); Py_CLEAR(interp->after_forkers_child); #endif - if (_PyRuntimeState_GetFinalizing(runtime) == NULL) { - _PyWarnings_Fini(interp); - } + + _PyAST_Fini(interp); + _PyWarnings_Fini(interp); + _PyAtExit_Fini(interp); + + // All Python types must be destroyed before the last GC collection. Python + // types create a reference cycle to themselves in their in their + // PyTypeObject.tp_mro member (the tuple contains the type). + + /* Last garbage collection on this interpreter */ + _PyGC_CollectNoFail(tstate); + _PyGC_Fini(interp); + + /* We don't clear sysdict and builtins until the end of this function. + Because clearing other attributes can execute arbitrary Python code + which requires sysdict and builtins. */ + PyDict_Clear(interp->sysdict); + PyDict_Clear(interp->builtins); + Py_CLEAR(interp->sysdict); + Py_CLEAR(interp->builtins); + // 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. } +void +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(); + + interpreter_clear(interp, current_tstate); +} + + +void +_PyInterpreterState_Clear(PyThreadState *tstate) +{ + interpreter_clear(tstate->interp, tstate); +} + + static void zapthreads(PyInterpreterState *interp, int check_current) { @@ -376,11 +416,12 @@ PyInterpreterState_Delete(PyInterpreterState *interp) } +#ifdef HAVE_FORK /* * Delete all interpreter states except the main interpreter. If there * is a current interpreter state, it *must* be the main interpreter. */ -void +PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) { struct _gilstate_runtime_state *gilstate = &runtime->gilstate; @@ -388,7 +429,7 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL); if (tstate != NULL && tstate->interp != interpreters->main) { - Py_FatalError("not main interpreter"); + return _PyStatus_ERR("not main interpreter"); } HEAD_LOCK(runtime); @@ -414,10 +455,12 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) HEAD_UNLOCK(runtime); if (interpreters->head == NULL) { - Py_FatalError("missing main interpreter"); + return _PyStatus_ERR("missing main interpreter"); } _PyThreadState_Swap(gilstate, tstate); + return _PyStatus_OK(); } +#endif PyInterpreterState * @@ -496,24 +539,25 @@ _PyInterpreterState_IDInitref(PyInterpreterState *interp) } -void +int _PyInterpreterState_IDIncref(PyInterpreterState *interp) { - if (interp->id_mutex == NULL) { - return; + if (_PyInterpreterState_IDInitref(interp) < 0) { + return -1; } + PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); interp->id_refcount += 1; PyThread_release_lock(interp->id_mutex); + return 0; } void _PyInterpreterState_IDDecref(PyInterpreterState *interp) { - if (interp->id_mutex == NULL) { - return; - } + assert(interp->id_mutex != NULL); + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); @@ -579,11 +623,11 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->frame = NULL; tstate->recursion_depth = 0; - tstate->overflowed = 0; - tstate->recursion_critical = 0; + tstate->recursion_headroom = 0; tstate->stackcheck_counter = 0; tstate->tracing = 0; - tstate->use_tracing = 0; + tstate->root_cframe.use_tracing = 0; + tstate->cframe = &tstate->root_cframe; tstate->gilstate_counter = 0; tstate->async_exc = NULL; tstate->thread_id = PyThread_get_thread_ident(); @@ -753,7 +797,7 @@ PyState_RemoveModule(struct PyModuleDef* def) return PyList_SetItem(interp->modules_by_index, index, Py_None); } -/* Used by PyImport_Cleanup() */ +// Used by finalize_modules() void _PyInterpreterState_ClearModules(PyInterpreterState *interp) { @@ -949,6 +993,14 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) } +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS +PyThreadState* +_PyThreadState_GetTSS(void) { + return PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey); +} +#endif + + PyThreadState * _PyThreadState_UncheckedGet(void) { @@ -968,7 +1020,11 @@ PyThreadState_Get(void) PyThreadState * _PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts) { +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + PyThreadState *oldts = _PyThreadState_GetTSS(); +#else PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate); +#endif _PyRuntimeGILState_SetThreadState(gilstate, newts); /* It should not be possible for more than one thread state @@ -986,6 +1042,9 @@ _PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *new Py_FatalError("Invalid thread state for this thread"); errno = err; } +#endif +#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + PyThread_tss_set(&gilstate->autoTSSkey, newts); #endif return oldts; } @@ -1092,7 +1151,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) HEAD_UNLOCK(runtime); Py_XDECREF(old_exc); - _PyEval_SignalAsyncExc(tstate); + _PyEval_SignalAsyncExc(tstate->interp); return 1; } HEAD_UNLOCK(runtime); @@ -1185,6 +1244,69 @@ done: return result; } +PyObject * +_PyThread_CurrentExceptions(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + + _Py_EnsureTstateNotNULL(tstate); + + if (_PySys_Audit(tstate, "sys._current_exceptions", NULL) < 0) { + return NULL; + } + + PyObject *result = PyDict_New(); + if (result == NULL) { + return NULL; + } + + /* for i in all interpreters: + * for t in all of i's thread states: + * if t's frame isn't NULL, map t's id to its frame + * 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->tstate_head; t != NULL; t = t->next) { + _PyErr_StackItem *err_info = _PyErr_GetTopmostException(t); + if (err_info == NULL) { + continue; + } + PyObject *id = PyLong_FromUnsignedLong(t->thread_id); + if (id == NULL) { + goto fail; + } + PyObject *exc_info = PyTuple_Pack( + 3, + err_info->exc_type != NULL ? err_info->exc_type : Py_None, + err_info->exc_value != NULL ? err_info->exc_value : Py_None, + err_info->exc_traceback != NULL ? err_info->exc_traceback : Py_None); + if (exc_info == NULL) { + Py_DECREF(id); + goto fail; + } + int stat = PyDict_SetItem(result, id, exc_info); + Py_DECREF(id); + Py_DECREF(exc_info); + if (stat < 0) { + goto fail; + } + } + } + goto done; + +fail: + Py_CLEAR(result); + +done: + HEAD_UNLOCK(runtime); + return result; +} + /* Python "auto thread state" API. */ /* Keep this as a static, as it is not reliable! It can only @@ -1208,9 +1330,23 @@ PyThreadState_IsCurrent(PyThreadState *tstate) Py_Initialize/Py_FinalizeEx */ PyStatus -_PyGILState_Init(PyThreadState *tstate) +_PyGILState_Init(_PyRuntimeState *runtime) +{ + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { + return _PyStatus_NO_MEMORY(); + } + // PyThreadState_New() calls _PyGILState_NoteThreadState() which does + // nothing before autoInterpreterState is set. + assert(gilstate->autoInterpreterState == NULL); + return _PyStatus_OK(); +} + + +PyStatus +_PyGILState_SetTstate(PyThreadState *tstate) { - if (!_Py_IsMainInterpreter(tstate)) { + if (!_Py_IsMainInterpreter(tstate->interp)) { /* Currently, PyGILState is shared by all interpreters. The main * interpreter is responsible to initialize it. */ return _PyStatus_OK(); @@ -1222,9 +1358,6 @@ _PyGILState_Init(PyThreadState *tstate) struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - return _PyStatus_NO_MEMORY(); - } gilstate->autoInterpreterState = tstate->interp; assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); assert(tstate->gilstate_counter == 0); @@ -1240,18 +1373,19 @@ _PyGILState_GetInterpreterStateUnsafe(void) } void -_PyGILState_Fini(PyThreadState *tstate) +_PyGILState_Fini(PyInterpreterState *interp) { - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; + 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. */ -void +PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime) { struct _gilstate_runtime_state *gilstate = &runtime->gilstate; @@ -1259,7 +1393,7 @@ _PyGILState_Reinit(_PyRuntimeState *runtime) PyThread_tss_delete(&gilstate->autoTSSkey); if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - Py_FatalError("Could not allocate TSS entry"); + return _PyStatus_NO_MEMORY(); } /* If the thread had an associated auto thread state, reassociate it with @@ -1267,9 +1401,11 @@ _PyGILState_Reinit(_PyRuntimeState *runtime) if (tstate && PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0) { - Py_FatalError("Couldn't create autoTSSkey mapping"); + 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 @@ -1356,7 +1492,9 @@ PyGILState_Ensure(void) /* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been called by Py_Initialize() */ +#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS assert(_PyEval_ThreadsInitialized(runtime)); +#endif assert(gilstate->autoInterpreterState); PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); @@ -1812,11 +1950,17 @@ _PyInterpreterState_GetConfig(PyInterpreterState *interp) } -PyStatus -_PyInterpreterState_SetConfig(PyInterpreterState *interp, - const PyConfig *config) +int +_PyInterpreterState_GetConfigCopy(PyConfig *config) { - return _PyConfig_Copy(&interp->config, config); + PyInterpreterState *interp = PyInterpreterState_Get(); + + PyStatus status = _PyConfig_Copy(config, &interp->config); + if (PyStatus_Exception(status)) { + _PyErr_SetFromPyStatus(status); + return -1; + } + return 0; } diff --git a/contrib/tools/python3/src/Python/pystrtod.c b/contrib/tools/python3/src/Python/pystrtod.c index 1c8202c7761..9145d4eba12 100644 --- a/contrib/tools/python3/src/Python/pystrtod.c +++ b/contrib/tools/python3/src/Python/pystrtod.c @@ -255,7 +255,7 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) char *copy, *c; /* Create a copy of the input, with the '.' converted to the locale-specific decimal point */ - copy = (char *)PyMem_MALLOC(end - digits_pos + + copy = (char *)PyMem_Malloc(end - digits_pos + 1 + decimal_point_len); if (copy == NULL) { *endptr = (char *)nptr; @@ -286,7 +286,7 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) (fail_pos - copy); } - PyMem_FREE(copy); + PyMem_Free(copy); } else { diff --git a/contrib/tools/python3/src/Python/pythonrun.c b/contrib/tools/python3/src/Python/pythonrun.c index 364101e99de..0f1794acec7 100644 --- a/contrib/tools/python3/src/Python/pythonrun.c +++ b/contrib/tools/python3/src/Python/pythonrun.c @@ -10,28 +10,22 @@ #include "Python.h" -#include "Python-ast.h" -#undef Yield /* undefine macro conflicting with */ - +#include "pycore_ast.h" // PyAST_mod2obj +#include "pycore_compile.h" // _PyAST_Compile() #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_object.h" // _PyDebug_PrintTotalRefs(), // _PyType_GetQualName() -#include "pycore_pyerrors.h" // _PyErr_Fetch +#include "pycore_parser.h" // _PyParser_ASTFromString() +#include "pycore_pyerrors.h" // _PyErr_Fetch, _Py_Offer_Suggestions #include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_sysmodule.h" // _PySys_Audit() -#include "node.h" // node #include "token.h" // INDENT -#include "parsetok.h" // perrdetail #include "errcode.h" // E_EOF #include "code.h" // PyCodeObject -#include "symtable.h" // PySymtable_BuildObject() -#include "ast.h" // PyAST_FromNodeObject() #include "marshal.h" // PyMarshal_ReadLongFromFile() -#include "pegen_interface.h" // PyPegen_ASTFrom* - #ifdef MS_WINDOWS # include "malloc.h" // alloca() #endif @@ -59,60 +53,81 @@ _Py_static_string(PyId_string, ""); extern "C" { #endif -extern Py_EXPORTED_SYMBOL grammar _PyParser_Grammar; /* From graminit.c */ - /* Forward */ static void flush_io(void); static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, PyCompilerFlags *, PyArena *); static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *, PyCompilerFlags *); -static void err_input(perrdetail *); -static void err_free(perrdetail *); static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *); static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags); -/* Parse input from a file and execute it */ int -PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, +_PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit, PyCompilerFlags *flags) { - if (filename == NULL) - filename = "???"; - if (Py_FdIsInteractive(fp, filename)) { - int err = PyRun_InteractiveLoopFlags(fp, filename, flags); - if (closeit) + int decref_filename = 0; + if (filename == NULL) { + filename = PyUnicode_FromString("???"); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + decref_filename = 1; + } + + int res; + if (_Py_FdIsInteractive(fp, filename)) { + res = _PyRun_InteractiveLoopObject(fp, filename, flags); + if (closeit) { fclose(fp); - return err; + } } - else - return PyRun_SimpleFileExFlags(fp, filename, closeit, flags); + else { + res = _PyRun_SimpleFileObject(fp, filename, closeit, flags); + } + + if (decref_filename) { + Py_DECREF(filename); + } + return res; } + +/* Parse input from a file and execute it */ int -PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) +PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, + PyCompilerFlags *flags) { - PyObject *filename, *v; - int ret, err; - PyCompilerFlags local_flags = _PyCompilerFlags_INIT; - int nomem_count = 0; -#ifdef Py_REF_DEBUG - int show_ref_count = _Py_GetConfig()->show_ref_count; -#endif - - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) { - PyErr_Print(); - return -1; + PyObject *filename_obj; + if (filename != NULL) { + filename_obj = PyUnicode_DecodeFSDefault(filename); + if (filename_obj == NULL) { + PyErr_Print(); + return -1; + } } + else { + filename_obj = NULL; + } + int res = _PyRun_AnyFileObject(fp, filename_obj, closeit, flags); + Py_XDECREF(filename_obj); + return res; +} + +int +_PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) +{ + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; if (flags == NULL) { flags = &local_flags; } - v = _PySys_GetObjectId(&PyId_ps1); + + PyObject *v = _PySys_GetObjectId(&PyId_ps1); if (v == NULL) { _PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> ")); Py_XDECREF(v); @@ -122,7 +137,13 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * _PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... ")); Py_XDECREF(v); } - err = 0; + +#ifdef Py_REF_DEBUG + int show_ref_count = _Py_GetConfig()->show_ref_count; +#endif + int err = 0; + int ret; + int nomem_count = 0; do { ret = PyRun_InteractiveOneObjectEx(fp, filename, flags); if (ret == -1 && PyErr_Occurred()) { @@ -149,35 +170,25 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * } #endif } while (ret != E_EOF); - Py_DECREF(filename); return err; } -/* compute parser flags based on compiler flags */ -static int PARSER_FLAGS(PyCompilerFlags *flags) + +int +PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) { - int parser_flags = 0; - if (!flags) - return 0; - if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT) - parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; - if (flags->cf_flags & PyCF_IGNORE_COOKIE) - parser_flags |= PyPARSE_IGNORE_COOKIE; - if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) - parser_flags |= PyPARSE_BARRY_AS_BDFL; - if (flags->cf_flags & PyCF_TYPE_COMMENTS) - parser_flags |= PyPARSE_TYPE_COMMENTS; - return parser_flags; + PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); + if (filename_obj == NULL) { + PyErr_Print(); + return -1; + } + + int err = _PyRun_InteractiveLoopObject(fp, filename_obj, flags); + Py_DECREF(filename_obj); + return err; + } -#if 0 -/* Keep an example of flags with future keyword support. */ -#define PARSER_FLAGS(flags) \ - ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \ - PyPARSE_DONT_IMPLY_DEDENT : 0) \ - | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \ - PyPARSE_WITH_IS_KEYWORD : 0)) : 0) -#endif /* A PyRun_InteractiveOneObject() auxiliary function that does not print the * error on failure. */ @@ -190,7 +201,6 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, PyArena *arena; const char *ps1 = "", *ps2 = "", *enc = NULL; int errcode = 0; - int use_peg = _PyInterpreterState_GET()->config._use_peg_parser; _Py_IDENTIFIER(encoding); _Py_IDENTIFIER(__main__); @@ -236,7 +246,7 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } } } - arena = PyArena_New(); + arena = _PyArena_New(); if (arena == NULL) { Py_XDECREF(v); Py_XDECREF(w); @@ -244,21 +254,14 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, return -1; } - if (use_peg) { - mod = PyPegen_ASTFromFileObject(fp, filename, Py_single_input, - enc, ps1, ps2, flags, &errcode, arena); - } - else { - mod = PyParser_ASTFromFileObject(fp, filename, enc, - Py_single_input, ps1, ps2, - flags, &errcode, arena); - } + mod = _PyParser_ASTFromFile(fp, filename, enc, Py_single_input, + ps1, ps2, flags, &errcode, arena); Py_XDECREF(v); Py_XDECREF(w); Py_XDECREF(oenc); if (mod == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); if (errcode == E_EOF) { PyErr_Clear(); return E_EOF; @@ -267,12 +270,12 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } m = PyImport_AddModuleObject(mod_name); if (m == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); return -1; } d = PyModule_GetDict(m); v = run_mod(mod, filename, d, d, flags, arena); - PyArena_Free(arena); + _PyArena_Free(arena); if (v == NULL) { return -1; } @@ -392,9 +395,9 @@ set_main_loader(PyObject *d, PyObject *filename, const char *loader_name) } -static int -pyrun_simple_file(FILE *fp, PyObject *filename, int closeit, - PyCompilerFlags *flags) +int +_PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, + PyCompilerFlags *flags) { PyObject *m, *d, *v; int set_file_name = 0, ret = -1; @@ -404,7 +407,10 @@ pyrun_simple_file(FILE *fp, PyObject *filename, int closeit, return -1; Py_INCREF(m); d = PyModule_GetDict(m); - if (PyDict_GetItemString(d, "__file__") == NULL) { + if (_PyDict_GetItemStringWithError(d, "__file__") == NULL) { + if (PyErr_Occurred()) { + goto done; + } if (PyDict_SetItemString(d, "__file__", filename) < 0) { goto done; } @@ -480,7 +486,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, if (filename_obj == NULL) { return -1; } - int res = pyrun_simple_file(fp, filename_obj, closeit, flags); + int res = _PyRun_SimpleFileObject(fp, filename_obj, closeit, flags); Py_DECREF(filename_obj); return res; } @@ -505,7 +511,9 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) static int parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, - Py_ssize_t *lineno, Py_ssize_t *offset, PyObject **text) + Py_ssize_t *lineno, Py_ssize_t *offset, + Py_ssize_t* end_lineno, Py_ssize_t* end_offset, + PyObject **text) { Py_ssize_t hold; PyObject *v; @@ -513,6 +521,8 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, _Py_IDENTIFIER(filename); _Py_IDENTIFIER(lineno); _Py_IDENTIFIER(offset); + _Py_IDENTIFIER(end_lineno); + _Py_IDENTIFIER(end_offset); _Py_IDENTIFIER(text); *message = NULL; @@ -560,6 +570,44 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, *offset = hold; } + if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) { + v = _PyObject_GetAttrId(err, &PyId_end_lineno); + if (!v) { + PyErr_Clear(); + *end_lineno = *lineno; + } + else if (v == Py_None) { + *end_lineno = *lineno; + Py_DECREF(v); + } else { + hold = PyLong_AsSsize_t(v); + Py_DECREF(v); + if (hold < 0 && PyErr_Occurred()) + goto finally; + *end_lineno = hold; + } + + v = _PyObject_GetAttrId(err, &PyId_end_offset); + if (!v) { + PyErr_Clear(); + *end_offset = -1; + } + else if (v == Py_None) { + *end_offset = -1; + Py_DECREF(v); + } else { + hold = PyLong_AsSsize_t(v); + Py_DECREF(v); + if (hold < 0 && PyErr_Occurred()) + goto finally; + *end_offset = hold; + } + } else { + // SyntaxError subclasses + *end_lineno = *lineno; + *end_offset = -1; + } + v = _PyObject_GetAttrId(err, &PyId_text); if (!v) goto finally; @@ -579,8 +627,9 @@ finally: } static void -print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj) +print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, PyObject *text_obj) { + size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ? end_offset - offset : 1; /* Convert text to a char pointer; return if error */ const char *text = PyUnicode_AsUTF8(text_obj); if (text == NULL) @@ -640,7 +689,10 @@ print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj) while (--offset >= 0) { PyFile_WriteString(" ", f); } - PyFile_WriteString("^\n", f); + for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) { + PyFile_WriteString("^", f); + } + PyFile_WriteString("\n", f); } @@ -838,7 +890,7 @@ static void print_exception(PyObject *f, PyObject *value) { int err = 0; - PyObject *type, *tb; + PyObject *type, *tb, *tmp; _Py_IDENTIFIER(print_file_and_line); if (!PyExceptionInstance_Check(value)) { @@ -857,12 +909,15 @@ print_exception(PyObject *f, PyObject *value) if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && - _PyObject_HasAttrId(value, &PyId_print_file_and_line)) + (err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0) { PyObject *message, *filename, *text; - Py_ssize_t lineno, offset; + Py_ssize_t lineno, offset, end_lineno, end_offset; + err = 0; + Py_DECREF(tmp); if (!parse_syntax_error(value, &message, &filename, - &lineno, &offset, &text)) + &lineno, &offset, + &end_lineno, &end_offset, &text)) PyErr_Clear(); else { PyObject *line; @@ -879,7 +934,21 @@ print_exception(PyObject *f, PyObject *value) } if (text != NULL) { - print_error_text(f, offset, text); + Py_ssize_t line_size; + const char* error_line = PyUnicode_AsUTF8AndSize(text, &line_size); + // If the location of the error spawn multiple lines, we want + // to just print the first one and highlight everything until + // the end of that one since we don't support multi-line error + // messages. + if (end_lineno > lineno) { + end_offset = (error_line != NULL) ? line_size : -1; + } + // Limit the amount of '^' that we can display to + // the size of the text in the source line. + if (error_line != NULL && end_offset > line_size + 1) { + end_offset = line_size + 1; + } + print_error_text(f, offset, end_offset, text); Py_DECREF(text); } @@ -947,6 +1016,18 @@ print_exception(PyObject *f, PyObject *value) if (err < 0) { PyErr_Clear(); } + PyObject* suggestions = _Py_Offer_Suggestions(value); + if (suggestions) { + // Add a trailer ". Did you mean: (...)?" + err = PyFile_WriteString(". Did you mean: '", f); + if (err == 0) { + err = PyFile_WriteObject(suggestions, f, Py_PRINT_RAW); + err += PyFile_WriteString("'?", f); + } + Py_DECREF(suggestions); + } else if (PyErr_Occurred()) { + PyErr_Clear(); + } err += PyFile_WriteString("\n", f); Py_XDECREF(tb); Py_DECREF(value); @@ -1087,26 +1168,20 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, mod_ty mod; PyArena *arena; PyObject *filename; - int use_peg = _PyInterpreterState_GET()->config._use_peg_parser; filename = _PyUnicode_FromId(&PyId_string); /* borrowed */ if (filename == NULL) return NULL; - arena = PyArena_New(); + arena = _PyArena_New(); if (arena == NULL) return NULL; - if (use_peg) { - mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena); - } - else { - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); - } + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod != NULL) ret = run_mod(mod, filename, globals, locals, flags, arena); - PyArena_Free(arena); + _PyArena_Free(arena); return ret; } @@ -1115,21 +1190,14 @@ static PyObject * pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags) { - PyArena *arena = PyArena_New(); + PyArena *arena = _PyArena_New(); if (arena == NULL) { return NULL; } mod_ty mod; - int use_peg = _PyInterpreterState_GET()->config._use_peg_parser; - if (use_peg) { - mod = PyPegen_ASTFromFileObject(fp, filename, start, NULL, NULL, NULL, - flags, NULL, arena); - } - else { - mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, 0, 0, - flags, NULL, arena); - } + mod = _PyParser_ASTFromFile(fp, filename, NULL, start, NULL, NULL, + flags, NULL, arena); if (closeit) { fclose(fp); @@ -1142,7 +1210,7 @@ pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, else { ret = NULL; } - PyArena_Free(arena); + _PyArena_Free(arena); return ret; } @@ -1211,9 +1279,11 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py _Py_UnhandledKeyboardInterrupt = 0; /* Set globals['__builtins__'] if it doesn't exist */ - if (globals != NULL && PyDict_GetItemString(globals, "__builtins__") == NULL) { - if (PyDict_SetItemString(globals, "__builtins__", - tstate->interp->builtins) < 0) { + if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) { + if (PyErr_Occurred() || + PyDict_SetItemString(globals, "__builtins__", + tstate->interp->builtins) < 0) + { return NULL; } } @@ -1230,7 +1300,7 @@ run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, PyCompilerFlags *flags, PyArena *arena) { PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *co = PyAST_CompileObject(mod, filename, flags, -1, arena); + PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena); if (co == NULL) return NULL; @@ -1293,28 +1363,22 @@ Py_CompileStringObject(const char *str, PyObject *filename, int start, { PyCodeObject *co; mod_ty mod; - int use_peg = _PyInterpreterState_GET()->config._use_peg_parser; - PyArena *arena = PyArena_New(); + PyArena *arena = _PyArena_New(); if (arena == NULL) return NULL; - if (use_peg) { - mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena); - } - else { - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); - } + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); return NULL; } if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { PyObject *result = PyAST_mod2obj(mod); - PyArena_Free(arena); + _PyArena_Free(arena); return result; } - co = PyAST_CompileObject(mod, filename, flags, optimize, arena); - PyArena_Free(arena); + co = _PyAST_Compile(mod, filename, flags, optimize, arena); + _PyArena_Free(arena); return (PyObject *)co; } @@ -1331,14 +1395,6 @@ Py_CompileStringExFlags(const char *str, const char *filename_str, int start, return co; } -/* For use in Py_LIMITED_API */ -#undef Py_CompileString -PyObject * -PyCompileString(const char *str, const char *filename, int start) -{ - return Py_CompileStringFlags(str, filename, start, NULL); -} - const char * _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) { @@ -1388,339 +1444,6 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp return str; } -struct symtable * -Py_SymtableStringObject(const char *str, PyObject *filename, int start) -{ - PyCompilerFlags flags = _PyCompilerFlags_INIT; - return _Py_SymtableStringObjectFlags(str, filename, start, &flags); -} - -struct symtable * -_Py_SymtableStringObjectFlags(const char *str, PyObject *filename, int start, PyCompilerFlags *flags) -{ - struct symtable *st; - mod_ty mod; - int use_peg = _PyInterpreterState_GET()->config._use_peg_parser; - PyArena *arena; - - arena = PyArena_New(); - if (arena == NULL) - return NULL; - - if (use_peg) { - mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena); - } - else { - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); - } - if (mod == NULL) { - PyArena_Free(arena); - return NULL; - } - st = PySymtable_BuildObject(mod, filename, 0); - PyArena_Free(arena); - return st; -} - -struct symtable * -Py_SymtableString(const char *str, const char *filename_str, int start) -{ - PyObject *filename; - struct symtable *st; - - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - st = Py_SymtableStringObject(str, filename, start); - Py_DECREF(filename); - return st; -} - -/* Preferred access to parser is through AST. */ -mod_ty -PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start, - PyCompilerFlags *flags, PyArena *arena) -{ - mod_ty mod; - PyCompilerFlags localflags = _PyCompilerFlags_INIT; - perrdetail err; - int iflags = PARSER_FLAGS(flags); - if (flags && (flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7) - iflags |= PyPARSE_ASYNC_HACKS; - - node *n = PyParser_ParseStringObject(s, filename, - &_PyParser_Grammar, start, &err, - &iflags); - if (flags == NULL) { - flags = &localflags; - } - if (n) { - flags->cf_flags |= iflags & PyCF_MASK; - mod = PyAST_FromNodeObject(n, flags, filename, arena); - PyNode_Free(n); - } - else { - err_input(&err); - mod = NULL; - } - err_free(&err); - return mod; -} - -mod_ty -PyParser_ASTFromString(const char *s, const char *filename_str, int start, - PyCompilerFlags *flags, PyArena *arena) -{ - PyObject *filename; - mod_ty mod; - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - mod = PyParser_ASTFromStringObject(s, filename, start, flags, arena); - Py_DECREF(filename); - return mod; -} - -mod_ty -PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc, - int start, const char *ps1, - const char *ps2, PyCompilerFlags *flags, int *errcode, - PyArena *arena) -{ - mod_ty mod; - PyCompilerFlags localflags = _PyCompilerFlags_INIT; - perrdetail err; - int iflags = PARSER_FLAGS(flags); - - node *n = PyParser_ParseFileObject(fp, filename, enc, - &_PyParser_Grammar, - start, ps1, ps2, &err, &iflags); - if (flags == NULL) { - flags = &localflags; - } - if (n) { - flags->cf_flags |= iflags & PyCF_MASK; - mod = PyAST_FromNodeObject(n, flags, filename, arena); - PyNode_Free(n); - } - else { - err_input(&err); - if (errcode) - *errcode = err.error; - mod = NULL; - } - err_free(&err); - return mod; -} - -mod_ty -PyParser_ASTFromFile(FILE *fp, const char *filename_str, const char* enc, - int start, const char *ps1, - const char *ps2, PyCompilerFlags *flags, int *errcode, - PyArena *arena) -{ - mod_ty mod; - PyObject *filename; - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - mod = PyParser_ASTFromFileObject(fp, filename, enc, start, ps1, ps2, - flags, errcode, arena); - Py_DECREF(filename); - return mod; -} - -/* Simplified interface to parsefile -- return node or set exception */ - -node * -PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags) -{ - perrdetail err; - node *n = PyParser_ParseFileFlags(fp, filename, NULL, - &_PyParser_Grammar, - start, NULL, NULL, &err, flags); - if (n == NULL) - err_input(&err); - err_free(&err); - - return n; -} - -/* Simplified interface to parsestring -- return node or set exception */ - -node * -PyParser_SimpleParseStringFlags(const char *str, int start, int flags) -{ - perrdetail err; - node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, - start, &err, flags); - if (n == NULL) - err_input(&err); - err_free(&err); - return n; -} - -node * -PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, - int start, int flags) -{ - perrdetail err; - node *n = PyParser_ParseStringFlagsFilename(str, filename, - &_PyParser_Grammar, start, &err, flags); - if (n == NULL) - err_input(&err); - err_free(&err); - return n; -} - -/* May want to move a more generalized form of this to parsetok.c or - even parser modules. */ - -void -PyParser_ClearError(perrdetail *err) -{ - err_free(err); -} - -void -PyParser_SetError(perrdetail *err) -{ - err_input(err); -} - -static void -err_free(perrdetail *err) -{ - Py_CLEAR(err->filename); -} - -/* Set the error appropriate to the given input error code (see errcode.h) */ - -static void -err_input(perrdetail *err) -{ - PyObject *v, *w, *errtype, *errtext; - PyObject *msg_obj = NULL; - const char *msg = NULL; - int offset = err->offset; - - errtype = PyExc_SyntaxError; - switch (err->error) { - case E_ERROR: - goto cleanup; - case E_SYNTAX: - errtype = PyExc_IndentationError; - if (err->expected == INDENT) - msg = "expected an indented block"; - else if (err->token == INDENT) - msg = "unexpected indent"; - else if (err->token == DEDENT) - msg = "unexpected unindent"; - else if (err->expected == NOTEQUAL) { - errtype = PyExc_SyntaxError; - msg = "with Barry as BDFL, use '<>' instead of '!='"; - } - else { - errtype = PyExc_SyntaxError; - msg = "invalid syntax"; - } - break; - case E_TOKEN: - msg = "invalid token"; - break; - case E_EOFS: - msg = "EOF while scanning triple-quoted string literal"; - break; - case E_EOLS: - msg = "EOL while scanning string literal"; - break; - case E_INTR: - if (!PyErr_Occurred()) - PyErr_SetNone(PyExc_KeyboardInterrupt); - goto cleanup; - case E_NOMEM: - PyErr_NoMemory(); - goto cleanup; - case E_EOF: - msg = "unexpected EOF while parsing"; - break; - case E_TABSPACE: - errtype = PyExc_TabError; - msg = "inconsistent use of tabs and spaces in indentation"; - break; - case E_OVERFLOW: - msg = "expression too long"; - break; - case E_DEDENT: - errtype = PyExc_IndentationError; - msg = "unindent does not match any outer indentation level"; - break; - case E_TOODEEP: - errtype = PyExc_IndentationError; - msg = "too many levels of indentation"; - break; - case E_DECODE: { - PyObject *type, *value, *tb; - PyErr_Fetch(&type, &value, &tb); - msg = "unknown decode error"; - if (value != NULL) - msg_obj = PyObject_Str(value); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(tb); - break; - } - case E_LINECONT: - msg = "unexpected character after line continuation character"; - break; - - case E_BADSINGLE: - msg = "multiple statements found while compiling a single statement"; - break; - default: - fprintf(stderr, "error=%d\n", err->error); - msg = "unknown parsing error"; - break; - } - /* err->text may not be UTF-8 in case of decoding errors. - Explicitly convert to an object. */ - if (!err->text) { - errtext = Py_None; - Py_INCREF(Py_None); - } else { - errtext = PyUnicode_DecodeUTF8(err->text, err->offset, - "replace"); - if (errtext != NULL) { - Py_ssize_t len = strlen(err->text); - offset = (int)PyUnicode_GET_LENGTH(errtext); - if (len != err->offset) { - Py_DECREF(errtext); - errtext = PyUnicode_DecodeUTF8(err->text, len, - "replace"); - } - } - } - v = Py_BuildValue("(OiiN)", err->filename, - err->lineno, offset, errtext); - if (v != NULL) { - if (msg_obj) - w = Py_BuildValue("(OO)", msg_obj, v); - else - w = Py_BuildValue("(sO)", msg, v); - } else - w = NULL; - Py_XDECREF(v); - PyErr_SetObject(errtype, w); - Py_XDECREF(w); -cleanup: - Py_XDECREF(msg_obj); - if (err->text != NULL) { - PyObject_FREE(err->text); - err->text = NULL; - } -} - - #if defined(USE_STACKCHECK) #if defined(WIN32) && defined(_MSC_VER) @@ -1760,20 +1483,6 @@ PyOS_CheckStack(void) /* Deprecated C API functions still provided for binary compatibility */ -#undef PyParser_SimpleParseFile -PyAPI_FUNC(node *) -PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) -{ - return PyParser_SimpleParseFileFlags(fp, filename, start, 0); -} - -#undef PyParser_SimpleParseString -PyAPI_FUNC(node *) -PyParser_SimpleParseString(const char *str, int start) -{ - return PyParser_SimpleParseStringFlags(str, start, 0); -} - #undef PyRun_AnyFile PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name) diff --git a/contrib/tools/python3/src/Python/pytime.c b/contrib/tools/python3/src/Python/pytime.c index a9af7572431..1ef99aee748 100644 --- a/contrib/tools/python3/src/Python/pytime.c +++ b/contrib/tools/python3/src/Python/pytime.c @@ -304,8 +304,8 @@ pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise) if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { if (raise) { _PyTime_overflow(); + res = -1; } - res = -1; t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; } else { @@ -318,8 +318,8 @@ pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise) if (t > _PyTime_MAX - nsec) { if (raise) { _PyTime_overflow(); + res = -1; } - res = -1; t = _PyTime_MAX; } else { @@ -350,8 +350,8 @@ pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise) if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { if (raise) { _PyTime_overflow(); + res = -1; } - res = -1; t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; } else { @@ -364,8 +364,8 @@ pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise) if (t > _PyTime_MAX - usec) { if (raise) { _PyTime_overflow(); + res = -1; } - res = -1; t = _PyTime_MAX; } else { @@ -656,7 +656,7 @@ _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts) #endif static int -pygettimeofday(_PyTime_t *tp, _Py_clock_info_t *info, int raise) +py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) { #ifdef MS_WINDOWS FILETIME system_time; @@ -769,9 +769,10 @@ _PyTime_t _PyTime_GetSystemClock(void) { _PyTime_t t; - if (pygettimeofday(&t, NULL, 0) < 0) { - /* should not happen, _PyTime_Init() checked the clock at startup */ - Py_FatalError("pygettimeofday() failed"); + if (py_get_system_clock(&t, NULL, 0) < 0) { + // If clock_gettime(CLOCK_REALTIME) or gettimeofday() fails: + // silently ignore the failure and return 0. + t = 0; } return t; } @@ -779,11 +780,61 @@ _PyTime_GetSystemClock(void) int _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) { - return pygettimeofday(t, info, 1); + return py_get_system_clock(t, info, 1); } +#if __APPLE__ static int -pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise) +py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) +{ + static mach_timebase_info_data_t timebase; + /* According to the Technical Q&A QA1398, mach_timebase_info() cannot + fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ + (void)mach_timebase_info(&timebase); + + /* Sanity check: should never occur in practice */ + if (timebase.numer < 1 || timebase.denom < 1) { + if (raise) { + PyErr_SetString(PyExc_RuntimeError, + "invalid mach_timebase_info"); + } + return -1; + } + + /* Check that timebase.numer and timebase.denom can be casted to + _PyTime_t. In practice, timebase uses uint32_t, so casting cannot + overflow. At the end, only make sure that the type is uint32_t + (_PyTime_t is 64-bit long). */ + Py_BUILD_ASSERT(sizeof(timebase.numer) < sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(timebase.denom) < sizeof(_PyTime_t)); + + /* Make sure that (ticks * timebase.numer) cannot overflow in + _PyTime_MulDiv(), with ticks < timebase.denom. + + Known time bases: + + * always (1, 1) on Intel + * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC + + None of these time bases can overflow with 64-bit _PyTime_t, but + check for overflow, just in case. */ + if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) { + if (raise) { + PyErr_SetString(PyExc_OverflowError, + "mach_timebase_info is too large"); + } + return -1; + } + + *pnumer = (_PyTime_t)timebase.numer; + *pdenom = (_PyTime_t)timebase.denom; + return 0; +} +#endif + + +static int +py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) { #if defined(MS_WINDOWS) ULONGLONG ticks; @@ -800,10 +851,12 @@ pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise) _PyTime_overflow(); return -1; } - /* Hello, time traveler! */ - Py_FatalError("pymonotonic: integer overflow"); + // Truncate to _PyTime_MAX silently. + *tp = _PyTime_MAX; + } + else { + *tp = t * MS_TO_NS; } - *tp = t * MS_TO_NS; if (info) { DWORD timeAdjustment, timeIncrement; @@ -821,62 +874,23 @@ pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise) } #elif defined(__APPLE__) - static mach_timebase_info_data_t timebase; - static uint64_t t0 = 0; - uint64_t ticks; - - if (timebase.denom == 0) { - /* According to the Technical Q&A QA1398, mach_timebase_info() cannot - fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ - (void)mach_timebase_info(&timebase); - - /* Sanity check: should never occur in practice */ - if (timebase.numer < 1 || timebase.denom < 1) { - PyErr_SetString(PyExc_RuntimeError, - "invalid mach_timebase_info"); - return -1; - } - - /* Check that timebase.numer and timebase.denom can be casted to - _PyTime_t. In practice, timebase uses uint32_t, so casting cannot - overflow. At the end, only make sure that the type is uint32_t - (_PyTime_t is 64-bit long). */ - assert(sizeof(timebase.numer) < sizeof(_PyTime_t)); - assert(sizeof(timebase.denom) < sizeof(_PyTime_t)); - - /* Make sure that (ticks * timebase.numer) cannot overflow in - _PyTime_MulDiv(), with ticks < timebase.denom. - - Known time bases: - - * always (1, 1) on Intel - * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC - - None of these time bases can overflow with 64-bit _PyTime_t, but - check for overflow, just in case. */ - if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) { - PyErr_SetString(PyExc_OverflowError, - "mach_timebase_info is too large"); + static _PyTime_t timebase_numer = 0; + static _PyTime_t timebase_denom = 0; + if (timebase_denom == 0) { + if (py_mach_timebase_info(&timebase_numer, &timebase_denom, raise) < 0) { return -1; } - - t0 = mach_absolute_time(); } if (info) { info->implementation = "mach_absolute_time()"; - info->resolution = (double)timebase.numer / (double)timebase.denom * 1e-9; + info->resolution = (double)timebase_numer / (double)timebase_denom * 1e-9; info->monotonic = 1; info->adjustable = 0; } - ticks = mach_absolute_time(); - /* Use a "time zero" to reduce precision loss when converting time - to floatting point number, as in time.monotonic(). */ - ticks -= t0; - *tp = _PyTime_MulDiv(ticks, - (_PyTime_t)timebase.numer, - (_PyTime_t)timebase.denom); + uint64_t ticks = mach_absolute_time(); + *tp = _PyTime_MulDiv((_PyTime_t)ticks, timebase_numer, timebase_denom); #elif defined(__hpux) hrtime_t time; @@ -940,10 +954,10 @@ _PyTime_t _PyTime_GetMonotonicClock(void) { _PyTime_t t; - if (pymonotonic(&t, NULL, 0) < 0) { - /* should not happen, _PyTime_Init() checked that monotonic clock at - startup */ - Py_FatalError("pymonotonic() failed"); + if (py_get_monotonic_clock(&t, NULL, 0) < 0) { + // If mach_timebase_info(), clock_gettime() or gethrtime() fails: + // silently ignore the failure and return 0. + t = 0; } return t; } @@ -951,56 +965,69 @@ _PyTime_GetMonotonicClock(void) int _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) { - return pymonotonic(tp, info, 1); + return py_get_monotonic_clock(tp, info, 1); } #ifdef MS_WINDOWS static int -win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info) +win_perf_counter_frequency(LONGLONG *pfrequency, int raise) { - static LONGLONG frequency = 0; - static LONGLONG t0 = 0; - LARGE_INTEGER now; - LONGLONG ticksll; - _PyTime_t ticks; + LONGLONG frequency; - if (frequency == 0) { - LARGE_INTEGER freq; - if (!QueryPerformanceFrequency(&freq)) { + LARGE_INTEGER freq; + if (!QueryPerformanceFrequency(&freq)) { + if (raise) { PyErr_SetFromWindowsErr(0); - return -1; } - frequency = freq.QuadPart; + return -1; + } + frequency = freq.QuadPart; - /* Sanity check: should never occur in practice */ - if (frequency < 1) { + /* Sanity check: should never occur in practice */ + if (frequency < 1) { + if (raise) { PyErr_SetString(PyExc_RuntimeError, "invalid QueryPerformanceFrequency"); - return -1; } + return -1; + } - /* Check that frequency can be casted to _PyTime_t. + /* Check that frequency can be casted to _PyTime_t. - Make also sure that (ticks * SEC_TO_NS) cannot overflow in - _PyTime_MulDiv(), with ticks < frequency. + Make also sure that (ticks * SEC_TO_NS) cannot overflow in + _PyTime_MulDiv(), with ticks < frequency. - Known QueryPerformanceFrequency() values: + Known QueryPerformanceFrequency() values: - * 10,000,000 (10 MHz): 100 ns resolution - * 3,579,545 Hz (3.6 MHz): 279 ns resolution + * 10,000,000 (10 MHz): 100 ns resolution + * 3,579,545 Hz (3.6 MHz): 279 ns resolution - None of these frequencies can overflow with 64-bit _PyTime_t, but - check for overflow, just in case. */ - if (frequency > _PyTime_MAX - || frequency > (LONGLONG)_PyTime_MAX / (LONGLONG)SEC_TO_NS) { + None of these frequencies can overflow with 64-bit _PyTime_t, but + check for overflow, just in case. */ + if (frequency > _PyTime_MAX + || frequency > (LONGLONG)_PyTime_MAX / (LONGLONG)SEC_TO_NS) + { + if (raise) { PyErr_SetString(PyExc_OverflowError, "QueryPerformanceFrequency is too large"); - return -1; } + return -1; + } - QueryPerformanceCounter(&now); - t0 = now.QuadPart; + *pfrequency = frequency; + return 0; +} + + +static int +py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise) +{ + static LONGLONG frequency = 0; + if (frequency == 0) { + if (win_perf_counter_frequency(&frequency, raise) < 0) { + return -1; + } } if (info) { @@ -1010,15 +1037,13 @@ win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info) info->adjustable = 0; } + LARGE_INTEGER now; QueryPerformanceCounter(&now); - ticksll = now.QuadPart; - - /* Use a "time zero" to reduce precision loss when converting time - to floatting point number, as in time.perf_counter(). */ - ticksll -= t0; + LONGLONG ticksll = now.QuadPart; /* Make sure that casting LONGLONG to _PyTime_t cannot overflow, both types are signed */ + _PyTime_t ticks; Py_BUILD_ASSERT(sizeof(ticksll) <= sizeof(ticks)); ticks = (_PyTime_t)ticksll; @@ -1032,7 +1057,7 @@ int _PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info) { #ifdef MS_WINDOWS - return win_perf_counter(t, info); + return py_get_win_perf_counter(t, info, 1); #else return _PyTime_GetMonotonicClockWithInfo(t, info); #endif @@ -1043,32 +1068,21 @@ _PyTime_t _PyTime_GetPerfCounter(void) { _PyTime_t t; - if (_PyTime_GetPerfCounterWithInfo(&t, NULL)) { - Py_FatalError("_PyTime_GetPerfCounterWithInfo() failed"); + int res; +#ifdef MS_WINDOWS + res = py_get_win_perf_counter(&t, NULL, 0); +#else + res = py_get_monotonic_clock(&t, NULL, 0); +#endif + if (res < 0) { + // If win_perf_counter_frequency() or py_get_monotonic_clock() fails: + // silently ignore the failure and return 0. + t = 0; } return t; } -int -_PyTime_Init(void) -{ - /* check that time.time(), time.monotonic() and time.perf_counter() clocks - are working properly to not have to check for exceptions at runtime. If - a clock works once, it cannot fail in next calls. */ - _PyTime_t t; - if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0) { - return -1; - } - if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) { - return -1; - } - if (_PyTime_GetPerfCounterWithInfo(&t, NULL) < 0) { - return -1; - } - return 0; -} - int _PyTime_localtime(time_t t, struct tm *tm) { diff --git a/contrib/tools/python3/src/Python/stdlib_module_names.h b/contrib/tools/python3/src/Python/stdlib_module_names.h new file mode 100644 index 00000000000..50cf340e543 --- /dev/null +++ b/contrib/tools/python3/src/Python/stdlib_module_names.h @@ -0,0 +1,308 @@ +// Auto-generated by Tools/scripts/generate_stdlib_module_names.py. +// List used to create sys.stdlib_module_names. + +static const char* _Py_stdlib_module_names[] = { +"__future__", +"_abc", +"_aix_support", +"_ast", +"_asyncio", +"_bisect", +"_blake2", +"_bootsubprocess", +"_bz2", +"_codecs", +"_codecs_cn", +"_codecs_hk", +"_codecs_iso2022", +"_codecs_jp", +"_codecs_kr", +"_codecs_tw", +"_collections", +"_collections_abc", +"_compat_pickle", +"_compression", +"_contextvars", +"_crypt", +"_csv", +"_ctypes", +"_curses", +"_curses_panel", +"_datetime", +"_dbm", +"_decimal", +"_elementtree", +"_frozen_importlib", +"_frozen_importlib_external", +"_functools", +"_gdbm", +"_hashlib", +"_heapq", +"_imp", +"_io", +"_json", +"_locale", +"_lsprof", +"_lzma", +"_markupbase", +"_md5", +"_msi", +"_multibytecodec", +"_multiprocessing", +"_opcode", +"_operator", +"_osx_support", +"_overlapped", +"_pickle", +"_posixshmem", +"_posixsubprocess", +"_py_abc", +"_pydecimal", +"_pyio", +"_queue", +"_random", +"_scproxy", +"_sha1", +"_sha256", +"_sha3", +"_sha512", +"_signal", +"_sitebuiltins", +"_socket", +"_sqlite3", +"_sre", +"_ssl", +"_stat", +"_statistics", +"_string", +"_strptime", +"_struct", +"_symtable", +"_thread", +"_threading_local", +"_tkinter", +"_tracemalloc", +"_uuid", +"_warnings", +"_weakref", +"_weakrefset", +"_winapi", +"_zoneinfo", +"abc", +"aifc", +"antigravity", +"argparse", +"array", +"ast", +"asynchat", +"asyncio", +"asyncore", +"atexit", +"audioop", +"base64", +"bdb", +"binascii", +"binhex", +"bisect", +"builtins", +"bz2", +"cProfile", +"calendar", +"cgi", +"cgitb", +"chunk", +"cmath", +"cmd", +"code", +"codecs", +"codeop", +"collections", +"colorsys", +"compileall", +"concurrent", +"configparser", +"contextlib", +"contextvars", +"copy", +"copyreg", +"crypt", +"csv", +"ctypes", +"curses", +"dataclasses", +"datetime", +"dbm", +"decimal", +"difflib", +"dis", +"distutils", +"doctest", +"email", +"encodings", +"ensurepip", +"enum", +"errno", +"faulthandler", +"fcntl", +"filecmp", +"fileinput", +"fnmatch", +"fractions", +"ftplib", +"functools", +"gc", +"genericpath", +"getopt", +"getpass", +"gettext", +"glob", +"graphlib", +"grp", +"gzip", +"hashlib", +"heapq", +"hmac", +"html", +"http", +"idlelib", +"imaplib", +"imghdr", +"imp", +"importlib", +"inspect", +"io", +"ipaddress", +"itertools", +"json", +"keyword", +"lib2to3", +"linecache", +"locale", +"logging", +"lzma", +"mailbox", +"mailcap", +"marshal", +"math", +"mimetypes", +"mmap", +"modulefinder", +"msilib", +"msvcrt", +"multiprocessing", +"netrc", +"nis", +"nntplib", +"nt", +"ntpath", +"nturl2path", +"numbers", +"opcode", +"operator", +"optparse", +"os", +"ossaudiodev", +"pathlib", +"pdb", +"pickle", +"pickletools", +"pipes", +"pkgutil", +"platform", +"plistlib", +"poplib", +"posix", +"posixpath", +"pprint", +"profile", +"pstats", +"pty", +"pwd", +"py_compile", +"pyclbr", +"pydoc", +"pydoc_data", +"pyexpat", +"queue", +"quopri", +"random", +"re", +"readline", +"reprlib", +"resource", +"rlcompleter", +"runpy", +"sched", +"secrets", +"select", +"selectors", +"shelve", +"shlex", +"shutil", +"signal", +"site", +"smtpd", +"smtplib", +"sndhdr", +"socket", +"socketserver", +"spwd", +"sqlite3", +"sre_compile", +"sre_constants", +"sre_parse", +"ssl", +"stat", +"statistics", +"string", +"stringprep", +"struct", +"subprocess", +"sunau", +"symtable", +"sys", +"sysconfig", +"syslog", +"tabnanny", +"tarfile", +"telnetlib", +"tempfile", +"termios", +"textwrap", +"this", +"threading", +"time", +"timeit", +"tkinter", +"token", +"tokenize", +"trace", +"traceback", +"tracemalloc", +"tty", +"turtle", +"turtledemo", +"types", +"typing", +"unicodedata", +"unittest", +"urllib", +"uu", +"uuid", +"venv", +"warnings", +"wave", +"weakref", +"webbrowser", +"winreg", +"winsound", +"wsgiref", +"xdrlib", +"xml", +"xmlrpc", +"zipapp", +"zipfile", +"zipimport", +"zlib", +"zoneinfo", +}; diff --git a/contrib/tools/python3/src/Python/structmember.c b/contrib/tools/python3/src/Python/structmember.c index ba88e15f938..c7e318811d8 100644 --- a/contrib/tools/python3/src/Python/structmember.c +++ b/contrib/tools/python3/src/Python/structmember.c @@ -5,11 +5,11 @@ #include "structmember.h" // PyMemberDef PyObject * -PyMember_GetOne(const char *addr, PyMemberDef *l) +PyMember_GetOne(const char *obj_addr, PyMemberDef *l) { PyObject *v; - addr += l->offset; + const char* addr = obj_addr + l->offset; switch (l->type) { case T_BOOL: v = PyBool_FromLong(*(char*)addr); @@ -69,8 +69,13 @@ PyMember_GetOne(const char *addr, PyMemberDef *l) break; case T_OBJECT_EX: v = *(PyObject **)addr; - if (v == NULL) - PyErr_SetString(PyExc_AttributeError, l->name); + if (v == NULL) { + PyObject *obj = (PyObject *)obj_addr; + PyTypeObject *tp = Py_TYPE(obj); + PyErr_Format(PyExc_AttributeError, + "'%.200s' object has no attribute '%s'", + tp->tp_name, l->name); + } Py_XINCREF(v); break; case T_LONGLONG: diff --git a/contrib/tools/python3/src/Python/suggestions.c b/contrib/tools/python3/src/Python/suggestions.c new file mode 100644 index 00000000000..4e2f9055779 --- /dev/null +++ b/contrib/tools/python3/src/Python/suggestions.c @@ -0,0 +1,289 @@ +#include "Python.h" +#include "frameobject.h" + +#include "pycore_pyerrors.h" + +#define MAX_CANDIDATE_ITEMS 750 +#define MAX_STRING_SIZE 40 + +#define MOVE_COST 2 +#define CASE_COST 1 + +#define LEAST_FIVE_BITS(n) ((n) & 31) + +static inline int +substitution_cost(char a, char b) +{ + if (LEAST_FIVE_BITS(a) != LEAST_FIVE_BITS(b)) { + // Not the same, not a case flip. + return MOVE_COST; + } + if (a == b) { + return 0; + } + if ('A' <= a && a <= 'Z') { + a += ('a' - 'A'); + } + if ('A' <= b && b <= 'Z') { + b += ('a' - 'A'); + } + if (a == b) { + return CASE_COST; + } + return MOVE_COST; +} + +/* Calculate the Levenshtein distance between string1 and string2 */ +static Py_ssize_t +levenshtein_distance(const char *a, size_t a_size, + const char *b, size_t b_size, + size_t max_cost) +{ + static size_t buffer[MAX_STRING_SIZE]; + + // Both strings are the same (by identity) + if (a == b) { + return 0; + } + + // Trim away common affixes. + while (a_size && b_size && a[0] == b[0]) { + a++; a_size--; + b++; b_size--; + } + while (a_size && b_size && a[a_size-1] == b[b_size-1]) { + a_size--; + b_size--; + } + if (a_size == 0 || b_size == 0) { + return (a_size + b_size) * MOVE_COST; + } + if (a_size > MAX_STRING_SIZE || b_size > MAX_STRING_SIZE) { + return max_cost + 1; + } + + // Prefer shorter buffer + if (b_size < a_size) { + const char *t = a; a = b; b = t; + size_t t_size = a_size; a_size = b_size; b_size = t_size; + } + + // quick fail when a match is impossible. + if ((b_size - a_size) * 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 + for (size_t i = 0; i < a_size; i++) { + // cost from b[:0] to a[:i+1] + buffer[i] = (i + 1) * MOVE_COST; + } + + size_t result = 0; + for (size_t b_index = 0; b_index < b_size; b_index++) { + char code = b[b_index]; + // cost(b[:b_index], a[:0]) == b_index * MOVE_COST + size_t distance = result = b_index * MOVE_COST; + size_t minimum = SIZE_MAX; + for (size_t index = 0; index < a_size; index++) { + + // cost(b[:b_index+1], a[:index+1]) = min( + // // 1) substitute + // cost(b[:b_index], a[:index]) + // + substitution_cost(b[b_index], a[index]), + // // 2) delete from b + // cost(b[:b_index], a[:index+1]) + MOVE_COST, + // // 3) delete from a + // cost(b[:b_index+1], a[index]) + MOVE_COST + // ) + + // 1) Previous distance in this row is cost(b[:b_index], a[:index]) + size_t substitute = distance + substitution_cost(code, a[index]); + // 2) cost(b[:b_index], a[:index+1]) from previous row + distance = buffer[index]; + // 3) existing result is cost(b[:b_index+1], a[index]) + + size_t insert_delete = Py_MIN(result, distance) + MOVE_COST; + result = Py_MIN(insert_delete, substitute); + + // cost(b[:b_index+1], a[:index+1]) + buffer[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; +} + +static inline PyObject * +calculate_suggestions(PyObject *dir, + PyObject *name) +{ + assert(!PyErr_Occurred()); + assert(PyList_CheckExact(dir)); + + Py_ssize_t dir_size = PyList_GET_SIZE(dir); + if (dir_size >= MAX_CANDIDATE_ITEMS) { + return NULL; + } + + Py_ssize_t suggestion_distance = PY_SSIZE_T_MAX; + PyObject *suggestion = NULL; + Py_ssize_t name_size; + const char *name_str = PyUnicode_AsUTF8AndSize(name, &name_size); + if (name_str == NULL) { + return NULL; + } + + for (int i = 0; i < dir_size; ++i) { + PyObject *item = PyList_GET_ITEM(dir, i); + Py_ssize_t item_size; + const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size); + if (item_str == NULL) { + 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); + if (current_distance > max_distance) { + continue; + } + if (!suggestion || current_distance < suggestion_distance) { + suggestion = item; + suggestion_distance = current_distance; + } + } + Py_XINCREF(suggestion); + return suggestion; +} + +static PyObject * +offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) +{ + PyObject *name = exc->name; // borrowed reference + PyObject *obj = exc->obj; // borrowed reference + + // Abort if we don't have an attribute name or we have an invalid one + if (name == NULL || obj == NULL || !PyUnicode_CheckExact(name)) { + return NULL; + } + + PyObject *dir = PyObject_Dir(obj); + if (dir == NULL) { + return NULL; + } + + PyObject *suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + return suggestions; +} + + +static PyObject * +offer_suggestions_for_name_error(PyNameErrorObject *exc) +{ + PyObject *name = exc->name; // borrowed reference + PyTracebackObject *traceback = (PyTracebackObject *) exc->traceback; // borrowed reference + // Abort if we don't have a variable name or we have an invalid one + // or if we don't have a traceback to work with + if (name == NULL || !PyUnicode_CheckExact(name) || + traceback == NULL || !Py_IS_TYPE(traceback, &PyTraceBack_Type) + ) { + return NULL; + } + + // Move to the traceback of the exception + while (1) { + PyTracebackObject *next = traceback->tb_next; + if (next == NULL || !Py_IS_TYPE(next, &PyTraceBack_Type)) { + break; + } + else { + traceback = next; + } + } + + PyFrameObject *frame = traceback->tb_frame; + assert(frame != NULL); + PyCodeObject *code = frame->f_code; + assert(code != NULL && code->co_varnames != NULL); + PyObject *dir = PySequence_List(code->co_varnames); + if (dir == NULL) { + return NULL; + } + + PyObject *suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + if (suggestions != NULL) { + return suggestions; + } + + dir = PySequence_List(frame->f_globals); + if (dir == NULL) { + return NULL; + } + suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + if (suggestions != NULL) { + return suggestions; + } + + dir = PySequence_List(frame->f_builtins); + if (dir == NULL) { + return NULL; + } + suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + + return suggestions; +} + +// Offer suggestions for a given exception. Returns a python string object containing the +// suggestions. This function returns NULL if no suggestion was found or if an exception happened, +// users must call PyErr_Occurred() to disambiguate. +PyObject * +_Py_Offer_Suggestions(PyObject *exception) +{ + PyObject *result = NULL; + assert(!PyErr_Occurred()); + if (Py_IS_TYPE(exception, (PyTypeObject*)PyExc_AttributeError)) { + 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); + } + return result; +} + +Py_ssize_t +_Py_UTF8_Edit_Cost(PyObject *a, PyObject *b, Py_ssize_t max_cost) +{ + assert(PyUnicode_Check(a) && PyUnicode_Check(b)); + Py_ssize_t size_a, size_b; + const char *utf8_a = PyUnicode_AsUTF8AndSize(a, &size_a); + if (utf8_a == NULL) { + return -1; + } + const char *utf8_b = PyUnicode_AsUTF8AndSize(b, &size_b); + if (utf8_b == NULL) { + return -1; + } + 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); +} + diff --git a/contrib/tools/python3/src/Python/symtable.c b/contrib/tools/python3/src/Python/symtable.c index d192f31deef..07f9d1132c7 100644 --- a/contrib/tools/python3/src/Python/symtable.c +++ b/contrib/tools/python3/src/Python/symtable.c @@ -1,7 +1,9 @@ #include "Python.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "symtable.h" -#undef Yield /* undefine macro conflicting with */ +#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 #include "structmember.h" // PyMemberDef /* error strings used for warnings */ @@ -43,9 +45,20 @@ #define NAMED_EXPR_COMP_ITER_EXPR \ "assignment expression cannot be used in a comprehension iterable expression" +#define ANNOTATION_NOT_ALLOWED \ +"'%s' can not be used within an annotation" + + +#define LOCATION(x) \ + (x)->lineno, (x)->col_offset, (x)->end_lineno, (x)->end_col_offset + +#define ST_LOCATION(x) \ + (x)->ste_lineno, (x)->ste_col_offset, (x)->ste_end_lineno, (x)->ste_end_col_offset + static PySTEntryObject * ste_new(struct symtable *st, identifier name, _Py_block_ty block, - void *key, int lineno, int col_offset) + void *key, int lineno, int col_offset, + int end_lineno, int end_col_offset) { PySTEntryObject *ste = NULL; PyObject *k = NULL; @@ -79,6 +92,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_opt_col_offset = 0; ste->ste_lineno = lineno; ste->ste_col_offset = col_offset; + ste->ste_end_lineno = end_lineno; + ste->ste_end_col_offset = end_col_offset; if (st->st_cur != NULL && (st->st_cur->ste_nested || @@ -87,7 +102,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_child_free = 0; ste->ste_generator = 0; ste->ste_coroutine = 0; - ste->ste_comprehension = 0; + ste->ste_comprehension = NoComprehension; ste->ste_returns_value = 0; ste->ste_needs_class_closure = 0; ste->ste_comp_iter_target = 0; @@ -128,7 +143,7 @@ ste_dealloc(PySTEntryObject *ste) Py_XDECREF(ste->ste_varnames); Py_XDECREF(ste->ste_children); Py_XDECREF(ste->ste_directives); - PyObject_Del(ste); + PyObject_Free(ste); } #define OFF(x) offsetof(PySTEntryObject, x) @@ -188,8 +203,9 @@ PyTypeObject PySTEntry_Type = { static int symtable_analyze(struct symtable *st); static int symtable_enter_block(struct symtable *st, identifier name, - _Py_block_ty block, void *ast, int lineno, - int col_offset); + _Py_block_ty block, void *ast, + int lineno, int col_offset, + int end_lineno, int end_col_offset); 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); @@ -202,16 +218,21 @@ static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty); static int symtable_visit_alias(struct symtable *st, alias_ty); static int symtable_visit_comprehension(struct symtable *st, comprehension_ty); static int symtable_visit_keyword(struct symtable *st, keyword_ty); -static int symtable_visit_params(struct symtable *st, asdl_seq *args); -static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args); +static int symtable_visit_params(struct symtable *st, asdl_arg_seq *args); +static int symtable_visit_annotation(struct symtable *st, expr_ty annotation); +static int symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args); static int symtable_implicit_arg(struct symtable *st, int pos); -static int symtable_visit_annotations(struct symtable *st, arguments_ty, expr_ty); +static int symtable_visit_annotations(struct symtable *st, stmt_ty, arguments_ty, expr_ty); static int symtable_visit_withitem(struct symtable *st, withitem_ty item); +static int symtable_visit_match_case(struct symtable *st, match_case_ty m); +static int symtable_visit_pattern(struct symtable *st, pattern_ty s); +static int symtable_raise_if_annotation_block(struct symtable *st, const char *, expr_ty); +static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty); static identifier top = NULL, lambda = NULL, genexpr = NULL, listcomp = NULL, setcomp = NULL, dictcomp = NULL, - __class__ = NULL; + __class__ = NULL, _annotation = NULL; #define GET_IDENTIFIER(VAR) \ ((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR))) @@ -241,7 +262,7 @@ symtable_new(void) st->st_private = NULL; return st; fail: - PySymtable_Free(st); + _PySymtable_Free(st); return NULL; } @@ -258,10 +279,10 @@ symtable_new(void) #define COMPILER_STACK_FRAME_SCALE 3 struct symtable * -PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) +_PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) { struct symtable *st = symtable_new(); - asdl_seq *seq; + asdl_stmt_seq *seq; int i; PyThreadState *tstate; int recursion_limit = Py_GetRecursionLimit(); @@ -270,7 +291,7 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) if (st == NULL) return NULL; if (filename == NULL) { - PySymtable_Free(st); + _PySymtable_Free(st); return NULL; } Py_INCREF(filename); @@ -280,7 +301,7 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) /* Setup recursion depth check counters */ tstate = _PyThreadState_GET(); if (!tstate) { - PySymtable_Free(st); + _PySymtable_Free(st); return NULL; } /* Be careful here to prevent overflow. */ @@ -292,8 +313,8 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) /* Make the initial symbol information gathering pass */ if (!GET_IDENTIFIER(top) || - !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0)) { - PySymtable_Free(st); + !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0, 0, 0)) { + _PySymtable_Free(st); return NULL; } @@ -323,7 +344,7 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) goto error; } if (!symtable_exit_block(st)) { - PySymtable_Free(st); + _PySymtable_Free(st); return NULL; } /* Check that the recursion depth counting balanced correctly */ @@ -331,35 +352,23 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) PyErr_Format(PyExc_SystemError, "symtable analysis recursion depth mismatch (before=%d, after=%d)", starting_recursion_depth, st->recursion_depth); - PySymtable_Free(st); + _PySymtable_Free(st); return NULL; } /* Make the second symbol analysis pass */ if (symtable_analyze(st)) return st; - PySymtable_Free(st); + _PySymtable_Free(st); return NULL; error: (void) symtable_exit_block(st); - PySymtable_Free(st); + _PySymtable_Free(st); return NULL; } -struct symtable * -PySymtable_Build(mod_ty mod, const char *filename_str, PyFutureFeatures *future) -{ - PyObject *filename; - struct symtable *st; - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - st = PySymtable_BuildObject(mod, filename, future); - Py_DECREF(filename); - return st; -} void -PySymtable_Free(struct symtable *st) +_PySymtable_Free(struct symtable *st) { Py_XDECREF(st->st_filename); Py_XDECREF(st->st_blocks); @@ -392,7 +401,7 @@ PySymtable_Lookup(struct symtable *st, void *key) static long _PyST_GetSymbol(PySTEntryObject *ste, PyObject *name) { - PyObject *v = PyDict_GetItem(ste->ste_symbols, name); + PyObject *v = PyDict_GetItemWithError(ste->ste_symbols, name); if (!v) return 0; assert(PyLong_Check(v)); @@ -400,7 +409,7 @@ _PyST_GetSymbol(PySTEntryObject *ste, PyObject *name) } int -PyST_GetScope(PySTEntryObject *ste, PyObject *name) +_PyST_GetScope(PySTEntryObject *ste, PyObject *name) { long symbol = _PyST_GetSymbol(ste, name); return (symbol >> SCOPE_OFFSET) & SCOPE_MASK; @@ -417,9 +426,11 @@ error_at_directive(PySTEntryObject *ste, PyObject *name) assert(PyTuple_CheckExact(data)); assert(PyUnicode_CheckExact(PyTuple_GET_ITEM(data, 0))); if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) { - PyErr_SyntaxLocationObject(ste->ste_table->st_filename, - PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), - PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1); + PyErr_RangedSyntaxLocationObject(ste->ste_table->st_filename, + PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), + PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1, + PyLong_AsLong(PyTuple_GET_ITEM(data, 3)), + PyLong_AsLong(PyTuple_GET_ITEM(data, 4)) + 1); return 0; } @@ -634,7 +645,7 @@ update_symbols(PyObject *symbols, PyObject *scopes, long scope, flags; assert(PyLong_Check(v)); flags = PyLong_AS_LONG(v); - v_scope = PyDict_GetItem(scopes, name); + v_scope = PyDict_GetItemWithError(scopes, name); assert(v_scope && PyLong_Check(v_scope)); scope = PyLong_AS_LONG(v_scope); flags |= (scope << SCOPE_OFFSET); @@ -966,11 +977,12 @@ symtable_exit_block(struct symtable *st) static int symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, - void *ast, int lineno, int col_offset) + void *ast, int lineno, int col_offset, + int end_lineno, int end_col_offset) { PySTEntryObject *prev = NULL, *ste; - ste = ste_new(st, name, block, ast, lineno, col_offset); + ste = ste_new(st, name, block, ast, lineno, col_offset, end_lineno, end_col_offset); if (ste == NULL) return 0; if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) { @@ -988,8 +1000,17 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, /* The entry is owned by the stack. Borrow it for st_cur. */ Py_DECREF(ste); st->st_cur = ste; + + /* Annotation blocks shouldn't have any affect on the symbol table since in + * the compilation stage, they will all be transformed to strings. They are + * only created if future 'annotations' feature is activated. */ + if (block == AnnotationBlock) { + return 1; + } + if (block == ModuleBlock) st->st_global = st->st_cur->ste_symbols; + if (prev) { if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) { return 0; @@ -1010,7 +1031,8 @@ symtable_lookup(struct symtable *st, PyObject *name) } static int -symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste) +symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste, + int lineno, int col_offset, int end_lineno, int end_col_offset) { PyObject *o; PyObject *dict; @@ -1026,9 +1048,9 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s if ((flag & DEF_PARAM) && (val & DEF_PARAM)) { /* Is it better to use 'mangled' or 'name' here? */ PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name); - PyErr_SyntaxLocationObject(st->st_filename, - ste->ste_lineno, - ste->ste_col_offset + 1); + PyErr_RangedSyntaxLocationObject(st->st_filename, + lineno, col_offset + 1, + end_lineno, end_col_offset + 1); goto error; } val |= flag; @@ -1048,9 +1070,9 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s if (val & (DEF_GLOBAL | DEF_NONLOCAL)) { PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name); - PyErr_SyntaxLocationObject(st->st_filename, - ste->ste_lineno, - ste->ste_col_offset + 1); + PyErr_RangedSyntaxLocationObject(st->st_filename, + lineno, col_offset + 1, + end_lineno, end_col_offset + 1); goto error; } val |= DEF_COMP_ITER; @@ -1071,9 +1093,12 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s /* XXX need to update DEF_GLOBAL for other flags too; perhaps only DEF_FREE_GLOBAL */ val = flag; - if ((o = PyDict_GetItem(st->st_global, mangled))) { + if ((o = PyDict_GetItemWithError(st->st_global, mangled))) { val |= PyLong_AS_LONG(o); } + else if (PyErr_Occurred()) { + goto error; + } o = PyLong_FromLong(val); if (o == NULL) goto error; @@ -1092,8 +1117,11 @@ error: } static int -symtable_add_def(struct symtable *st, PyObject *name, int flag) { - return symtable_add_def_helper(st, name, flag, st->st_cur); +symtable_add_def(struct symtable *st, PyObject *name, int flag, + int lineno, int col_offset, int end_lineno, int end_col_offset) +{ + return symtable_add_def_helper(st, name, flag, st->st_cur, + lineno, col_offset, end_lineno, end_col_offset); } /* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument. @@ -1116,7 +1144,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { #define VISIT_SEQ(ST, TYPE, SEQ) { \ int i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + 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 (!symtable_visit_ ## TYPE((ST), elt)) \ @@ -1126,7 +1154,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { #define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \ int i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (i = (START); i < asdl_seq_LEN(seq); i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ if (!symtable_visit_ ## TYPE((ST), elt)) \ @@ -1136,7 +1164,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { #define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) { \ int i = 0; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + 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 (!elt) continue; /* can be NULL */ \ @@ -1146,7 +1174,8 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { } static int -symtable_record_directive(struct symtable *st, identifier name, int lineno, int col_offset) +symtable_record_directive(struct symtable *st, identifier name, int lineno, + int col_offset, int end_lineno, int end_col_offset) { PyObject *data, *mangled; int res; @@ -1158,7 +1187,7 @@ symtable_record_directive(struct symtable *st, identifier name, int lineno, int mangled = _Py_Mangle(st->st_private, name); if (!mangled) return 0; - data = Py_BuildValue("(Nii)", mangled, lineno, col_offset); + data = Py_BuildValue("(Niiii)", mangled, lineno, col_offset, end_lineno, end_col_offset); if (!data) return 0; res = PyList_Append(st->st_cur->ste_directives, data); @@ -1177,20 +1206,20 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } switch (s->kind) { case FunctionDef_kind: - if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL)) + if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s))) VISIT_QUIT(st, 0); if (s->v.FunctionDef.args->defaults) 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 (!symtable_visit_annotations(st, s->v.FunctionDef.args, + 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, s->lineno, - s->col_offset)) + FunctionBlock, (void *)s, + LOCATION(s))) VISIT_QUIT(st, 0); VISIT(st, arguments, s->v.FunctionDef.args); VISIT_SEQ(st, stmt, s->v.FunctionDef.body); @@ -1199,14 +1228,15 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case ClassDef_kind: { PyObject *tmp; - if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL)) + 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 (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, - (void *)s, s->lineno, s->col_offset)) + (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; @@ -1242,19 +1272,21 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) PyErr_Format(PyExc_SyntaxError, cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT, e_name->v.Name.id); - PyErr_SyntaxLocationObject(st->st_filename, - s->lineno, - s->col_offset + 1); + PyErr_RangedSyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset + 1, + s->end_lineno, + s->end_col_offset + 1); VISIT_QUIT(st, 0); } if (s->v.AnnAssign.simple && !symtable_add_def(st, e_name->v.Name.id, - DEF_ANNOT | DEF_LOCAL)) { + DEF_ANNOT | DEF_LOCAL, LOCATION(e_name))) { VISIT_QUIT(st, 0); } else { if (s->v.AnnAssign.value - && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL)) { + && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL, LOCATION(e_name))) { VISIT_QUIT(st, 0); } } @@ -1262,7 +1294,10 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) else { VISIT(st, expr, s->v.AnnAssign.target); } - VISIT(st, expr, s->v.AnnAssign.annotation); + if (!symtable_visit_annotation(st, s->v.AnnAssign.annotation)) { + VISIT_QUIT(st, 0); + } + if (s->v.AnnAssign.value) { VISIT(st, expr, s->v.AnnAssign.value); } @@ -1291,6 +1326,10 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) if (s->v.If.orelse) VISIT_SEQ(st, stmt, s->v.If.orelse); break; + case Match_kind: + VISIT(st, expr, s->v.Match.subject); + VISIT_SEQ(st, match_case, s->v.Match.cases); + break; case Raise_kind: if (s->v.Raise.exc) { VISIT(st, expr, s->v.Raise.exc); @@ -1318,7 +1357,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case Global_kind: { int i; - asdl_seq *seq = s->v.Global.names; + asdl_identifier_seq *seq = s->v.Global.names; for (i = 0; i < asdl_seq_LEN(seq); i++) { identifier name = (identifier)asdl_seq_GET(seq, i); long cur = symtable_lookup(st, name); @@ -1337,21 +1376,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } PyErr_Format(PyExc_SyntaxError, msg, name); - PyErr_SyntaxLocationObject(st->st_filename, - s->lineno, - s->col_offset + 1); + PyErr_RangedSyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset + 1, + s->end_lineno, + s->end_col_offset + 1); VISIT_QUIT(st, 0); } - if (!symtable_add_def(st, name, DEF_GLOBAL)) + if (!symtable_add_def(st, name, DEF_GLOBAL, LOCATION(s))) VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) + if (!symtable_record_directive(st, name, s->lineno, s->col_offset, + s->end_lineno, s->end_col_offset)) VISIT_QUIT(st, 0); } break; } case Nonlocal_kind: { int i; - asdl_seq *seq = s->v.Nonlocal.names; + asdl_identifier_seq *seq = s->v.Nonlocal.names; for (i = 0; i < asdl_seq_LEN(seq); i++) { identifier name = (identifier)asdl_seq_GET(seq, i); long cur = symtable_lookup(st, name); @@ -1369,14 +1411,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) msg = NONLOCAL_AFTER_ASSIGN; } PyErr_Format(PyExc_SyntaxError, msg, name); - PyErr_SyntaxLocationObject(st->st_filename, - s->lineno, - s->col_offset + 1); + PyErr_RangedSyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset + 1, + s->end_lineno, + s->end_col_offset + 1); VISIT_QUIT(st, 0); } - if (!symtable_add_def(st, name, DEF_NONLOCAL)) + if (!symtable_add_def(st, name, DEF_NONLOCAL, LOCATION(s))) VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) + if (!symtable_record_directive(st, name, s->lineno, s->col_offset, + s->end_lineno, s->end_col_offset)) VISIT_QUIT(st, 0); } break; @@ -1394,21 +1439,22 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, stmt, s->v.With.body); break; case AsyncFunctionDef_kind: - if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL)) + if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL, LOCATION(s))) VISIT_QUIT(st, 0); if (s->v.AsyncFunctionDef.args->defaults) VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults); if (s->v.AsyncFunctionDef.args->kw_defaults) VISIT_SEQ_WITH_NULL(st, expr, s->v.AsyncFunctionDef.args->kw_defaults); - if (!symtable_visit_annotations(st, s->v.AsyncFunctionDef.args, + 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)) + FunctionBlock, (void *)s, + s->lineno, s->col_offset, + s->end_lineno, s->end_col_offset)) VISIT_QUIT(st, 0); st->st_cur->ste_coroutine = 1; VISIT(st, arguments, s->v.AsyncFunctionDef.args); @@ -1454,9 +1500,11 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) long target_in_scope = _PyST_GetSymbol(ste, target_name); if (target_in_scope & DEF_COMP_ITER) { PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); - PyErr_SyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); VISIT_QUIT(st, 0); } continue; @@ -1466,32 +1514,34 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) if (ste->ste_type == FunctionBlock) { long target_in_scope = _PyST_GetSymbol(ste, target_name); if (target_in_scope & DEF_GLOBAL) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) VISIT_QUIT(st, 0); } else { - if (!symtable_add_def(st, target_name, DEF_NONLOCAL)) + if (!symtable_add_def(st, target_name, DEF_NONLOCAL, LOCATION(e))) VISIT_QUIT(st, 0); } - if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) + if (!symtable_record_directive(st, target_name, LOCATION(e))) VISIT_QUIT(st, 0); - return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste); + return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste, LOCATION(e)); } /* If we find a ModuleBlock entry, add as GLOBAL */ if (ste->ste_type == ModuleBlock) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) + if (!symtable_record_directive(st, target_name, LOCATION(e))) VISIT_QUIT(st, 0); - return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste); + 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); - PyErr_SyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); VISIT_QUIT(st, 0); } } @@ -1509,9 +1559,11 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty e) if (st->st_cur->ste_comp_iter_expr > 0) { /* Assignment isn't allowed in a comprehension iterable expression */ PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR); - PyErr_SyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); return 0; } if (st->st_cur->ste_comprehension) { @@ -1534,6 +1586,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e) } switch (e->kind) { case NamedExpr_kind: + if (!symtable_raise_if_annotation_block(st, "named expression", e)) { + VISIT_QUIT(st, 0); + } if(!symtable_handle_namedexpr(st, e)) VISIT_QUIT(st, 0); break; @@ -1555,8 +1610,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e) if (e->v.Lambda.args->kw_defaults) VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults); if (!symtable_enter_block(st, lambda, - FunctionBlock, (void *)e, e->lineno, - e->col_offset)) + FunctionBlock, (void *)e, + e->lineno, e->col_offset, + e->end_lineno, e->end_col_offset)) VISIT_QUIT(st, 0); VISIT(st, arguments, e->v.Lambda.args); VISIT(st, expr, e->v.Lambda.body); @@ -1593,15 +1649,30 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_QUIT(st, 0); break; case Yield_kind: + if (!symtable_raise_if_annotation_block(st, "yield expression", e)) { + VISIT_QUIT(st, 0); + } if (e->v.Yield.value) VISIT(st, expr, e->v.Yield.value); st->st_cur->ste_generator = 1; + if (st->st_cur->ste_comprehension) { + return symtable_raise_if_comprehension_block(st, e); + } break; case YieldFrom_kind: + if (!symtable_raise_if_annotation_block(st, "yield expression", e)) { + VISIT_QUIT(st, 0); + } VISIT(st, expr, e->v.YieldFrom.value); st->st_cur->ste_generator = 1; + if (st->st_cur->ste_comprehension) { + return symtable_raise_if_comprehension_block(st, e); + } break; case Await_kind: + if (!symtable_raise_if_annotation_block(st, "await expression", e)) { + VISIT_QUIT(st, 0); + } VISIT(st, expr, e->v.Await.value); st->st_cur->ste_coroutine = 1; break; @@ -1646,14 +1717,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e) break; case Name_kind: if (!symtable_add_def(st, e->v.Name.id, - e->v.Name.ctx == Load ? USE : DEF_LOCAL)) + e->v.Name.ctx == Load ? USE : DEF_LOCAL, LOCATION(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 && _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) { if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, USE)) + !symtable_add_def(st, __class__, USE, LOCATION(e))) VISIT_QUIT(st, 0); } break; @@ -1668,13 +1739,63 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_QUIT(st, 1); } +static int +symtable_visit_pattern(struct symtable *st, pattern_ty p) +{ + if (++st->recursion_depth > st->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + VISIT_QUIT(st, 0); + } + switch (p->kind) { + case MatchValue_kind: + VISIT(st, expr, p->v.MatchValue.value); + break; + case MatchSingleton_kind: + /* Nothing to do here. */ + break; + case MatchSequence_kind: + VISIT_SEQ(st, pattern, p->v.MatchSequence.patterns); + break; + case MatchStar_kind: + if (p->v.MatchStar.name) { + symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p)); + } + break; + case MatchMapping_kind: + VISIT_SEQ(st, expr, p->v.MatchMapping.keys); + VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns); + if (p->v.MatchMapping.rest) { + symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p)); + } + break; + case MatchClass_kind: + VISIT(st, expr, p->v.MatchClass.cls); + VISIT_SEQ(st, pattern, p->v.MatchClass.patterns); + VISIT_SEQ(st, pattern, p->v.MatchClass.kwd_patterns); + break; + case MatchAs_kind: + if (p->v.MatchAs.pattern) { + VISIT(st, pattern, p->v.MatchAs.pattern); + } + if (p->v.MatchAs.name) { + symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p)); + } + break; + case MatchOr_kind: + VISIT_SEQ(st, pattern, p->v.MatchOr.patterns); + break; + } + VISIT_QUIT(st, 1); +} + static int symtable_implicit_arg(struct symtable *st, int pos) { PyObject *id = PyUnicode_FromFormat(".%d", pos); if (id == NULL) return 0; - if (!symtable_add_def(st, id, DEF_PARAM)) { + if (!symtable_add_def(st, id, DEF_PARAM, ST_LOCATION(st->st_cur))) { Py_DECREF(id); return 0; } @@ -1683,7 +1804,7 @@ symtable_implicit_arg(struct symtable *st, int pos) } static int -symtable_visit_params(struct symtable *st, asdl_seq *args) +symtable_visit_params(struct symtable *st, asdl_arg_seq *args) { int i; @@ -1692,7 +1813,7 @@ symtable_visit_params(struct symtable *st, asdl_seq *args) for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - if (!symtable_add_def(st, arg->arg, DEF_PARAM)) + if (!symtable_add_def(st, arg->arg, DEF_PARAM, LOCATION(arg))) return 0; } @@ -1700,7 +1821,25 @@ symtable_visit_params(struct symtable *st, asdl_seq *args) } static int -symtable_visit_argannotations(struct symtable *st, asdl_seq *args) +symtable_visit_annotation(struct symtable *st, expr_ty annotation) +{ + int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS; + if (future_annotations && + !symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock, + (void *)annotation, annotation->lineno, + annotation->col_offset, annotation->end_lineno, + annotation->end_col_offset)) { + VISIT_QUIT(st, 0); + } + VISIT(st, expr, annotation); + if (future_annotations && !symtable_exit_block(st)) { + VISIT_QUIT(st, 0); + } + return 1; +} + +static int +symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args) { int i; @@ -1717,8 +1856,15 @@ symtable_visit_argannotations(struct symtable *st, asdl_seq *args) } static int -symtable_visit_annotations(struct symtable *st, arguments_ty a, expr_ty returns) +symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_ty returns) { + int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS; + if (future_annotations && + !symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock, + (void *)o, o->lineno, o->col_offset, o->end_lineno, + o->end_col_offset)) { + VISIT_QUIT(st, 0); + } if (a->posonlyargs && !symtable_visit_argannotations(st, a->posonlyargs)) return 0; if (a->args && !symtable_visit_argannotations(st, a->args)) @@ -1729,8 +1875,12 @@ symtable_visit_annotations(struct symtable *st, arguments_ty a, expr_ty returns) VISIT(st, expr, a->kwarg->annotation); if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs)) return 0; - if (returns) - VISIT(st, expr, returns); + if (future_annotations && !symtable_exit_block(st)) { + VISIT_QUIT(st, 0); + } + if (returns && !symtable_visit_annotation(st, returns)) { + VISIT_QUIT(st, 0); + } return 1; } @@ -1747,12 +1897,12 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a) if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs)) return 0; if (a->vararg) { - if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM)) + if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM, LOCATION(a->vararg))) return 0; st->st_cur->ste_varargs = 1; } if (a->kwarg) { - if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM)) + if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM, LOCATION(a->kwarg))) return 0; st->st_cur->ste_varkeywords = 1; } @@ -1766,7 +1916,7 @@ symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh) if (eh->v.ExceptHandler.type) VISIT(st, expr, eh->v.ExceptHandler.type); if (eh->v.ExceptHandler.name) - if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL)) + if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL, LOCATION(eh))) return 0; VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body); return 1; @@ -1782,6 +1932,16 @@ symtable_visit_withitem(struct symtable *st, withitem_ty item) return 1; } +static int +symtable_visit_match_case(struct symtable *st, match_case_ty m) +{ + VISIT(st, pattern, m->pattern); + if (m->guard) { + VISIT(st, expr, m->guard); + } + VISIT_SEQ(st, stmt, m->body); + return 1; +} static int symtable_visit_alias(struct symtable *st, alias_ty a) @@ -1804,16 +1964,20 @@ symtable_visit_alias(struct symtable *st, alias_ty a) Py_INCREF(store_name); } if (!_PyUnicode_EqualToASCIIString(name, "*")) { - int r = symtable_add_def(st, store_name, DEF_IMPORT); + int r = symtable_add_def(st, store_name, DEF_IMPORT, LOCATION(a)); Py_DECREF(store_name); return r; } else { if (st->st_cur->ste_type != ModuleBlock) { - int lineno = st->st_cur->ste_lineno; - int col_offset = st->st_cur->ste_col_offset; + int lineno = a->lineno; + int col_offset = a->col_offset; + int end_lineno = a->end_lineno; + int end_col_offset = a->end_col_offset; PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); - PyErr_SyntaxLocationObject(st->st_filename, lineno, col_offset + 1); + PyErr_RangedSyntaxLocationObject(st->st_filename, + lineno, col_offset + 1, + end_lineno, end_col_offset + 1); Py_DECREF(store_name); return 0; } @@ -1850,7 +2014,7 @@ symtable_visit_keyword(struct symtable *st, keyword_ty k) static int symtable_handle_comprehension(struct symtable *st, expr_ty e, - identifier scope_name, asdl_seq *generators, + identifier scope_name, asdl_comprehension_seq *generators, expr_ty elt, expr_ty value) { int is_generator = (e->kind == GeneratorExp_kind); @@ -1863,13 +2027,27 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, /* Create comprehension scope for the rest */ if (!scope_name || !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, - e->lineno, e->col_offset)) { + e->lineno, e->col_offset, + e->end_lineno, e->end_col_offset)) { return 0; } + switch(e->kind) { + case ListComp_kind: + st->st_cur->ste_comprehension = ListComprehension; + break; + case SetComp_kind: + st->st_cur->ste_comprehension = SetComprehension; + break; + case DictComp_kind: + st->st_cur->ste_comprehension = DictComprehension; + break; + default: + st->st_cur->ste_comprehension = GeneratorExpression; + break; + } if (outermost->is_async) { st->st_cur->ste_coroutine = 1; } - st->st_cur->ste_comprehension = 1; /* Outermost iter is received as an argument */ if (!symtable_implicit_arg(st, 0)) { @@ -1886,18 +2064,6 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, if (value) VISIT(st, expr, value); VISIT(st, expr, elt); - if (st->st_cur->ste_generator) { - PyErr_SetString(PyExc_SyntaxError, - (e->kind == ListComp_kind) ? "'yield' inside list comprehension" : - (e->kind == SetComp_kind) ? "'yield' inside set comprehension" : - (e->kind == DictComp_kind) ? "'yield' inside dict comprehension" : - "'yield' inside generator expression"); - PyErr_SyntaxLocationObject(st->st_filename, - st->st_cur->ste_lineno, - st->st_cur->ste_col_offset + 1); - symtable_exit_block(st); - return 0; - } st->st_cur->ste_generator = is_generator; return symtable_exit_block(st); } @@ -1934,3 +2100,62 @@ symtable_visit_dictcomp(struct symtable *st, expr_ty e) e->v.DictComp.key, e->v.DictComp.value); } + +static int +symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_ty e) +{ + if (st->st_cur->ste_type != AnnotationBlock) { + return 1; + } + + PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); + return 0; +} + +static int +symtable_raise_if_comprehension_block(struct symtable *st, expr_ty e) { + _Py_comprehension_ty type = st->st_cur->ste_comprehension; + PyErr_SetString(PyExc_SyntaxError, + (type == ListComprehension) ? "'yield' inside list comprehension" : + (type == SetComprehension) ? "'yield' inside set comprehension" : + (type == DictComprehension) ? "'yield' inside dict comprehension" : + "'yield' inside generator expression"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, e->col_offset + 1, + e->end_lineno, e->end_col_offset + 1); + VISIT_QUIT(st, 0); +} + +struct symtable * +_Py_SymtableStringObjectFlags(const char *str, PyObject *filename, + int start, PyCompilerFlags *flags) +{ + struct symtable *st; + mod_ty mod; + PyArena *arena; + + arena = _PyArena_New(); + if (arena == NULL) + return NULL; + + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); + if (mod == NULL) { + _PyArena_Free(arena); + return NULL; + } + PyFutureFeatures *future = _PyFuture_FromAST(mod, filename); + if (future == NULL) { + _PyArena_Free(arena); + return NULL; + } + future->ff_features |= flags->cf_flags; + st = _PySymtable_Build(mod, filename, future); + PyObject_Free((void *)future); + _PyArena_Free(arena); + return st; +} diff --git a/contrib/tools/python3/src/Python/sysmodule.c b/contrib/tools/python3/src/Python/sysmodule.c index 33eb848fac3..1a96c50d250 100644 --- a/contrib/tools/python3/src/Python/sysmodule.c +++ b/contrib/tools/python3/src/Python/sysmodule.c @@ -15,20 +15,22 @@ Data members: */ #include "Python.h" -#include "code.h" -#include "frameobject.h" // PyFrame_GetBack() -#include "pycore_ceval.h" -#include "pycore_initconfig.h" -#include "pycore_object.h" -#include "pycore_pathconfig.h" -#include "pycore_pyerrors.h" -#include "pycore_pylifecycle.h" +#include "pycore_ceval.h" // _Py_RecursionLimitLowerWaterMark() +#include "pycore_initconfig.h" // _PyStatus_EXCEPTION() +#include "pycore_object.h" // _PyObject_IS_GC() +#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() +#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook() #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tupleobject.h" +#include "pycore_tuple.h" // _PyTuple_FromArray() +#include "pycore_structseq.h" // PyStructSequence_InitType() +#include "code.h" +#include "frameobject.h" // PyFrame_GetBack() #include "pydtrace.h" #include "osdefs.h" // DELIM +#include "stdlib_module_names.h" // _Py_stdlib_module_names #include #ifdef MS_WINDOWS @@ -68,7 +70,13 @@ sys_get_object_id(PyThreadState *tstate, _Py_Identifier *key) if (sd == NULL) { return NULL; } - return _PyDict_GetItemId(sd, key); + PyObject *exc_type, *exc_value, *exc_tb; + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + PyObject *value = _PyDict_GetItemIdWithError(sd, key); + /* XXX Suppress a new exception if it was raised and restore + * the old one. */ + _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + return value; } PyObject * @@ -78,77 +86,91 @@ _PySys_GetObjectId(_Py_Identifier *key) return sys_get_object_id(tstate, key); } +static PyObject * +_PySys_GetObject(PyInterpreterState *interp, const char *name) +{ + PyObject *sysdict = interp->sysdict; + if (sysdict == NULL) { + return NULL; + } + return _PyDict_GetItemStringWithError(sysdict, name); +} + PyObject * PySys_GetObject(const char *name) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *sd = tstate->interp->sysdict; - if (sd == NULL) { - return NULL; - } - return PyDict_GetItemString(sd, name); + + PyObject *exc_type, *exc_value, *exc_tb; + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + 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); + return value; } static int -sys_set_object_id(PyThreadState *tstate, _Py_Identifier *key, PyObject *v) +sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v) { - PyObject *sd = tstate->interp->sysdict; + if (key == NULL) { + return -1; + } + PyObject *sd = interp->sysdict; if (v == NULL) { - if (_PyDict_GetItemId(sd, key) == NULL) { - return 0; - } - else { - return _PyDict_DelItemId(sd, key); + v = _PyDict_Pop(sd, key, Py_None); + if (v == NULL) { + return -1; } + Py_DECREF(v); + return 0; } else { - return _PyDict_SetItemId(sd, key, v); + return PyDict_SetItem(sd, key, v); } } +static int +sys_set_object_id(PyInterpreterState *interp, _Py_Identifier *key, PyObject *v) +{ + return sys_set_object(interp, _PyUnicode_FromId(key), v); +} + int _PySys_SetObjectId(_Py_Identifier *key, PyObject *v) { - PyThreadState *tstate = _PyThreadState_GET(); - return sys_set_object_id(tstate, key, v); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return sys_set_object_id(interp, key, v); } static int -sys_set_object(PyThreadState *tstate, const char *name, PyObject *v) +sys_set_object_str(PyInterpreterState *interp, const char *name, PyObject *v) { - PyObject *sd = tstate->interp->sysdict; - if (v == NULL) { - if (PyDict_GetItemString(sd, name) == NULL) { - return 0; - } - else { - return PyDict_DelItemString(sd, name); - } - } - else { - return PyDict_SetItemString(sd, name, v); - } + PyObject *key = v ? PyUnicode_InternFromString(name) + : PyUnicode_FromString(name); + int r = sys_set_object(interp, key, v); + Py_XDECREF(key); + return r; } int PySys_SetObject(const char *name, PyObject *v) { - PyThreadState *tstate = _PyThreadState_GET(); - return sys_set_object(tstate, name, v); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return sys_set_object_str(interp, name, v); } static int -should_audit(PyInterpreterState *is) +should_audit(PyInterpreterState *interp) { - /* tstate->interp cannot be NULL, but test it just in case - for extra safety */ - assert(is != NULL); - if (!is) { + /* interp must not be NULL, but test it just in case for extra safety */ + assert(interp != NULL); + if (!interp) { return 0; } - return (is->runtime->audit_hook_head - || is->audit_hooks + return (interp->runtime->audit_hook_head + || interp->audit_hooks || PyDTrace_AUDIT_ENABLED()); } @@ -231,7 +253,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event, /* Disallow tracing in hooks unless explicitly enabled */ ts->tracing++; - ts->use_tracing = 0; + ts->cframe->use_tracing = 0; while ((hook = PyIter_Next(hooks)) != NULL) { _Py_IDENTIFIER(__cantrace__); PyObject *o; @@ -244,14 +266,14 @@ sys_audit_tstate(PyThreadState *ts, const char *event, break; } if (canTrace) { - ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); + ts->cframe->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); ts->tracing--; } PyObject* args[2] = {eventName, eventArgs}; o = _PyObject_FastCallTstate(ts, hook, args, 2); if (canTrace) { ts->tracing++; - ts->use_tracing = 0; + ts->cframe->use_tracing = 0; } if (!o) { break; @@ -259,7 +281,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event, Py_DECREF(o); Py_CLEAR(hook); } - ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); + ts->cframe->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); ts->tracing--; if (_PyErr_Occurred(ts)) { goto exit; @@ -433,15 +455,15 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook) return NULL; } - PyInterpreterState *is = tstate->interp; - if (is->audit_hooks == NULL) { - is->audit_hooks = PyList_New(0); - if (is->audit_hooks == NULL) { + PyInterpreterState *interp = tstate->interp; + if (interp->audit_hooks == NULL) { + interp->audit_hooks = PyList_New(0); + if (interp->audit_hooks == NULL) { return NULL; } } - if (PyList_Append(is->audit_hooks, hook) < 0) { + if (PyList_Append(interp->audit_hooks, hook) < 0) { return NULL; } @@ -816,8 +838,7 @@ sys_exit_impl(PyObject *module, PyObject *status) /*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/ { /* Raise SystemExit so callers may catch it or clean up. */ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetObject(tstate, PyExc_SystemExit, status); + PyErr_SetObject(PyExc_SystemExit, status); return NULL; } @@ -883,15 +904,14 @@ static PyObject * sys_intern_impl(PyObject *module, PyObject *s) /*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/ { - PyThreadState *tstate = _PyThreadState_GET(); if (PyUnicode_CheckExact(s)) { Py_INCREF(s); PyUnicode_InternInPlace(&s); return s; } else { - _PyErr_Format(tstate, PyExc_TypeError, - "can't intern %.400s", Py_TYPE(s)->tp_name); + PyErr_Format(PyExc_TypeError, + "can't intern %.400s", Py_TYPE(s)->tp_name); return NULL; } } @@ -1119,10 +1139,9 @@ static PyObject * sys_setswitchinterval_impl(PyObject *module, double interval) /*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/ { - PyThreadState *tstate = _PyThreadState_GET(); if (interval <= 0.0) { - _PyErr_SetString(tstate, PyExc_ValueError, - "switch interval must be strictly positive"); + PyErr_SetString(PyExc_ValueError, + "switch interval must be strictly positive"); return NULL; } _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval)); @@ -1255,7 +1274,6 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) static char *keywords[] = {"firstiter", "finalizer", NULL}; PyObject *firstiter = NULL; PyObject *finalizer = NULL; - PyThreadState *tstate = _PyThreadState_GET(); if (!PyArg_ParseTupleAndKeywords( args, kw, "|OO", keywords, @@ -1265,9 +1283,9 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) if (finalizer && finalizer != Py_None) { if (!PyCallable_Check(finalizer)) { - _PyErr_Format(tstate, PyExc_TypeError, - "callable finalizer expected, got %.50s", - Py_TYPE(finalizer)->tp_name); + PyErr_Format(PyExc_TypeError, + "callable finalizer expected, got %.50s", + Py_TYPE(finalizer)->tp_name); return NULL; } if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) { @@ -1280,9 +1298,9 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) if (firstiter && firstiter != Py_None) { if (!PyCallable_Check(firstiter)) { - _PyErr_Format(tstate, PyExc_TypeError, - "callable firstiter expected, got %.50s", - Py_TYPE(firstiter)->tp_name); + PyErr_Format(PyExc_TypeError, + "callable firstiter expected, got %.50s", + Py_TYPE(firstiter)->tp_name); return NULL; } if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) { @@ -1388,7 +1406,7 @@ get_hash_info(PyThreadState *tstate) PyStructSequence_SET_ITEM(hash_info, field++, PyLong_FromLong(_PyHASH_INF)); PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(_PyHASH_NAN)); + PyLong_FromLong(0)); // This is no longer used PyStructSequence_SET_ITEM(hash_info, field++, PyLong_FromLong(_PyHASH_IMAG)); PyStructSequence_SET_ITEM(hash_info, field++, @@ -1483,7 +1501,6 @@ sys_getwindowsversion_impl(PyObject *module) wchar_t kernel32_path[MAX_PATH]; LPVOID verblock; DWORD verblock_size; - PyThreadState *tstate = _PyThreadState_GET(); ver.dwOSVersionInfoSize = sizeof(ver); if (!GetVersionExW((OSVERSIONINFOW*) &ver)) @@ -1534,11 +1551,10 @@ sys_getwindowsversion_impl(PyObject *module) realBuild )); - if (_PyErr_Occurred(tstate)) { + if (PyErr_Occurred()) { Py_DECREF(version); return NULL; } - return version; } @@ -1591,8 +1607,8 @@ static PyObject * sys_setdlopenflags_impl(PyObject *module, int new_val) /*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - tstate->interp->dlopenflags = new_val; + PyInterpreterState *interp = _PyInterpreterState_GET(); + interp->dlopenflags = new_val; Py_RETURN_NONE; } @@ -1609,8 +1625,8 @@ static PyObject * sys_getdlopenflags_impl(PyObject *module) /*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - return PyLong_FromLong(tstate->interp->dlopenflags); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return PyLong_FromLong(interp->dlopenflags); } #endif /* HAVE_DLOPEN */ @@ -1821,6 +1837,21 @@ sys__current_frames_impl(PyObject *module) return _PyThread_CurrentFrames(); } +/*[clinic input] +sys._current_exceptions + +Return a dict mapping each thread's identifier to its current raised exception. + +This function should be used for specialized purposes only. +[clinic start generated code]*/ + +static PyObject * +sys__current_exceptions_impl(PyObject *module) +/*[clinic end generated code: output=2ccfd838c746f0ba input=0e91818fbf2edc1f]*/ +{ + return _PyThread_CurrentExceptions(); +} + /*[clinic input] sys.call_tracing @@ -1871,12 +1902,12 @@ sys__debugmallocstats_impl(PyObject *module) } #ifdef Py_TRACE_REFS -/* Defined in objects.c because it uses static globals if that file */ +/* Defined in objects.c because it uses static globals in that file */ extern PyObject *_Py_GetObjects(PyObject *, PyObject *); #endif #ifdef DYNAMIC_EXECUTION_PROFILE -/* Defined in ceval.c because it uses static globals if that file */ +/* Defined in ceval.c because it uses static globals in that file */ extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); #endif @@ -1928,6 +1959,20 @@ sys_getandroidapilevel_impl(PyObject *module) #endif /* ANDROID_API_LEVEL */ +/*[clinic input] +sys._deactivate_opcache + +Deactivate the opcode cache permanently +[clinic start generated code]*/ + +static PyObject * +sys__deactivate_opcache_impl(PyObject *module) +/*[clinic end generated code: output=00e20982bd012122 input=501eac146735ccf9]*/ +{ + _PyEval_DeactivateOpCache(); + Py_RETURN_NONE; +} + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ @@ -1937,6 +1982,7 @@ static PyMethodDef sys_methods[] = { METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc}, SYS__CLEAR_TYPE_CACHE_METHODDEF SYS__CURRENT_FRAMES_METHODDEF + SYS__CURRENT_EXCEPTIONS_METHODDEF SYS_DISPLAYHOOK_METHODDEF SYS_EXC_INFO_METHODDEF SYS_EXCEPTHOOK_METHODDEF @@ -1980,36 +2026,67 @@ static PyMethodDef sys_methods[] = { SYS_GET_ASYNCGEN_HOOKS_METHODDEF SYS_GETANDROIDAPILEVEL_METHODDEF SYS_UNRAISABLEHOOK_METHODDEF + SYS__DEACTIVATE_OPCACHE_METHODDEF {NULL, NULL} /* sentinel */ }; + static PyObject * list_builtin_module_names(void) { PyObject *list = PyList_New(0); - int i; - if (list == NULL) + if (list == NULL) { return NULL; - for (i = 0; PyImport_Inittab[i].name != NULL; i++) { - PyObject *name = PyUnicode_FromString( - PyImport_Inittab[i].name); - if (name == NULL) - break; - PyList_Append(list, name); + } + 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) { - Py_DECREF(list); - list = NULL; + goto error; + } + PyObject *tuple = PyList_AsTuple(list); + Py_DECREF(list); + return tuple; + +error: + Py_DECREF(list); + return NULL; +} + + +static PyObject * +list_stdlib_module_names(void) +{ + Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names); + PyObject *names = PyTuple_New(len); + if (names == NULL) { + return NULL; } - if (list) { - PyObject *v = PyList_AsTuple(list); - Py_DECREF(list); - list = v; + + for (Py_ssize_t i = 0; i < len; i++) { + PyObject *name = PyUnicode_FromString(_Py_stdlib_module_names[i]); + if (name == NULL) { + Py_DECREF(names); + return NULL; + } + PyTuple_SET_ITEM(names, i, name); } - return list; + + PyObject *set = PyObject_CallFunction((PyObject *)&PyFrozenSet_Type, + "(O)", names); + Py_DECREF(names); + return set; } + /* Pre-initialization support for sys.warnoptions and sys._xoptions * * Modern internal code paths: @@ -2155,7 +2232,7 @@ get_warnoptions(PyThreadState *tstate) if (warnoptions == NULL) { return NULL; } - if (sys_set_object_id(tstate, &PyId_warnoptions, warnoptions)) { + if (sys_set_object_id(tstate->interp, &PyId_warnoptions, warnoptions)) { Py_DECREF(warnoptions); return NULL; } @@ -2248,7 +2325,7 @@ get_xoptions(PyThreadState *tstate) if (xoptions == NULL) { return NULL; } - if (sys_set_object_id(tstate, &PyId__xoptions, xoptions)) { + if (sys_set_object_id(tstate->interp, &PyId__xoptions, xoptions)) { Py_DECREF(xoptions); return NULL; } @@ -2432,14 +2509,13 @@ static PyStructSequence_Field flags_fields[] = { {"no_site", "-S"}, {"ignore_environment", "-E"}, {"verbose", "-v"}, - /* {"unbuffered", "-u"}, */ - /* {"skip_first", "-x"}, */ {"bytes_warning", "-b"}, {"quiet", "-q"}, {"hash_randomization", "-R"}, {"isolated", "-I"}, {"dev_mode", "-X dev"}, {"utf8_mode", "-X utf8"}, + {"warn_default_encoding", "-X warn_default_encoding"}, {0} }; @@ -2447,24 +2523,29 @@ static PyStructSequence_Desc flags_desc = { "sys.flags", /* name */ flags__doc__, /* doc */ flags_fields, /* fields */ - 15 + 16 }; -static PyObject* -make_flags(PyThreadState *tstate) +static int +set_flags_from_config(PyInterpreterState *interp, PyObject *flags) { - PyInterpreterState *interp = tstate->interp; const PyPreConfig *preconfig = &interp->runtime->preconfig; const PyConfig *config = _PyInterpreterState_GetConfig(interp); - PyObject *seq = PyStructSequence_New(&FlagsType); - if (seq == NULL) { - return NULL; - } - - int pos = 0; -#define SetFlag(flag) \ - PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag)) + // _PySys_UpdateConfig() modifies sys.flags in-place: + // Py_XDECREF() is needed in this case. + Py_ssize_t pos = 0; +#define SetFlagObj(expr) \ + do { \ + PyObject *value = (expr); \ + if (value == NULL) { \ + return -1; \ + } \ + Py_XDECREF(PyStructSequence_GET_ITEM(flags, pos)); \ + PyStructSequence_SET_ITEM(flags, pos, value); \ + pos++; \ + } while (0) +#define SetFlag(expr) SetFlagObj(PyLong_FromLong(expr)) SetFlag(config->parser_debug); SetFlag(config->inspect); @@ -2475,23 +2556,35 @@ make_flags(PyThreadState *tstate) SetFlag(!config->site_import); SetFlag(!config->use_environment); SetFlag(config->verbose); - /* SetFlag(saw_unbuffered_flag); */ - /* SetFlag(skipfirstline); */ SetFlag(config->bytes_warning); SetFlag(config->quiet); SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0); SetFlag(config->isolated); - PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode)); + SetFlagObj(PyBool_FromLong(config->dev_mode)); SetFlag(preconfig->utf8_mode); + SetFlag(config->warn_default_encoding); +#undef SetFlagObj #undef SetFlag + return 0; +} - if (_PyErr_Occurred(tstate)) { - Py_DECREF(seq); + +static PyObject* +make_flags(PyInterpreterState *interp) +{ + PyObject *flags = PyStructSequence_New(&FlagsType); + if (flags == NULL) { + return NULL; + } + + if (set_flags_from_config(interp, flags) < 0) { + Py_DECREF(flags); return NULL; } - return seq; + return flags; } + PyDoc_STRVAR(version_info__doc__, "sys.version_info\n\ \n\ @@ -2647,18 +2740,7 @@ static struct PyModuleDef sysmodule = { }; /* Updating the sys namespace, returning NULL pointer on error */ -#define SET_SYS_FROM_STRING_BORROW(key, value) \ - do { \ - PyObject *v = (value); \ - if (v == NULL) { \ - goto err_occurred; \ - } \ - res = PyDict_SetItemString(sysdict, key, v); \ - if (res < 0) { \ - goto err_occurred; \ - } \ - } while (0) -#define SET_SYS_FROM_STRING(key, value) \ +#define SET_SYS(key, value) \ do { \ PyObject *v = (value); \ if (v == NULL) { \ @@ -2671,6 +2753,9 @@ static struct PyModuleDef sysmodule = { } \ } while (0) +#define SET_SYS_FROM_STRING(key, value) \ + SET_SYS(key, PyUnicode_FromString(value)) + static PyStatus _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) { @@ -2679,123 +2764,93 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) /* stdin/stdout/stderr are set in pylifecycle.c */ - SET_SYS_FROM_STRING_BORROW("__displayhook__", - PyDict_GetItemString(sysdict, "displayhook")); - SET_SYS_FROM_STRING_BORROW("__excepthook__", - PyDict_GetItemString(sysdict, "excepthook")); - SET_SYS_FROM_STRING_BORROW( - "__breakpointhook__", - PyDict_GetItemString(sysdict, "breakpointhook")); - SET_SYS_FROM_STRING_BORROW("__unraisablehook__", - PyDict_GetItemString(sysdict, "unraisablehook")); - - SET_SYS_FROM_STRING("version", - PyUnicode_FromString(Py_GetVersion())); - SET_SYS_FROM_STRING("hexversion", - PyLong_FromLong(PY_VERSION_HEX)); - SET_SYS_FROM_STRING("_git", - Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), - _Py_gitversion())); - SET_SYS_FROM_STRING("_framework", PyUnicode_FromString(_PYTHONFRAMEWORK)); - SET_SYS_FROM_STRING("api_version", - PyLong_FromLong(PYTHON_API_VERSION)); - SET_SYS_FROM_STRING("copyright", - PyUnicode_FromString(Py_GetCopyright())); - SET_SYS_FROM_STRING("platform", - PyUnicode_FromString(Py_GetPlatform())); - SET_SYS_FROM_STRING("maxsize", - PyLong_FromSsize_t(PY_SSIZE_T_MAX)); - SET_SYS_FROM_STRING("float_info", - PyFloat_GetInfo()); - SET_SYS_FROM_STRING("int_info", - PyLong_GetInfo()); +#define COPY_SYS_ATTR(tokey, fromkey) \ + SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey)) + + COPY_SYS_ATTR("__displayhook__", "displayhook"); + COPY_SYS_ATTR("__excepthook__", "excepthook"); + COPY_SYS_ATTR("__breakpointhook__", "breakpointhook"); + COPY_SYS_ATTR("__unraisablehook__", "unraisablehook"); + +#undef COPY_SYS_ATTR + + SET_SYS_FROM_STRING("version", Py_GetVersion()); + SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX)); + SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), + _Py_gitversion())); + SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK); + SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION)); + SET_SYS_FROM_STRING("copyright", Py_GetCopyright()); + SET_SYS_FROM_STRING("platform", Py_GetPlatform()); + SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); + 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; } } - SET_SYS_FROM_STRING("hash_info", - get_hash_info(tstate)); - SET_SYS_FROM_STRING("maxunicode", - PyLong_FromLong(0x10FFFF)); - SET_SYS_FROM_STRING("builtin_module_names", - list_builtin_module_names()); + SET_SYS("hash_info", get_hash_info(tstate)); + SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF)); + SET_SYS("builtin_module_names", list_builtin_module_names()); + SET_SYS("stdlib_module_names", list_stdlib_module_names()); #if PY_BIG_ENDIAN - SET_SYS_FROM_STRING("byteorder", - PyUnicode_FromString("big")); + SET_SYS_FROM_STRING("byteorder", "big"); #else - SET_SYS_FROM_STRING("byteorder", - PyUnicode_FromString("little")); + SET_SYS_FROM_STRING("byteorder", "little"); #endif #ifdef MS_COREDLL - SET_SYS_FROM_STRING("dllhandle", - PyLong_FromVoidPtr(PyWin_DLLhModule)); - SET_SYS_FROM_STRING("winver", - PyUnicode_FromString(PyWin_DLLVersionString)); + SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule)); + SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString); #endif #ifdef ABIFLAGS - SET_SYS_FROM_STRING("abiflags", - PyUnicode_FromString(ABIFLAGS)); + SET_SYS_FROM_STRING("abiflags", ABIFLAGS); #endif /* version_info */ if (VersionInfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&VersionInfoType, - &version_info_desc) < 0) { + if (_PyStructSequence_InitType(&VersionInfoType, + &version_info_desc, + Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { goto type_init_failed; } } version_info = make_version_info(tstate); - SET_SYS_FROM_STRING("version_info", version_info); - /* prevent user from creating new instances */ - VersionInfoType.tp_init = NULL; - VersionInfoType.tp_new = NULL; - res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__"); - if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - _PyErr_Clear(tstate); - } + SET_SYS("version_info", version_info); /* implementation */ - SET_SYS_FROM_STRING("implementation", make_impl_info(version_info)); + SET_SYS("implementation", make_impl_info(version_info)); - /* flags */ + // sys.flags: updated in-place later by _PySys_UpdateConfig() if (FlagsType.tp_name == 0) { - if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) { + if (_PyStructSequence_InitType(&FlagsType, &flags_desc, + Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { goto type_init_failed; } } - /* Set flags to their default values (updated by _PySys_InitMain()) */ - SET_SYS_FROM_STRING("flags", make_flags(tstate)); + SET_SYS("flags", make_flags(tstate->interp)); #if defined(MS_WINDOWS) /* getwindowsversion */ - if (WindowsVersionType.tp_name == 0) - if (PyStructSequence_InitType2(&WindowsVersionType, - &windows_version_desc) < 0) { + if (WindowsVersionType.tp_name == 0) { + if (_PyStructSequence_InitType(&WindowsVersionType, + &windows_version_desc, + Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { goto type_init_failed; } - /* prevent user from creating new instances */ - WindowsVersionType.tp_init = NULL; - WindowsVersionType.tp_new = NULL; - assert(!_PyErr_Occurred(tstate)); - res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__"); - if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - _PyErr_Clear(tstate); } #endif /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #ifndef PY_NO_SHORT_FLOAT_REPR - SET_SYS_FROM_STRING("float_repr_style", - PyUnicode_FromString("short")); + SET_SYS_FROM_STRING("float_repr_style", "short"); #else - SET_SYS_FROM_STRING("float_repr_style", - PyUnicode_FromString("legacy")); + SET_SYS_FROM_STRING("float_repr_style", "legacy"); #endif - SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo()); + SET_SYS("thread_info", PyThread_GetInfo()); /* initialize asyncgen_hooks */ if (AsyncGenHooksType.tp_name == NULL) { @@ -2805,6 +2860,11 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) } } + /* adding sys.path_hooks and sys.path_importer_cache */ + SET_SYS("meta_path", PyList_New(0)); + SET_SYS("path_importer_cache", PyDict_New()); + SET_SYS("path_hooks", PyList_New(0)); + if (_PyErr_Occurred(tstate)) { goto err_occurred; } @@ -2817,20 +2877,6 @@ err_occurred: return _PyStatus_ERR("can't initialize sys module"); } -/* Updating the sys namespace, returning integer error codes */ -#define SET_SYS_FROM_STRING_INT_RESULT(key, value) \ - do { \ - PyObject *v = (value); \ - if (v == NULL) \ - return -1; \ - res = PyDict_SetItemString(sysdict, key, v); \ - Py_DECREF(v); \ - if (res < 0) { \ - return res; \ - } \ - } while (0) - - static int sys_add_xoption(PyObject *opts, const wchar_t *s) { @@ -2885,42 +2931,38 @@ sys_create_xoptions_dict(const PyConfig *config) } +// Update sys attributes for a new PyConfig configuration. +// This function also adds attributes that _PySys_InitCore() didn't add. int -_PySys_InitMain(PyThreadState *tstate) +_PySys_UpdateConfig(PyThreadState *tstate) { - PyObject *sysdict = tstate->interp->sysdict; - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); + PyInterpreterState *interp = tstate->interp; + PyObject *sysdict = interp->sysdict; + const PyConfig *config = _PyInterpreterState_GetConfig(interp); int res; #define COPY_LIST(KEY, VALUE) \ - do { \ - PyObject *list = _PyWideStringList_AsList(&(VALUE)); \ - if (list == NULL) { \ - return -1; \ - } \ - SET_SYS_FROM_STRING_BORROW(KEY, list); \ - Py_DECREF(list); \ - } while (0) + SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE))); #define SET_SYS_FROM_WSTR(KEY, VALUE) \ - do { \ - PyObject *str = PyUnicode_FromWideChar(VALUE, -1); \ - if (str == NULL) { \ - return -1; \ - } \ - SET_SYS_FROM_STRING_BORROW(KEY, str); \ - Py_DECREF(str); \ - } while (0) + SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1)); - COPY_LIST("path", config->module_search_paths); +#define COPY_WSTR(SYS_ATTR, WSTR) \ + if (WSTR != NULL) { \ + SET_SYS_FROM_WSTR(SYS_ATTR, WSTR); \ + } - SET_SYS_FROM_WSTR("executable", config->executable); - SET_SYS_FROM_WSTR("_base_executable", config->base_executable); - SET_SYS_FROM_WSTR("prefix", config->prefix); - SET_SYS_FROM_WSTR("base_prefix", config->base_prefix); - SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix); - SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix); - SET_SYS_FROM_WSTR("platlibdir", config->platlibdir); + if (config->module_search_paths_set) { + COPY_LIST("path", config->module_search_paths); + } + + COPY_WSTR("executable", config->executable); + COPY_WSTR("_base_executable", config->base_executable); + COPY_WSTR("prefix", config->prefix); + COPY_WSTR("base_prefix", config->base_prefix); + COPY_WSTR("exec_prefix", config->exec_prefix); + COPY_WSTR("base_exec_prefix", config->base_exec_prefix); + COPY_WSTR("platlibdir", config->platlibdir); if (config->pycache_prefix != NULL) { SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); @@ -2929,41 +2971,25 @@ _PySys_InitMain(PyThreadState *tstate) } COPY_LIST("argv", config->argv); + COPY_LIST("orig_argv", config->orig_argv); COPY_LIST("warnoptions", config->warnoptions); - PyObject *xoptions = sys_create_xoptions_dict(config); - if (xoptions == NULL) { - return -1; - } - SET_SYS_FROM_STRING_BORROW("_xoptions", xoptions); - Py_DECREF(xoptions); + SET_SYS("_xoptions", sys_create_xoptions_dict(config)); -#undef COPY_LIST #undef SET_SYS_FROM_WSTR +#undef COPY_LIST +#undef COPY_WSTR - - /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(tstate)); - /* prevent user from creating new instances */ - FlagsType.tp_init = NULL; - FlagsType.tp_new = NULL; - res = PyDict_DelItemString(FlagsType.tp_dict, "__new__"); - if (res < 0) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - return res; - } - _PyErr_Clear(tstate); + // sys.flags + PyObject *flags = _PySys_GetObject(interp, "flags"); // borrowed ref + if (flags == NULL) { + return -1; } - - SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode", - PyBool_FromLong(!config->write_bytecode)); - - if (get_warnoptions(tstate) == NULL) { + if (set_flags_from_config(interp, flags) < 0) { return -1; } - if (get_xoptions(tstate) == NULL) - return -1; + SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode)); if (_PyErr_Occurred(tstate)) { goto err_occurred; @@ -2975,15 +3001,14 @@ err_occurred: return -1; } +#undef SET_SYS #undef SET_SYS_FROM_STRING -#undef SET_SYS_FROM_STRING_BORROW -#undef SET_SYS_FROM_STRING_INT_RESULT /* Set up a preliminary stderr printer until we have enough infrastructure for the io module in place. - Use UTF-8/surrogateescape and ignore EAGAIN errors. */ + Use UTF-8/backslashreplace and ignore EAGAIN errors. */ static PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict) { @@ -3006,8 +3031,8 @@ error: } -/* Create sys module without all attributes: _PySys_InitMain() should be called - later to add remaining attributes. */ +/* Create sys module without all attributes. + _PySys_UpdateConfig() should be called later to add remaining attributes. */ PyStatus _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) { @@ -3100,8 +3125,8 @@ PySys_SetPath(const wchar_t *path) PyObject *v; if ((v = makepathobject(path, DELIM)) == NULL) Py_FatalError("can't create sys.path"); - PyThreadState *tstate = _PyThreadState_GET(); - if (sys_set_object_id(tstate, &PyId_path, v) != 0) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (sys_set_object_id(interp, &PyId_path, v) != 0) { Py_FatalError("can't assign sys.path"); } Py_DECREF(v); @@ -3142,7 +3167,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) if (av == NULL) { Py_FatalError("no mem for sys.argv"); } - if (sys_set_object(tstate, "argv", av) != 0) { + if (sys_set_object_str(tstate->interp, "argv", av) != 0) { Py_DECREF(av); Py_FatalError("can't assign sys.argv"); } diff --git a/contrib/tools/python3/src/Python/thread.c b/contrib/tools/python3/src/Python/thread.c index a10f5728dc0..dfe28b6bdb6 100644 --- a/contrib/tools/python3/src/Python/thread.c +++ b/contrib/tools/python3/src/Python/thread.c @@ -75,6 +75,25 @@ PyThread_init_thread(void) 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(_POSIX_THREADS) # define PYTHREAD_NAME "pthread" # include "thread_pthread.h" diff --git a/contrib/tools/python3/src/Python/thread_pthread.h b/contrib/tools/python3/src/Python/thread_pthread.h index 83974b4c0ca..35b9810aa37 100644 --- a/contrib/tools/python3/src/Python/thread_pthread.h +++ b/contrib/tools/python3/src/Python/thread_pthread.h @@ -32,18 +32,17 @@ #define THREAD_STACK_SIZE 0 /* use default stack size */ #endif -/* The default stack size for new threads on OSX and BSD is small enough that +/* The default stack size for new threads on BSD is small enough that * we'll get hard crashes instead of 'maximum recursion depth exceeded' * exceptions. * - * The default stack sizes below are the empirically determined minimal stack + * The default stack size below is the empirically determined minimal stack * sizes where a simple recursive function doesn't cause a hard crash. + * + * For macOS the value of THREAD_STACK_SIZE is determined in configure.ac + * as it also depends on the other configure options like chosen sanitizer + * runtimes. */ -#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 -#undef THREAD_STACK_SIZE -/* Note: This matches the value of -Wl,-stack_size in configure.ac */ -#define THREAD_STACK_SIZE 0x1000000 -#endif #if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 #undef THREAD_STACK_SIZE #define THREAD_STACK_SIZE 0x400000 @@ -62,6 +61,10 @@ # define THREAD_STACK_SIZE 0x800000 # endif #endif +#if defined(__VXWORKS__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#undef THREAD_STACK_SIZE +#define THREAD_STACK_SIZE 0x100000 +#endif /* for safety, ensure a viable minimum stacksize */ #define THREAD_STACK_MIN 0x8000 /* 32 KiB */ #else /* !_POSIX_THREAD_ATTR_STACKSIZE */ diff --git a/contrib/tools/python3/src/Python/traceback.c b/contrib/tools/python3/src/Python/traceback.c index 23d0e38e737..7d6f7f435a6 100644 --- a/contrib/tools/python3/src/Python/traceback.c +++ b/contrib/tools/python3/src/Python/traceback.c @@ -4,6 +4,7 @@ #include "Python.h" #include "code.h" +#include "pycore_interp.h" // PyInterpreterState.gc #include "frameobject.h" // PyFrame_GetBack() #include "structmember.h" // PyMemberDef #include "osdefs.h" // SEP @@ -147,7 +148,7 @@ static PyMethodDef tb_methods[] = { }; static PyMemberDef tb_memberlist[] = { - {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|READ_RESTRICTED}, + {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ}, {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, {NULL} /* Sentinel */ @@ -233,7 +234,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) assert(tb_next == NULL || PyTraceBack_Check(tb_next)); assert(frame != NULL); - return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti, + return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti*sizeof(_Py_CODEUNIT), PyFrame_GetLineNumber(frame)); } @@ -419,12 +420,12 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { Py_DECREF(io); Py_DECREF(binary); - PyMem_FREE(found_encoding); + PyMem_Free(found_encoding); return 0; } fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); Py_DECREF(io); - PyMem_FREE(found_encoding); + PyMem_Free(found_encoding); if (fob == NULL) { PyErr_Clear(); @@ -628,12 +629,12 @@ PyTraceBack_Print(PyObject *v, PyObject *f) This function is signal safe. */ void -_Py_DumpDecimal(int fd, unsigned long value) +_Py_DumpDecimal(int fd, size_t value) { /* 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 null byte. 53/22 is an upper bound for log10(256). */ - char buffer[1 + (sizeof(unsigned long)*53-1) / 22 + 1]; + char buffer[1 + (sizeof(size_t)*53-1) / 22 + 1]; char *ptr, *end; end = &buffer[Py_ARRAY_LENGTH(buffer) - 1]; @@ -649,15 +650,12 @@ _Py_DumpDecimal(int fd, unsigned long value) _Py_write_noraise(fd, ptr, end - ptr); } -/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits, - and write it into the file fd. - - This function is signal safe. */ - +/* Format an integer as hexadecimal with width digits into fd file descriptor. + The function is signal safe. */ void -_Py_DumpHexadecimal(int fd, unsigned long value, Py_ssize_t width) +_Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width) { - char buffer[sizeof(unsigned long) * 2 + 1], *ptr, *end; + char buffer[sizeof(uintptr_t) * 2 + 1], *ptr, *end; const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1; if (width > size) @@ -788,11 +786,10 @@ dump_frame(int fd, PyFrameObject *frame) PUTS(fd, "???"); } - /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */ - int lineno = PyCode_Addr2Line(code, frame->f_lasti); + int lineno = PyFrame_GetLineNumber(frame); PUTS(fd, ", line "); if (lineno >= 0) { - _Py_DumpDecimal(fd, (unsigned long)lineno); + _Py_DumpDecimal(fd, (size_t)lineno); } else { PUTS(fd, "???"); @@ -826,7 +823,7 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) // not modify Python objects. frame = tstate->frame; if (frame == NULL) { - PUTS(fd, "\n"); + PUTS(fd, " \n"); return; } @@ -940,6 +937,9 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, break; } write_thread_id(fd, tstate, tstate == current_tstate); + if (tstate == current_tstate && tstate->interp->gc.collecting) { + PUTS(fd, " Garbage-collecting\n"); + } dump_traceback(fd, tstate, 0); tstate = PyThreadState_Next(tstate); nthreads++; diff --git a/contrib/tools/python3/src/README.rst b/contrib/tools/python3/src/README.rst index d3b2521a875..215ff1e5b94 100644 --- a/contrib/tools/python3/src/README.rst +++ b/contrib/tools/python3/src/README.rst @@ -1,21 +1,17 @@ -This is Python version 3.9.12 +This is Python version 3.10.4 ============================= -.. image:: https://travis-ci.org/python/cpython.svg?branch=3.9 +.. image:: https://travis-ci.com/python/cpython.svg?branch=master :alt: CPython build status on Travis CI - :target: https://travis-ci.org/python/cpython + :target: https://travis-ci.com/python/cpython .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg :alt: CPython build status on GitHub Actions :target: https://github.com/python/cpython/actions -.. image:: https://dev.azure.com/python/cpython/_apis/build/status/Azure%20Pipelines%20CI?branchName=3.9 +.. image:: https://dev.azure.com/python/cpython/_apis/build/status/Azure%20Pipelines%20CI?branchName=master :alt: CPython build status on Azure DevOps - :target: https://dev.azure.com/python/cpython/_build/latest?definitionId=4&branchName=3.9 - -.. image:: https://codecov.io/gh/python/cpython/branch/3.9/graph/badge.svg - :alt: CPython code coverage on Codecov - :target: https://codecov.io/gh/python/cpython + :target: https://dev.azure.com/python/cpython/_build/latest?definitionId=4&branchName=master .. image:: https://img.shields.io/badge/discourse-join_chat-brightgreen.svg :alt: Python Discourse chat @@ -79,10 +75,10 @@ dependencies for various Linux distributions and macOS. On macOS, there are additional configure and build options related to macOS framework and universal builds. Refer to `Mac/README.rst -`_. +`_. On Windows, see `PCbuild/readme.txt -`_. +`_. If you wish, you can create a subdirectory and invoke configure from there. For example:: @@ -141,11 +137,11 @@ What's New ---------- We have a comprehensive overview of the changes in the `What's New in Python -3.9 `_ document. For a more +3.10 `_ document. For a more detailed change log, read `Misc/NEWS -`_, but a full +`_, but a full accounting of changes can only be gleaned from the `commit history -`_. +`_. If you want to install multiple versions of Python, see the section below entitled "Installing multiple versions". @@ -154,7 +150,7 @@ entitled "Installing multiple versions". Documentation ------------- -`Documentation for Python 3.9 `_ is online, +`Documentation for Python 3.10 `_ is online, updated daily. It can also be downloaded in many formats for faster access. The documentation @@ -163,7 +159,7 @@ is primarily for documentation authors, translators, and people with special formatting requirements. For information about building Python's documentation, refer to `Doc/README.rst -`_. +`_. Converting From Python 2.x to 3.x @@ -213,8 +209,8 @@ 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.9 with 3.9 being the -primary version, you would execute ``make install`` in your 3.9 build directory +For example, if you want to install Python 2.7, 3.6, and 3.10 with 3.10 being the +primary version, you would execute ``make install`` in your 3.10 build directory and ``make altinstall`` in the others. @@ -245,7 +241,7 @@ All current PEPs, as well as guidelines for submitting a new PEP, are listed at Release Schedule ---------------- -See :pep:`596` for Python 3.9 release details. +See :pep:`619` for Python 3.10 release details. Copyright and License Information @@ -260,8 +256,9 @@ rights reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. -See the file "LICENSE" for information on the history of this software, terms & -conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. +See the `LICENSE `_ for +information on the history of this software, terms & conditions for usage, and a +DISCLAIMER OF ALL WARRANTIES. This Python distribution contains *no* GNU General Public License (GPL) code, so it may be used in proprietary projects. There are interfaces to some GNU -- cgit v1.3